-
Notifications
You must be signed in to change notification settings - Fork 909
added VA topic coverage checker #2235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
ChaseMillers
wants to merge
1
commit into
ServiceNowDevProgram:main
from
ChaseMillers:add-va-topic-coverage-report
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Empty file.
89 changes: 89 additions & 0 deletions
89
... Components/Background Scripts/Virtual Agent Topic Coverage Report/MOCK_DATA.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| # Mock Data Seeder for VA Topic Coverage Report | ||
|
|
||
| Use this script to create test data for the Virtual Agent Topic Coverage Report. | ||
|
|
||
| ## Mock Data Script | ||
|
|
||
| Run this in **System Definition → Scripts - Background** to create test topics: | ||
|
|
||
| ```javascript | ||
| // Generate mock VA topics for testing Topic Coverage Report | ||
| // Creates topics with various states (active/inactive, published/unpublished) | ||
|
|
||
| (function() { | ||
| var TEST_TOPICS = [ | ||
| {name: 'Password Reset Help', active: true, published: true, hasConversations: true, count: 15}, | ||
| {name: 'VPN Access Request', active: true, published: true, hasConversations: true, count: 8}, | ||
| {name: 'Laptop Request', active: true, published: true, hasConversations: false, count: 0}, | ||
| {name: 'Printer Support', active: true, published: false, hasConversations: false, count: 0}, | ||
| {name: 'Email Issues', active: false, published: true, hasConversations: false, count: 0}, | ||
| {name: 'Test Topic Draft', active: false, published: false, hasConversations: false, count: 0} | ||
| ]; | ||
|
|
||
| var topicGr = new GlideRecord('sys_cs_topic'); | ||
| if (!topicGr.isValid()) { | ||
| gs.error('Table sys_cs_topic not found. Virtual Agent may not be installed.'); | ||
| return; | ||
| } | ||
|
|
||
| // Auto-detect conversation field | ||
| var convGr = new GlideRecord('sys_cs_conversation'); | ||
| var topicField = null; | ||
| if (convGr.isValid()) { | ||
| topicField = convGr.isValidField('topic') ? 'topic' : | ||
| (convGr.isValidField('selected_topic') ? 'selected_topic' : null); | ||
| } | ||
|
|
||
| gs.info('Creating ' + TEST_TOPICS.length + ' test VA topics...'); | ||
|
|
||
| for (var i = 0; i < TEST_TOPICS.length; i++) { | ||
| var topic = TEST_TOPICS[i]; | ||
|
|
||
| // Check if topic already exists | ||
| topicGr.initialize(); | ||
| topicGr.addQuery('name', topic.name); | ||
| topicGr.setLimit(1); | ||
| topicGr.query(); | ||
|
|
||
| var topicId; | ||
| if (topicGr.next()) { | ||
| topicId = topicGr.getUniqueValue(); | ||
| gs.info('Topic already exists: ' + topic.name); | ||
| } else { | ||
| // Create new topic | ||
| topicGr.initialize(); | ||
| topicGr.setValue('name', topic.name); | ||
| if (topicGr.isValidField('short_description')) { | ||
| topicGr.setValue('short_description', 'Test topic for coverage report'); | ||
| } | ||
| topicGr.setValue('active', topic.active); | ||
| topicGr.setValue('published', topic.published); | ||
| topicId = topicGr.insert(); | ||
| gs.info('Created topic: ' + topic.name + ' (active: ' + topic.active + ', published: ' + topic.published + ')'); | ||
| } | ||
|
|
||
| // Create conversations if needed | ||
| if (topic.hasConversations && topicField && topicId) { | ||
| for (var j = 0; j < topic.count; j++) { | ||
| convGr.initialize(); | ||
| convGr.setValue(topicField, topicId); | ||
| if (convGr.isValidField('state')) convGr.setValue('state', 2); // closed | ||
| convGr.insert(); | ||
| } | ||
| gs.info(' Created ' + topic.count + ' conversations for: ' + topic.name); | ||
| } | ||
| } | ||
|
|
||
| gs.info('\n=== Mock Data Complete ==='); | ||
| gs.info('Run the Virtual Agent Topic Coverage Report to see results!'); | ||
| })(); | ||
| ``` | ||
|
|
||
| ## Expected Output | ||
|
|
||
| After running the mock data seeder, your coverage report should show: | ||
|
|
||
| - **Total Topics**: 6 | ||
| - **Inactive Topics**: 2 (Email Issues, Test Topic Draft) | ||
| - **Unpublished Topics**: 2 (Printer Support, Test Topic Draft) | ||
| - **Topics with Zero Usage**: 1 (Laptop Request - active & published but no conversations) |
27 changes: 27 additions & 0 deletions
27
...ide Components/Background Scripts/Virtual Agent Topic Coverage Report/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # Virtual Agent Topic Coverage Report | ||
|
|
||
| A background script that analyzes Virtual Agent topic configuration health by identifying inactive, unpublished, or unused topics. | ||
|
|
||
| ## Usage | ||
|
|
||
| 1. Navigate to **System Definition → Scripts - Background** | ||
| 2. Copy and paste the script content | ||
| 3. (Optional) Modify `daysBack` variable to set the usage analysis timeframe (default: 30 days) | ||
| 4. Click "Run script" | ||
|
|
||
| ## What It Does | ||
|
|
||
| The script: | ||
| 1. Queries all Virtual Agent topics in the system | ||
| 2. Checks each topic's active and published status | ||
| 3. Counts conversations per topic over the past 30 days (configurable) | ||
| 4. Displays inactive topics, unpublished topics, and zero-usage topics | ||
| 5. Helps identify topics that need attention before go-live or during health checks | ||
|
|
||
| ## Report Categories | ||
|
|
||
| **Inactive Topics**: Topics where the "Active" checkbox is unchecked. These topics are disabled and won't respond to user inputs even if published. | ||
|
|
||
| **Unpublished Topics**: Topics where the "Published" checkbox is unchecked. These are draft topics not yet available to end users. | ||
|
|
||
| **Topics with Zero Usage**: Topics that are both active and published but have had no conversations in the specified timeframe. May indicate topics that need better training phrases or are not discoverable by users. |
106 changes: 106 additions & 0 deletions
106
Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/script.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| // Virtual Agent Topic Coverage Report | ||
| // Analyzes VA topic configuration health and usage patterns | ||
|
|
||
| var daysBack = 30; // Analyze topic usage from the past 30 days | ||
|
|
||
| // Calculate date range for usage analysis | ||
| var startDate = new GlideDateTime(); | ||
| startDate.addDaysLocalTime(-daysBack); | ||
|
|
||
| gs.info('=== Virtual Agent Topic Coverage Report ==='); | ||
| gs.info('Analyzing topics and usage from: ' + startDate.getDisplayValue()); | ||
|
|
||
| // Get all VA topics | ||
| var topicGr = new GlideRecord('sys_cs_topic'); | ||
| if (!topicGr.isValid()) { | ||
| gs.warn('Table sys_cs_topic not found. Virtual Agent may not be installed.'); | ||
| } else { | ||
| topicGr.query(); | ||
|
|
||
| var totalTopics = topicGr.getRowCount(); | ||
| gs.info('Total Topics: ' + totalTopics); | ||
|
|
||
| var inactiveTopics = []; | ||
| var unpublishedTopics = []; | ||
| var zeroUsageTopics = []; | ||
| var topicUsage = {}; | ||
|
|
||
| // Auto-detect conversation table field name | ||
| var convGr = new GlideRecord('sys_cs_conversation'); | ||
| var topicField = null; | ||
| if (convGr.isValid()) { | ||
| topicField = convGr.isValidField('topic') ? 'topic' : | ||
| (convGr.isValidField('selected_topic') ? 'selected_topic' : null); | ||
| } | ||
|
|
||
| while (topicGr.next()) { | ||
| var topicId = topicGr.getUniqueValue(); | ||
| var topicName = topicGr.getValue('name'); | ||
| var isActive = topicGr.getValue('active') == 'true' || topicGr.getValue('active') == '1'; | ||
| var isPublished = topicGr.getValue('published') == 'true' || topicGr.getValue('published') == '1'; | ||
|
|
||
| // Track inactive topics | ||
| if (!isActive) { | ||
| inactiveTopics.push(topicName); | ||
| } | ||
|
|
||
| // Track unpublished topics | ||
| if (!isPublished) { | ||
| unpublishedTopics.push(topicName); | ||
| } | ||
|
|
||
| // Count conversations for this topic (if conversation table exists) | ||
| var conversationCount = 0; | ||
| if (topicField) { | ||
| var convCountGr = new GlideAggregate('sys_cs_conversation'); | ||
| convCountGr.addQuery(topicField, topicId); | ||
| convCountGr.addQuery('sys_created_on', '>=', startDate); | ||
| convCountGr.addAggregate('COUNT'); | ||
| convCountGr.query(); | ||
| if (convCountGr.next()) { | ||
| conversationCount = parseInt(convCountGr.getAggregate('COUNT')) || 0; | ||
| } | ||
| } | ||
|
|
||
| topicUsage[topicName] = conversationCount; | ||
|
|
||
| // Track topics with zero usage | ||
| if (isActive && isPublished && conversationCount === 0) { | ||
| zeroUsageTopics.push(topicName); | ||
| } | ||
| } | ||
|
|
||
| // Display results | ||
| gs.info('\n=== Inactive Topics ==='); | ||
| if (inactiveTopics.length > 0) { | ||
| for (var i = 0; i < inactiveTopics.length; i++) { | ||
| gs.info((i + 1) + '. ' + inactiveTopics[i]); | ||
| } | ||
| } else { | ||
| gs.info('No inactive topics found'); | ||
| } | ||
|
|
||
| gs.info('\n=== Unpublished Topics ==='); | ||
| if (unpublishedTopics.length > 0) { | ||
| for (var j = 0; j < unpublishedTopics.length; j++) { | ||
| gs.info((j + 1) + '. ' + unpublishedTopics[j]); | ||
| } | ||
| } else { | ||
| gs.info('No unpublished topics found'); | ||
| } | ||
|
|
||
| gs.info('\n=== Topics with Zero Usage (Active & Published) ==='); | ||
| if (zeroUsageTopics.length > 0) { | ||
| for (var k = 0; k < zeroUsageTopics.length; k++) { | ||
| gs.info((k + 1) + '. ' + zeroUsageTopics[k]); | ||
| } | ||
| } else { | ||
| if (topicField) { | ||
| gs.info('All active & published topics have been used'); | ||
| } else { | ||
| gs.info('Cannot analyze usage - conversation table not available'); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| gs.info('\n=== Analysis Complete ==='); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file appears to have been included in error