Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions Specialized Areas/Virtual Agent/Conversation Analyzer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# VA Conversation Analyzer

A background script that generates comprehensive analytics reports on Virtual Agent conversations, providing insights into usage patterns, topic performance, and user engagement.

## ⚠️ Important Note

This script analyzes data from the ServiceNow Virtual Agent (VA) `sys_cs_conversation` table.


## What It Does

The script:
1. Analyzes all Virtual Agent conversations within a specified time period (default: 30 days)
2. Generates statistics on topic usage, completion rates, and abandonment patterns
3. Breaks down conversation data by department, time of day, and user engagement
4. Identifies topics with high abandonment rates that may need improvement
5. Provides actionable recommendations based on the data
6. Calculates user engagement metrics including power users vs. casual users

## Use Cases

- **Topic Performance Review**: Identify which topics are most/least effective
- **Service Improvement**: Find topics with high abandonment for optimization
- **Resource Planning**: Understand when and how users interact with VA
- **Executive Reporting**: Generate comprehensive VA usage reports
- **User Behavior Analysis**: Understand your user base's engagement patterns
- **ROI Measurement**: Track VA adoption and success metrics

## Sample Output

```
=== VA Conversation Analysis Report ===
Analyzing conversations from last 30 days

Total Conversations: 1,247

=== Topic Statistics ===

Top Topics by Conversation Count:
-----------------------------------
Password Reset
Total: 324 | Completed: 298 | Abandoned: 26 | Abandon Rate: 8.0% | Unique Users: 215

Software Request
Total: 187 | Completed: 165 | Abandoned: 22 | Abandon Rate: 11.8% | Unique Users: 134

Topics with High Abandonment (>30%):
-------------------------------------
⚠️ VPN Setup - 42.3% abandonment (11/26)
⚠️ Printer Configuration - 35.7% abandonment (5/14)

=== Department Statistics ===

IT: 456 conversations (36.6%)
HR: 298 conversations (23.9%)
Finance: 189 conversations (15.2%)

=== Time of Day Statistics ===

Morning (6am-12pm): 423 (33.9%)
Afternoon (12pm-5pm): 587 (47.1%)
Evening (5pm-10pm): 201 (16.1%)
Night (10pm-6am): 36 (2.9%)

=== User Engagement Statistics ===

Total Unique Users: 542
Power Users (5+ conversations): 89
Casual Users (<5 conversations): 453
Average Conversations per User: 2.3

=== Overall Statistics ===

Total Conversations: 1,247
Completed: 1,089 (87.3%)
Abandoned: 158 (12.7%)
Average Daily Conversations: 41.6


## Configuration Options

### Adjust Analysis Time Period
```javascript
// At the top of the script, modify:
var config = {
daysToAnalyze: 30, // Change to 7, 14, 60, 90, etc.
includeAbandoned: true,
includeCompleted: true,
minConversations: 5
};
```

### Focus on Specific Topics
```javascript
// Add after line 15 (conversations.query()):
conversations.addQuery('topic', 'specific_topic_sys_id');
```

### Filter by Department
```javascript
// Add department filter:
conversations.addQuery('user.department', 'IT');
```

## Prerequisites

- **ServiceNow Virtual Agent** plugin enabled (com.glide.cs)
- Access to `sys_cs_conversation` table
- Background script execution rights


Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
// ========================================
// VA Conversation Analyzer - Background Script
// ========================================
// Purpose: On-demand analysis of Virtual Agent conversations
// Usage: Run from Scripts - Background when you need immediate insights
// Output: Detailed analytics report in system logs
// ========================================

(function analyzeConversations() {

// Configuration
var config = {
daysToAnalyze: 30, // Analyze last 30 days
includeAbandoned: true,
includeCompleted: true,
minConversations: 5 // Minimum conversations to show in report
};

gs.info('=== VA Conversation Analysis Report ===');
gs.info('Analyzing conversations from last ' + config.daysToAnalyze + ' days');
gs.info('');

// Get all conversations in time range
var conversations = new GlideRecord('sys_cs_conversation');
conversations.addEncodedQuery('sys_created_on>=javascript:gs.daysAgoStart(' + config.daysToAnalyze + ')');
conversations.query();

var totalConversations = conversations.getRowCount();
gs.info('Total Conversations: ' + totalConversations);

if (totalConversations == 0) {
gs.info('No conversations found in the specified time period');
return;
}

// Analytics collections
var topicStats = {};
var userStats = {};
var departmentStats = {};
var timeStats = { morning: 0, afternoon: 0, evening: 0, night: 0 };
var totalAbandoned = 0;
var totalCompleted = 0;

// Process each conversation
conversations.query();
while (conversations.next()) {
var topicName = conversations.topic.getDisplayValue() || 'Unknown Topic';
var userId = conversations.getValue('user');
var state = conversations.getValue('state');
var timestamp = conversations.getValue('sys_created_on');

// Topic statistics
if (!topicStats[topicName]) {
topicStats[topicName] = {
total: 0,
abandoned: 0,
completed: 0,
users: {}
};
}
topicStats[topicName].total++;
topicStats[topicName].users[userId] = true;

if (state == 'abandoned') {
topicStats[topicName].abandoned++;
totalAbandoned++;
} else if (state == 'complete') {
topicStats[topicName].completed++;
totalCompleted++;
}

// User statistics
if (!userStats[userId]) {
userStats[userId] = 0;
}
userStats[userId]++;

// Department statistics
var department = getUserDepartment(userId);
if (!departmentStats[department]) {
departmentStats[department] = 0;
}
departmentStats[department]++;

// Time of day statistics
var timeSegment = getTimeSegment(timestamp);
timeStats[timeSegment]++;
}

// Print Topic Statistics
gs.info('');
gs.info('=== Topic Statistics ===');
gs.info('');

var topicArray = [];
for (var topic in topicStats) {
var stats = topicStats[topic];
topicArray.push({
name: topic,
total: stats.total,
abandoned: stats.abandoned,
completed: stats.completed,
uniqueUsers: Object.keys(stats.users).length,
abandonRate: ((stats.abandoned / stats.total) * 100).toFixed(1)
});
}

// Sort by total conversations
topicArray.sort(function(a, b) {
return b.total - a.total;
});

// Print top topics
gs.info('Top Topics by Conversation Count:');
gs.info('-----------------------------------');
topicArray.forEach(function(topic) {
if (topic.total >= config.minConversations) {
gs.info(topic.name);
gs.info(' Total: ' + topic.total +
' | Completed: ' + topic.completed +
' | Abandoned: ' + topic.abandoned +
' | Abandon Rate: ' + topic.abandonRate + '%' +
' | Unique Users: ' + topic.uniqueUsers);
}
});

// Print topics with high abandonment
gs.info('');
gs.info('Topics with High Abandonment (>30%):');
gs.info('-------------------------------------');
var highAbandonmentFound = false;
topicArray.forEach(function(topic) {
if (parseFloat(topic.abandonRate) > 30 && topic.total >= config.minConversations) {
gs.info('⚠️ ' + topic.name + ' - ' + topic.abandonRate + '% abandonment (' + topic.abandoned + '/' + topic.total + ')');
highAbandonmentFound = true;
}
});
if (!highAbandonmentFound) {
gs.info('None - all topics performing well!');
}

// Print Department Statistics
gs.info('');
gs.info('=== Department Statistics ===');
gs.info('');

var deptArray = [];
for (var dept in departmentStats) {
deptArray.push({
name: dept,
count: departmentStats[dept]
});
}

deptArray.sort(function(a, b) {
return b.count - a.count;
});

deptArray.forEach(function(dept) {
var percentage = ((dept.count / totalConversations) * 100).toFixed(1);
gs.info(dept.name + ': ' + dept.count + ' conversations (' + percentage + '%)');
});

// Print Time of Day Statistics
gs.info('');
gs.info('=== Time of Day Statistics ===');
gs.info('');
gs.info('Morning (6am-12pm): ' + timeStats.morning + ' (' + ((timeStats.morning / totalConversations) * 100).toFixed(1) + '%)');
gs.info('Afternoon (12pm-5pm): ' + timeStats.afternoon + ' (' + ((timeStats.afternoon / totalConversations) * 100).toFixed(1) + '%)');
gs.info('Evening (5pm-10pm): ' + timeStats.evening + ' (' + ((timeStats.evening / totalConversations) * 100).toFixed(1) + '%)');
gs.info('Night (10pm-6am): ' + timeStats.night + ' (' + ((timeStats.night / totalConversations) * 100).toFixed(1) + '%)');

// Print User Engagement Statistics
gs.info('');
gs.info('=== User Engagement Statistics ===');
gs.info('');

var totalUsers = Object.keys(userStats).length;
var powerUsers = 0;
var casualUsers = 0;

for (var user in userStats) {
if (userStats[user] >= 5) {
powerUsers++;
} else {
casualUsers++;
}
}

gs.info('Total Unique Users: ' + totalUsers);
gs.info('Power Users (5+ conversations): ' + powerUsers);
gs.info('Casual Users (<5 conversations): ' + casualUsers);
gs.info('Average Conversations per User: ' + (totalConversations / totalUsers).toFixed(1));

// Print Overall Statistics
gs.info('');
gs.info('=== Overall Statistics ===');
gs.info('');
gs.info('Total Conversations: ' + totalConversations);
gs.info('Completed: ' + totalCompleted + ' (' + ((totalCompleted / totalConversations) * 100).toFixed(1) + '%)');
gs.info('Abandoned: ' + totalAbandoned + ' (' + ((totalAbandoned / totalConversations) * 100).toFixed(1) + '%)');
gs.info('Average Daily Conversations: ' + (totalConversations / config.daysToAnalyze).toFixed(1));


gs.info('');
gs.info('=== Analysis Complete ===');

// Helper functions
function getUserDepartment(userId) {
var user = new GlideRecord('sys_user');
if (user.get(userId)) {
return user.getDisplayValue('department') || 'Unknown';
}
return 'Unknown';
}

function getTimeSegment(timestamp) {
var dt = new GlideDateTime(timestamp);
var timeStr = dt.getDisplayValue();
var hour = parseInt(timeStr.split(' ')[1].split(':')[0]);

if (hour >= 6 && hour < 12) return 'morning';
if (hour >= 12 && hour < 17) return 'afternoon';
if (hour >= 17 && hour < 22) return 'evening';
return 'night';
}

})();
Loading