Skip to navigation

Optional Lab: Live Agent Handoff

View as Markdown

This optional Live Agent Handoff lab cannot be fully tested in the cohort training instances. Those ServiceNow instances do not permit outbound REST traffic, so the live agent message-brokering callbacks to Moveworks (api.moveworks.ai/rest/LiveAgentService/...) fail at the network layer. The configuration walkthrough remains useful, but 2.1: Test the Handoff will not succeed in a cohort training instance.

Use the walkthrough as an implementation reference for your own ServiceNow tenant where outbound REST is permitted. See Configure ServiceNow Live Agent Message Brokering for the canonical product documentation.

This lab is optional and isn’t part of the standard ILT flow. It needs a ServiceNow instance with the Moveworks Live Agent update sets and a second ServiceNow user to act as the agent. Confirm with your ILT host before starting.

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:
    • Lab #8 complete
    • A ServiceNow instance with these update sets applied (your ILT host provides them):
      • Moveworks Live Agent VA API Config (Virtual Agent API scope)
      • Moveworks Live Agent AWA Config (Global scope)
    • Access to Tool Studio in My Moveworks (for the API key)
    • ServiceNow admin credentials for your lab instance
    • A ServiceNow instance that allows outbound REST traffic to api.moveworks.ai. The cohort training instances do not; see the warning above.

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 can’t resolve a user’s issue, it hands the conversation to a human agent.

  • Message Brokering vs. Deep Link: Message brokering keeps the conversation in the user’s chat platform (Slack or Teams). The deep link approach sends users to a ServiceNow portal instead.
  • 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.

Relevant documentation:

🛠️ 1: Walkthrough

1.1: Verify ServiceNow Prerequisites

The update sets handle most of the ServiceNow configuration. Verify they were applied correctly before continuing.

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:

(function() {
gs.print('=== Verifying VA API Config ===');
var rest = new GlideRecord('sys_rest_message');
rest.addQuery('name', 'VA Bot to Bot');
rest.query();
if (rest.next()) {
gs.print('VA Bot to Bot endpoint: ' + rest.rest_endpoint);
} else {
gs.print('ERROR: VA Bot to Bot REST message not found');
}
var post = new GlideRecord('sys_rest_message_fn');
post.addQuery('rest_message', rest.sys_id);
post.addQuery('http_method', 'POST');
post.query();
if (post.next()) {
gs.print('POST endpoint: ' + post.rest_endpoint);
} else {
gs.print('ERROR: POST method not found');
}
gs.print('\n=== Verifying AWA Config ===');
var q = new GlideRecord('awa_queue');
q.addQuery('name', 'Moveworks Labs Live Agent Chat Queue');
q.query();
if (q.next()) {
gs.print('Queue: ' + q.name + ' | active=' + q.active + ' | channel=' + q.service_channel.getDisplayValue());
} else {
gs.print('Chat queue not found');
}
var ar = new GlideRecord('awa_assignment_rule');
ar.addQuery('name', 'Chat - Most Capacity');
ar.query();
if (ar.next()) {
gs.print('Assignment Rule: ' + ar.name + ' | active=' + ar.active);
} else {
gs.print('Assignment rule not found');
}
var ep = new GlideRecord('awa_eligibility_pool');
ep.addQuery('display_name', 'Agent Chat Group : Chat - Most Capacity');
ep.query();
if (ep.next()) {
gs.print('Eligibility Pool: ' + ep.display_name);
} else {
gs.print('ERROR: Eligibility pool not found');
}
gs.print('\n=== Verification Complete ===');
})();

Expected Output:

Every line should match. If any line shows ERROR, the update set may not have been applied correctly. Contact your ILT host.

*** 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 an API Key

  1. In My Moveworks, open HTTP Connectors from the waffle menu.

  2. Click Credentials, then Create.

  3. Enter a Credential Name (for example, ServiceNow Live Agent API Key).

  4. Choose API Key.

Copy the API key as soon as you click Publish and save it somewhere secure. It isn’t displayed again.

  1. Click Publish and save the API key.

1.3: Set the 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)

These records live in the Virtual Agent API application scope, not Global. See ServiceNow application scopes.

Click the link shown below to switch to the Virtual Agent API scope before editing.

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

  1. Click Update

1.4: Set the 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 https://[your-instance].service-now.com/token_verification_list.do

  2. Open the record named Moveworks Live Agent Message Brokering - IT

  3. Set a secure password in Token. Save it; you need it in Section 1.7.

  4. Click Update


1.5: Configure Live Agent Handoff

  1. In Moveworks Setup, 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:

