Lab #7: Handoff — Live Agent

View as Markdown

Overview

  • Learning Objectives: Configure Moveworks to broker live agent chat sessions between users and ServiceNow agents using the Virtual Agent API integration.
  • Estimated Time: 30 minutes
  • Prerequisites:
    • Access to a ServiceNow lab instance with the following update sets already applied:
      • Moveworks Live Agent VA API Config (Virtual Agent API scope)
      • Moveworks Live Agent AWA Config (Global scope)
    • Access to your tenant’s MyMoveworks portal with the Agent Studio module
    • ServiceNow admin credentials for your lab instance

Key Concepts

Live Agent Message Brokering allows Moveworks to act as a bridge between end users in their chat platform (Slack, Teams, etc.) and live agents in ServiceNow’s Service Operations Workspace. When the AI Assistant cannot resolve a user’s issue, it can seamlessly hand off the conversation to a human agent.

  • Message Brokering vs. Deep Link: Message brokering keeps the conversation within the user’s native chat platform (Slack/Teams). The alternative deep link approach redirects users to a ServiceNow portal. Message brokering provides a better user experience.
  • Virtual Agent API: Moveworks uses ServiceNow’s Virtual Agent Bot-to-Bot API (/api/sn_va_as_service/bot/integration) to initiate conversations and relay messages between users and agents.
  • Agent Availability: Moveworks checks the awa_agent_presence_capacity table to determine if agents are available before offering the handoff option.
  • AWA Routing: Interactions must be routed through Advanced Work Assignment (AWA) queues. Without a properly configured queue, assignment rule, and eligibility pool, interactions will immediately close.

🛠️ 1: Walkthrough

1.1 Verify ServiceNow Prerequisites

Warning: The update sets handle most of the ServiceNow configuration. Before proceeding, verify the setup was applied correctly.

Verify Virtual Agent API Plugin

  1. In your ServiceNow instance, navigate to System Applications > All Available Applications > All
  2. Search for Virtual Agent API and confirm it is installed
  3. Search for Agent Chat plugin and confirm it is installed

Verify Update Set Configurations

Run the following script in Scripts - Background to confirm the update sets were applied correctly:

1(function() {
2 gs.print('=== Verifying VA API Config ===');
3
4 var rest = new GlideRecord('sys_rest_message');
5 rest.addQuery('name', 'VA Bot to Bot');
6 rest.query();
7 if (rest.next()) {
8 gs.print('VA Bot to Bot endpoint: ' + rest.rest_endpoint);
9 } else {
10 gs.print('ERROR: VA Bot to Bot REST message not found');
11 }
12
13 var post = new GlideRecord('sys_rest_message_fn');
14 post.addQuery('rest_message', rest.sys_id);
15 post.addQuery('http_method', 'POST');
16 post.query();
17 if (post.next()) {
18 gs.print('POST endpoint: ' + post.rest_endpoint);
19 } else {
20 gs.print('ERROR: POST method not found');
21 }
22
23 gs.print('\n=== Verifying AWA Config ===');
24
25 var q = new GlideRecord('awa_queue');
26 q.addQuery('name', 'Moveworks Labs Live Agent Chat Queue');
27 q.query();
28 if (q.next()) {
29 gs.print('Queue: ' + q.name + ' | active=' + q.active + ' | channel=' + q.service_channel.getDisplayValue());
30 } else {
31 gs.print('Chat queue not found');
32 }
33
34 var ar = new GlideRecord('awa_assignment_rule');
35 ar.addQuery('name', 'Chat - Most Capacity');
36 ar.query();
37 if (ar.next()) {
38 gs.print('Assignment Rule: ' + ar.name + ' | active=' + ar.active);
39 } else {
40 gs.print('Assignment rule not found');
41 }
42
43 var ep = new GlideRecord('awa_eligibility_pool');
44 ep.addQuery('display_name', 'Agent Chat Group : Chat - Most Capacity');
45 ep.query();
46 if (ep.next()) {
47 gs.print('Eligibility Pool: ' + ep.display_name);
48 } else {
49 gs.print('ERROR: Eligibility pool not found');
50 }
51
52 gs.print('\n=== Verification Complete ===');
53})();

