Skip to content

Commit ef13ea1

Browse files
committed
added VA topic coverage checker
1 parent 452ffcf commit ef13ea1

File tree

4 files changed

+222
-0
lines changed

4 files changed

+222
-0
lines changed

Server-Side Components/Background Scripts/AI Search Usage Analytics/script.js

Whitespace-only changes.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Mock Data Seeder for VA Topic Coverage Report
2+
3+
Use this script to create test data for the Virtual Agent Topic Coverage Report.
4+
5+
## Mock Data Script
6+
7+
Run this in **System Definition → Scripts - Background** to create test topics:
8+
9+
```javascript
10+
// Generate mock VA topics for testing Topic Coverage Report
11+
// Creates topics with various states (active/inactive, published/unpublished)
12+
13+
(function() {
14+
var TEST_TOPICS = [
15+
{name: 'Password Reset Help', active: true, published: true, hasConversations: true, count: 15},
16+
{name: 'VPN Access Request', active: true, published: true, hasConversations: true, count: 8},
17+
{name: 'Laptop Request', active: true, published: true, hasConversations: false, count: 0},
18+
{name: 'Printer Support', active: true, published: false, hasConversations: false, count: 0},
19+
{name: 'Email Issues', active: false, published: true, hasConversations: false, count: 0},
20+
{name: 'Test Topic Draft', active: false, published: false, hasConversations: false, count: 0}
21+
];
22+
23+
var topicGr = new GlideRecord('sys_cs_topic');
24+
if (!topicGr.isValid()) {
25+
gs.error('Table sys_cs_topic not found. Virtual Agent may not be installed.');
26+
return;
27+
}
28+
29+
// Auto-detect conversation field
30+
var convGr = new GlideRecord('sys_cs_conversation');
31+
var topicField = null;
32+
if (convGr.isValid()) {
33+
topicField = convGr.isValidField('topic') ? 'topic' :
34+
(convGr.isValidField('selected_topic') ? 'selected_topic' : null);
35+
}
36+
37+
gs.info('Creating ' + TEST_TOPICS.length + ' test VA topics...');
38+
39+
for (var i = 0; i < TEST_TOPICS.length; i++) {
40+
var topic = TEST_TOPICS[i];
41+
42+
// Check if topic already exists
43+
topicGr.initialize();
44+
topicGr.addQuery('name', topic.name);
45+
topicGr.setLimit(1);
46+
topicGr.query();
47+
48+
var topicId;
49+
if (topicGr.next()) {
50+
topicId = topicGr.getUniqueValue();
51+
gs.info('Topic already exists: ' + topic.name);
52+
} else {
53+
// Create new topic
54+
topicGr.initialize();
55+
topicGr.setValue('name', topic.name);
56+
if (topicGr.isValidField('short_description')) {
57+
topicGr.setValue('short_description', 'Test topic for coverage report');
58+
}
59+
topicGr.setValue('active', topic.active);
60+
topicGr.setValue('published', topic.published);
61+
topicId = topicGr.insert();
62+
gs.info('Created topic: ' + topic.name + ' (active: ' + topic.active + ', published: ' + topic.published + ')');
63+
}
64+
65+
// Create conversations if needed
66+
if (topic.hasConversations && topicField && topicId) {
67+
for (var j = 0; j < topic.count; j++) {
68+
convGr.initialize();
69+
convGr.setValue(topicField, topicId);
70+
if (convGr.isValidField('state')) convGr.setValue('state', 2); // closed
71+
convGr.insert();
72+
}
73+
gs.info(' Created ' + topic.count + ' conversations for: ' + topic.name);
74+
}
75+
}
76+
77+
gs.info('\n=== Mock Data Complete ===');
78+
gs.info('Run the Virtual Agent Topic Coverage Report to see results!');
79+
})();
80+
```
81+
82+
## Expected Output
83+
84+
After running the mock data seeder, your coverage report should show:
85+
86+
- **Total Topics**: 6
87+
- **Inactive Topics**: 2 (Email Issues, Test Topic Draft)
88+
- **Unpublished Topics**: 2 (Printer Support, Test Topic Draft)
89+
- **Topics with Zero Usage**: 1 (Laptop Request - active & published but no conversations)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Virtual Agent Topic Coverage Report
2+
3+
A background script that analyzes Virtual Agent topic configuration health by identifying inactive, unpublished, or unused topics.
4+
5+
## Usage
6+
7+
1. Navigate to **System Definition → Scripts - Background**
8+
2. Copy and paste the script content
9+
3. (Optional) Modify `daysBack` variable to set the usage analysis timeframe (default: 30 days)
10+
4. Click "Run script"
11+
12+
## What It Does
13+
14+
The script:
15+
1. Queries all Virtual Agent topics in the system
16+
2. Checks each topic's active and published status
17+
3. Counts conversations per topic over the past 30 days (configurable)
18+
4. Displays inactive topics, unpublished topics, and zero-usage topics
19+
5. Helps identify topics that need attention before go-live or during health checks
20+
21+
## Report Categories
22+
23+
**Inactive Topics**: Topics where the "Active" checkbox is unchecked. These topics are disabled and won't respond to user inputs even if published.
24+
25+
**Unpublished Topics**: Topics where the "Published" checkbox is unchecked. These are draft topics not yet available to end users.
26+
27+
**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.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Virtual Agent Topic Coverage Report
2+
// Analyzes VA topic configuration health and usage patterns
3+
4+
var daysBack = 30; // Analyze topic usage from the past 30 days
5+
6+
// Calculate date range for usage analysis
7+
var startDate = new GlideDateTime();
8+
startDate.addDaysLocalTime(-daysBack);
9+
10+
gs.info('=== Virtual Agent Topic Coverage Report ===');
11+
gs.info('Analyzing topics and usage from: ' + startDate.getDisplayValue());
12+
13+
// Get all VA topics
14+
var topicGr = new GlideRecord('sys_cs_topic');
15+
if (!topicGr.isValid()) {
16+
gs.warn('Table sys_cs_topic not found. Virtual Agent may not be installed.');
17+
} else {
18+
topicGr.query();
19+
20+
var totalTopics = topicGr.getRowCount();
21+
gs.info('Total Topics: ' + totalTopics);
22+
23+
var inactiveTopics = [];
24+
var unpublishedTopics = [];
25+
var zeroUsageTopics = [];
26+
var topicUsage = {};
27+
28+
// Auto-detect conversation table field name
29+
var convGr = new GlideRecord('sys_cs_conversation');
30+
var topicField = null;
31+
if (convGr.isValid()) {
32+
topicField = convGr.isValidField('topic') ? 'topic' :
33+
(convGr.isValidField('selected_topic') ? 'selected_topic' : null);
34+
}
35+
36+
while (topicGr.next()) {
37+
var topicId = topicGr.getUniqueValue();
38+
var topicName = topicGr.getValue('name');
39+
var isActive = topicGr.getValue('active') == 'true' || topicGr.getValue('active') == '1';
40+
var isPublished = topicGr.getValue('published') == 'true' || topicGr.getValue('published') == '1';
41+
42+
// Track inactive topics
43+
if (!isActive) {
44+
inactiveTopics.push(topicName);
45+
}
46+
47+
// Track unpublished topics
48+
if (!isPublished) {
49+
unpublishedTopics.push(topicName);
50+
}
51+
52+
// Count conversations for this topic (if conversation table exists)
53+
var conversationCount = 0;
54+
if (topicField) {
55+
var convCountGr = new GlideAggregate('sys_cs_conversation');
56+
convCountGr.addQuery(topicField, topicId);
57+
convCountGr.addQuery('sys_created_on', '>=', startDate);
58+
convCountGr.addAggregate('COUNT');
59+
convCountGr.query();
60+
if (convCountGr.next()) {
61+
conversationCount = parseInt(convCountGr.getAggregate('COUNT')) || 0;
62+
}
63+
}
64+
65+
topicUsage[topicName] = conversationCount;
66+
67+
// Track topics with zero usage
68+
if (isActive && isPublished && conversationCount === 0) {
69+
zeroUsageTopics.push(topicName);
70+
}
71+
}
72+
73+
// Display results
74+
gs.info('\n=== Inactive Topics ===');
75+
if (inactiveTopics.length > 0) {
76+
for (var i = 0; i < inactiveTopics.length; i++) {
77+
gs.info((i + 1) + '. ' + inactiveTopics[i]);
78+
}
79+
} else {
80+
gs.info('No inactive topics found');
81+
}
82+
83+
gs.info('\n=== Unpublished Topics ===');
84+
if (unpublishedTopics.length > 0) {
85+
for (var j = 0; j < unpublishedTopics.length; j++) {
86+
gs.info((j + 1) + '. ' + unpublishedTopics[j]);
87+
}
88+
} else {
89+
gs.info('No unpublished topics found');
90+
}
91+
92+
gs.info('\n=== Topics with Zero Usage (Active & Published) ===');
93+
if (zeroUsageTopics.length > 0) {
94+
for (var k = 0; k < zeroUsageTopics.length; k++) {
95+
gs.info((k + 1) + '. ' + zeroUsageTopics[k]);
96+
}
97+
} else {
98+
if (topicField) {
99+
gs.info('All active & published topics have been used');
100+
} else {
101+
gs.info('Cannot analyze usage - conversation table not available');
102+
}
103+
}
104+
}
105+
106+
gs.info('\n=== Analysis Complete ===');

0 commit comments

Comments
 (0)