{
"language": "language OR null",
"liveagent_optional_skills": "domain OR null"
}

  1. Set the Integration ID to snow (the connector from Lab #3)

  2. Set Enable Live Agent to TRUE

  3. Click Run and enter your email to confirm the rule evaluates to TRUE for you.

Field NameAction / Value to Enter
ConfigurationAgent Broker Handoff
Handoff Identifieragent_broker_instance_1
Integration IDsnow
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
Live Agent Handoffagent_broker_instance_1 (the configuration from 1.5; required, or the item won’t save)
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 Item display key (agent_broker_instance_1) is set under Map of actions for handoff items
  3. Set the Value field to a user-friendly name (for example, Live Chat). Users see this name when they choose the handoff option. If the values are already set, continue to the next section.

If the item display key has no action text in Display Configurations, the Start agent chat button doesn’t appear in the AI Assistant.


1.7: Add the Token to the ServiceNow Connector

  1. In Moveworks Setup, navigate to Connectors > Built-in Connectors

  2. Find the snow connector 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 this script in Scripts - Background to configure the live agent user. Set userName to the ServiceNow user ID of the agent:

Set the instance to Global scope first.

You can’t answer your own live agent chat, so the agent must be a different user from the one starting the handoff. If your instance doesn’t have a second user, create one in User Administration > Users first. The script is preset to moveworks.admin; change userName to your agent’s user ID.

(function() {
var userName = 'moveworks.admin'; // <-- Set your agent's user ID here
var user = new GlideRecord('sys_user');
user.addQuery('user_name', userName);
user.query();
if (!user.next()) { gs.print('User not found: ' + userName); return; }
gs.print('Setting up agent: ' + user.getDisplayValue() + ' (' + userName + ')');
// Add to Agent Chat Group
var grp = new GlideRecord('sys_user_group');
grp.addQuery('name', 'Agent Chat Group');
grp.query();
if (!grp.next()) { gs.print('ERROR: Agent Chat Group not found'); return; }
var gm = new GlideRecord('sys_user_grmember');
gm.addQuery('group', grp.sys_id);
gm.addQuery('user', user.sys_id);
gm.query();
if (!gm.next()) {
gm.newRecord();
gm.group = grp.sys_id;
gm.user = user.sys_id;
gm.insert();
gs.print(' Added to Agent Chat Group');
} else {
gs.print(' Already in Agent Chat Group');
}
// Grant awa_agent role
var role = new GlideRecord('sys_user_role');
role.addQuery('name', 'awa_agent');
role.query();
if (role.next()) {
var hr = new GlideRecord('sys_user_has_role');
hr.addQuery('user', user.sys_id);
hr.addQuery('role', role.sys_id);
hr.query();
if (!hr.next()) {
hr.newRecord();
hr.user = user.sys_id;
hr.role = role.sys_id;
hr.insert();
gs.print(' Granted awa_agent role');
} else {
gs.print(' Already has awa_agent role');
}
}
// Create agent presence
var ap = new GlideRecord('awa_agent_presence');
ap.addQuery('agent', user.sys_id);
ap.query();
if (!ap.next()) {
ap.newRecord();
ap.agent = user.sys_id;
var ps = new GlideRecord('awa_presence_state');
ps.addQuery('name', 'Available');
ps.query();
if (ps.next()) ap.current_presence_state = ps.sys_id;
ap.insert();
gs.print(' Created agent presence (Available)');
} else {
gs.print(' Agent presence exists | state=' + ap.current_presence_state.getDisplayValue());
}
// Create Chat capacity
var ch = new GlideRecord('awa_service_channel');
ch.addQuery('name', 'Chat');
ch.query();
if (ch.next()) {
var ac = new GlideRecord('awa_agent_capacity');
ac.addQuery('user', user.sys_id);
ac.addQuery('channel', ch.sys_id);
ac.query();
if (!ac.next()) {
ac.newRecord();
ac.user = user.sys_id;
ac.channel = ch.sys_id;
ac.applied_max_capacity = 4;
ac.insert();
gs.print(' Created Chat capacity (max=4)');
} else {
gs.print(' Chat capacity exists');
}
// Create Chat availability
var aca = new GlideRecord('awa_agent_channel_availability');
aca.addQuery('agent', user.sys_id);
aca.addQuery('service_channel', ch.sys_id);
aca.query();
if (!aca.next()) {
aca.newRecord();
aca.agent = user.sys_id;
aca.service_channel = ch.sys_id;
aca.available = true;
aca.insert();
gs.print(' Created Chat availability (available=true)');
} else {
gs.print(' Chat availability exists');
}
}
gs.print('\nDone! Set your status to Available in Service Operations Workspace.');
})();

Expected Output:

Impersonate your agent user (shown here as moveworks.admin).

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


✅ 2: Verification & Testing

2.1: Test the Handoff

This test requires a ServiceNow tenant that allows outbound REST traffic. The cohort training instances do not. In those instances, handoff initiation succeeds until ServiceNow tries to call back into api.moveworks.ai; the chat session is then not brokered into Service Operations Workspace. Skip this test in a cohort training instance, or run it in your own tenant where outbound REST is permitted.

  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 starts. Check Service Operations Workspace for the incoming chat.

Impersonate the agent user (for example, moveworks.admin) to receive the 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 run 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, AWA routing is broken
”Start agent chat” button doesn’t appearItem display key has no action text in Display ConfigurationsVerify Display Configurations > Handoff has an action text for the item display key
Auth errors from ServiceNowAPI key not set in auth profile, or token mismatchVerify auth profile password and connector token match

Next: Return to the Moveworks Setup labs to continue with the core labs or pick another optional lab.


🪞 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 Details

ComponentWhereWhat
API KeyMy Moveworks > 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 HandoffMoveworks Setup > Handoff > Live Agent HandoffAgent Broker Handoff config with handoff identifier and integration ID
Smart HandoffMoveworks Setup > Handoff > Handoff SettingsItem display key and display configuration
Connector TokenMoveworks Setup > Connectors > Built-in ConnectorsToken verification password added to ServiceNow connector
Agent SetupServiceNow > Scripts - BackgroundAgent added to Chat queue with roles, presence, and capacity