Expected Output:

Note: All lines should show the expected values. If any line shows ERROR, the update set may not have been applied correctly. Contact your lab instructor.

*** Script: === Verifying VA API Config ===
*** Script: VA Bot to Bot endpoint: https://api.moveworks.ai
*** Script: POST endpoint: https://api.moveworks.ai/rest/LiveAgentService/SnowSendMessageToUser
*** Script:
=== Verifying AWA Config ===
*** Script: Queue: Moveworks Labs Live Agent Chat Queue | active=true | channel=Chat
*** Script: Assignment Rule: Chat - Most Capacity | active=undefined
*** Script: Eligibility Pool: Agent Chat Group : Chat - Most Capacity
*** Script:
=== Verification Complete ===

1.2 Generate API Key

  1. Navigate to the MyMoveworks portal
  2. Open the HTTP Connectors App
  3. Click on Credentials and click Create
  4. Enter a Credential Name (e.g., ServiceNow Live Agent API Key)
  5. Choose API Key

Warning: Once you click Publish, copy and paste the API Key immediately and save it in a secure location. This key will not be displayed again.

  1. Click Publish and save the API Key securely

1.3 Set Auth Profile Password in ServiceNow

The update set creates the auth profile but cannot transport the password. You must enter the API key you just generated.

  1. In your ServiceNow instance, navigate to Outbound > REST Message
  2. Click into VA Bot to Bot
  3. Open the POST method record called postMessage (listed under HTTP Methods)
  4. Go to the Authentication tab and open the auth profile Moveworks Live Agent Auth (click the “i” icon and select open record)

Note: Some of these configurations reside within the Virtual Agent API application scope rather than the Global scope. You can learn more about application scopes here.

To complete the remaining steps, please click the link below to allow the changes to occur within the Virtual Agent API scope.

  1. Enter the API key from Section 1.2 as the Password

Note: To complete the remaining steps, please click the link below to allow the changes to occur within the Virtual Agent API scope.

  1. Click Update

1.4 Set Token Verification Password in ServiceNow

The update set creates the token verification record but cannot transport the password. You must set it manually.

  1. Navigate to [your_instance]/token_verification_list.do
  2. Open the record named Moveworks Live Agent Message Brokering - IT
  3. Set any secure password in Tokensave this password securely, you will need it in Section 1.6
  4. Click Update

1.5 Configure Live Agent Handoff

  1. In MyMoveworks, navigate to Handoff > Live Agent Handoff
  2. Click Create to add a new configuration
  3. Set Configuration to Agent Broker Handoff
  4. Open the Live Agent Handoff dropdown and set the Handoff Identifier (e.g., agent_broker_instance_1)
  5. Configure the Snow Handoff Config Context Bender with the following default payload:
1{
2 "language": "language OR null",
3 "liveagent_optional_skills": "domain OR null"
4}

  1. Set the Integration ID to the ServiceNow connector that will be used as the live agent chat platform
  2. Set Enable Live Agent to TRUE
  3. Click Run and enter your email. This confirms the DSL rule evaluates to TRUE for your profile, ensuring that Live Agent is correctly enabled for you.
Field NameAction / Value to Enter
ConfigurationAgent Broker Handoff
Handoff Identifieragent_broker_instance_1
Trigger Rulecontext.domain == "IT_DOMAIN"
Integration IDYour ServiceNow connector
Enable Live AgentTRUE

1.6 Configure Smart Handoff

  1. Navigate to Handoff > Handoff Settings
  2. Expand Setup items for categories, then add a new Item Display Key with the following values (you may need to scroll to the bottom and click Add +)
Field NameAction / Value to Enter
Item display keyagent_broker_instance_1
Metadata DomainIT_DOMAIN
Handoff TypeAGENT_HANDOFF
Pretrigger RuleIF (context.domain_candidates[0].domain == "IT_DOMAIN") THEN 1.0 ELSE 0.5
Category display keysIT

  1. Navigate to Display Configurations > Handoff
  2. Scroll down within the Handoff configurations and ensure the Handoff Identifier (agent_broker_instance_1) is set under Map of actions for handoff items
  3. Set the Value field to a user-friendly name (e.g., Live Chat) — this is what users will see when selecting this handoff option (if these values are already preset, you are done and can move on to the next step)

