In the world of Salesforce Service Cloud, managing user expectations during a hand-off is critical for a high-quality Customer Experience (CX). With Salesforce Enhanced Messaging, developers and architects have more control than ever over the conversation lifecycle.
One common requirement is notifying the user when their session has been transferred between agents or queues. Here is a technical guide on how to implement Transfer Notifications using the Embedded Messaging API.
Master Salesforce Enhanced Chat: Implementing Transfer Notifications with utilAPI
The Challenge: Improving Visibility During Handoffs
In standard chat configurations, users are often left in the dark when a “Transfer” occurs. For technical teams, the goal is to provide a seamless transition by programmatically identifying the routing state and alerting the user via the chat interface.
The Solution: Leveraging onEmbeddedMessagingConversationRouted
The onEmbeddedMessagingConversationRouted event is a powerful listener that triggers whenever a Messaging Session is assigned—whether it’s the initial routing or a subsequent transfer to another agent or bot.
Implementation Guide
To implement this, you need to set up an event listener on the window object to capture the routing payload and then use the utilAPI to push a message back to the UI.
1. Listening for the Routing Event
By inspecting the entryPayload within the event detail, we can parse the routingType. This allows us to distinguish between a brand-new session and an escalated or transferred one.
/* START:: Conversation Routed Listener */
window.addEventListener("onEmbeddedMessagingConversationRouted", (event) => {
console.log( "Conversation Routed" );
console.log( "Event detail: ", JSON.stringify( event.detail ) );
const payloadString = event.detail.conversationEntry.entryPayload;
const innerData = JSON.parse(payloadString);
const routingType = innerData.routingType;
console.log(routingType);
if ( routingType == "Initial" ) {
sendMessageToUser('Initial Transfer');
} else if ( routingType == "Transfer" ) {
sendMessageToUser('Subsequent Transfer');
}
});
/* END:: Conversation Routed Listener */
2. Sending the Notification via utilAPI
Once we’ve identified the transfer, we use the embeddedservice_bootstrap.utilAPI.sendTextMessage method. This programmatically inserts a message into the transcript as if it were sent by the system or user.
function sendMessageToUser(message) {
embeddedservice_bootstrap.utilAPI.sendTextMessage(message)
.then(() => {
console.log("Message sent");
})
.catch(() => {
console.log("Message not sent");
})
.finally(() => {
console.log("Message sent - finally");
});
}
Best Practices & Recommendations
Based on the implementation above, here are several technical recommendations for Architects and Developers:
- Error Handling: Always include the
.catch()block when usingsendTextMessage. If the network is unstable or the session has expired, the message will fail; you should log these instances to a monitoring service. - Payload Validation: Before calling
JSON.parse(payloadString), ensurepayloadStringis not null or undefined to prevent runtime script errors that could break the entire chat widget. - User Experience (UX) Tip: Instead of generic strings like “Initial Transfer,” use user-friendly language like “Please wait while we connect you with an expert…” or “You are being transferred to our specialized billing team.”
- Security: Avoid sending sensitive data through
sendTextMessageas these messages are visible in the clear-text transcript for the user.
Embedded Service Deployment Code Snippet
<html lang="en">
<script type='text/javascript'>
function sendMessageToUser(message) {
embeddedservice_bootstrap.utilAPI.sendTextMessage(message)
.then(() => {
console.log("Message sent");
})
.catch(() => {
console.log("Message not sent");
})
.finally(() => {
console.log("Message sent - finally");
});
}
function initEmbeddedMessaging() {
try {
embeddedservice_bootstrap.settings.language = 'en_US'; // For example, enter 'en' or 'en-US'
/* START:: Conversation Routed Listener */
window.addEventListener("onEmbeddedMessagingConversationRouted", (event) => {
console.log("Conversation Routed");
console.log("Event detail: ", JSON.stringify(event.detail));
const payloadString = event.detail.conversationEntry.entryPayload;
const innerData = JSON.parse(payloadString);
const routingType = innerData.routingType;
console.log(routingType);
if (routingType == "Initial") {
sendMessageToUser('Initial Transfer');
} else if (routingType == "Transfer") {
sendMessageToUser('Subsequent Transfer');
}
});
/* END:: Conversation Routed Listener */
embeddedservice_bootstrap.init(
'<Your Org Id>',
'<Your Embedded Service DeploymentName>',
'<Your Site URL>',
{
scrt2URL: '<Your SCRT2 URL>'
}
);
} catch (err) {
console.error('Error loading Embedded Messaging: ', err);
}
};
</script>
<script type='text/javascript' src='<Your Site URL>/assets/js/bootstrap.min.js' onload='initEmbeddedMessaging()'></script>
</html>
onEmbeddedMessagingConversationRouted Event
https://developer.salesforce.com/docs/service/messaging-web/guide/event-listeners.html
embeddedservice_bootstrap.utilAPI.sendTextMessage method
https://developer.salesforce.com/docs/service/messaging-web/guide/send-message.html