Note: If the Handoff Identifier is not set in Display Configurations, the “Start agent chat” button will not appear in the AI Assistant.


1.7 Update ServiceNow Connector with Token

  1. In Moveworks Setup, navigate to Connectors > Built-in Connectors
  2. Find the ServiceNow connector for your lab instance and click Edit
  3. Add the token password from Section 1.4 to the ServiceNow Virtual Agent API Token field
  4. Click Save

1.8 Set Up Your Agent in ServiceNow

Run the following script in Scripts - Background to configure your user as a live agent. Replace CHANGE_ME with your ServiceNow username:

Note 1: Make sure the instance is set to Global scope.

Note 2: The script is pre-configured to set up moveworks.admin (Jordan Taylor) as the live agent. You cannot answer your own live agent chat — the agent receiving the chat must be a different user than the one initiating the handoff.

1(function() {
2 var userName = 'moveworks.admin'; // <-- Set your moveworks.admin here
3
4 var user = new GlideRecord('sys_user');
5 user.addQuery('user_name', userName);
6 user.query();
7 if (!user.next()) { gs.print('User not found: ' + userName); return; }
8 gs.print('Setting up agent: ' + user.getDisplayValue() + ' (' + userName + ')');
9
10 // Add to Agent Chat Group
11 var grp = new GlideRecord('sys_user_group');
12 grp.addQuery('name', 'Agent Chat Group');
13 grp.query();
14 if (!grp.next()) { gs.print('ERROR: Agent Chat Group not found'); return; }
15
16 var gm = new GlideRecord('sys_user_grmember');
17 gm.addQuery('group', grp.sys_id);
18 gm.addQuery('user', user.sys_id);
19 gm.query();
20 if (!gm.next()) {
21 gm.newRecord();
22 gm.group = grp.sys_id;
23 gm.user = user.sys_id;
24 gm.insert();
25 gs.print(' Added to Agent Chat Group');
26 } else {
27 gs.print(' Already in Agent Chat Group');
28 }
29
30 // Grant awa_agent role
31 var role = new GlideRecord('sys_user_role');
32 role.addQuery('name', 'awa_agent');
33 role.query();
34 if (role.next()) {
35 var hr = new GlideRecord('sys_user_has_role');
36 hr.addQuery('user', user.sys_id);
37 hr.addQuery('role', role.sys_id);
38 hr.query();
39 if (!hr.next()) {
40 hr.newRecord();
41 hr.user = user.sys_id;
42 hr.role = role.sys_id;
43 hr.insert();
44 gs.print(' Granted awa_agent role');
45 } else {
46 gs.print(' Already has awa_agent role');
47 }
48 }
49
50 // Create agent presence
51 var ap = new GlideRecord('awa_agent_presence');
52 ap.addQuery('agent', user.sys_id);
53 ap.query();
54 if (!ap.next()) {
55 ap.newRecord();
56 ap.agent = user.sys_id;
57 var ps = new GlideRecord('awa_presence_state');
58 ps.addQuery('name', 'Available');
59 ps.query();
60 if (ps.next()) ap.current_presence_state = ps.sys_id;
61 ap.insert();
62 gs.print(' Created agent presence (Available)');
63 } else {
64 gs.print(' Agent presence exists | state=' + ap.current_presence_state.getDisplayValue());
65 }
66
67 // Create Chat capacity
68 var ch = new GlideRecord('awa_service_channel');
69 ch.addQuery('name', 'Chat');
70 ch.query();
71 if (ch.next()) {
72 var ac = new GlideRecord('awa_agent_capacity');
73 ac.addQuery('user', user.sys_id);
74 ac.addQuery('channel', ch.sys_id);
75 ac.query();
76 if (!ac.next()) {
77 ac.newRecord();
78 ac.user = user.sys_id;
79 ac.channel = ch.sys_id;
80 ac.applied_max_capacity = 4;
81 ac.insert();
82 gs.print(' Created Chat capacity (max=4)');
83 } else {
84 gs.print(' Chat capacity exists');
85 }
86
87 // Create Chat availability
88 var aca = new GlideRecord('awa_agent_channel_availability');
89 aca.addQuery('agent', user.sys_id);
90 aca.addQuery('service_channel', ch.sys_id);
91 aca.query();
92 if (!aca.next()) {
93 aca.newRecord();
94 aca.agent = user.sys_id;
95 aca.service_channel = ch.sys_id;
96 aca.available = true;
97 aca.insert();
98 gs.print(' Created Chat availability (available=true)');
99 } else {
100 gs.print(' Chat availability exists');
101 }
102 }
103
104 gs.print('\nDone! Set your status to Available in Service Operations Workspace.');
105})();

Expected Output:

Impersonate moveworks.admin (Jordan Taylor)

After running the script, open Service Operations Workspace in ServiceNow and set your status to Available.


✅ 2: Verification & Testing

2.1 Test the Handoff

  1. Open your AI Assistant
  2. Start a conversation and click Get Help
  3. Select Start agent chat
  4. Verify the description and click Submit
  5. The live agent session should begin — check Service Operations Workspace for the incoming chat

Note: Impersonate the moveworks.admin user (Jordan Taylor) to receive the incoming chat in Service Operations Workspace.


2.2 Troubleshooting

SymptomLikely CauseHow to Check
”No agents available”Agent not set to Available in SOW, or schedule config blockingVerify agent status in SOW; check awa_agent_presence_capacity API. In ServiceNow, navigate to Service Operations Workspace, set your status to Available, then verify agents are available by running: GET [your_instance]/api/now/table/awa_agent_presence_capacity?sysparm_query=aca_available=true — you should see at least one result with aca_available: true
Interaction created but immediately closesAWA queue, assignment rule, or eligibility pool missing/misconfiguredCheck interaction.list — if active=false and queue is empty, the AWA routing is broken
”Start agent chat” button doesn’t appearHandoff Identifier not set in Display ConfigurationsVerify Display Configurations > Handoff has the correct identifier
Auth errors from ServiceNowAPI key not set in auth profile, or token mismatchVerify auth profile password and connector token match

You’ve completed the Moveworks Setup labs! Recommended next step: the Agent Studio Quickstart series, which walks you through building plugins on top of your now-configured Moveworks instance. Start with the Purple API Tool to set up your shared session, then work through Quickstart #1.


🪞 3: Reflecting on This Configuration

Through this lab, you’ve learned the following:

  • How to configure Moveworks Live Agent Handoff to broker chat sessions between users and ServiceNow agents
  • How to connect Moveworks and ServiceNow using the Virtual Agent Bot-to-Bot API with proper authentication (API key + token verification)
  • How to configure Smart Handoff rules to control when the live agent option appears based on domain context
  • How to verify agent availability and troubleshoot common issues like missing AWA queue configuration, closed interactions, and authentication mismatches
  • How the end-to-end flow works: availability check → interaction creation → AWA routing → agent assignment → message brokering

⚙️ 4: Configuration Summary

ComponentWhereWhat
API KeyMyMoveworks > HTTP ConnectorsGenerated credential for ServiceNow auth profile
Auth Profile PasswordServiceNow > VA Bot to Bot > POST > Auth ProfileAPI key entered as password
Token Verification PasswordServiceNow > token_verification_list.doPassword set on Moveworks token record
Live Agent HandoffMyMoveworks > Handoff > Live Agent HandoffAgent Broker Handoff config with trigger rule and integration ID
Smart HandoffMyMoveworks > Handoff > Handoff SettingsItem display key and display configuration
Connector TokenMyMoveworks > Connectors > Built-in ConnectorsToken verification password added to ServiceNow connector
Agent SetupServiceNow > Scripts - BackgroundAgent added to Chat queue with roles, presence, and capacity