Module 3 Receive inbound chats
The following diagram illustrates the steps to authorize the application using the Javascript SDK:
- Get the agent details, get the conversation details, and get the agent alias in order to cross-check future logic that handles the conversation.
- Set up the notification channel for chat interactions. To receive notifications of new chats from customers, we need to create a notification channel and subscribe to incoming chat conversations.
- Get the chat transcript for a chat interaction. This step is triggered when an agent has already started a chat interaction with a customer before opening the chat translation application. This step retrieves the chat transcript and displays it in the Genesys Cloud agent UI.
Code for inbound chats
The docs/scripts/main.js
file contains all the code that handles inbound chats. The specific code is found immediately after the code that authorizes the application.
The following code handles inbound chats:
const urlParams = new URLSearchParams(window.location.search);
currentConversationId = urlParams.get(`conversationid`);
genesysCloudLanguage = urlParams.get(`language`);
client.setPersistSettings(true, `chat-translator`);
client.setEnvironment(config.genesysCloud.region);
client.loginImplicitGrant(
config.clientID,
config.redirectUri,
{ state: JSON.stringify({
conversationId: currentConversationId,
language: genesysCloudLanguage
}) })
.then(data => {
console.log(data);
// Assign conversation id
let stateData = JSON.parse(data.state);
currentConversationId = stateData.conversationId;
genesysCloudLanguage = stateData.language;
// Get details of current user
return usersApi.getUsersMe();
}).then(userMe => {
userId = userMe.id;
agentName = userMe.name;
return getAgentAlias();
}).then(agentName => {
agentAlias = agentName ? agentName : agentAlias;
// Get current conversation
return conversationsApi.getConversation(currentConversationId);
}).then((conv) => {
currentConversation = conv;
customerName = conv.participants.find(p => p.purpose == `customer`).name;
return setupChatChannel();
}).then(data => {
// Get current chat conversations
return showChatTranscript(currentConversationId);
}).then(data => {
console.log(`Finished Setup`);
// Error handling
}).catch(e => console.log(e));
Get the agent details
The agent details we need for the chat translation assistant application are the user ID, agent name, and alias.
To get these details, we make an API call to getUsersMe()
function of the Users API. We assign the agent details to the global variables userId
and agentName
, which are consumed throughout the chat translation assistant application.
The code snippet below calls the API endpoint and assigns the returned data to global variables. In the script file, this code snippet follows the code that authorizes the application.
.then(data => {
console.log(data);
// Assign conversation id
let stateData = JSON.parse(data.state);
currentConversationId = stateData.conversationId;
genesysCloudLanguage = stateData.language;
// Get details of current user
return usersApi.getUsersMe();
}).then(userMe => {
userId = userMe.id;
agentName = userMe.name;
return getAgentAlias();
}).then(agentName => {
agentAlias = agentName ? agentName : agentAlias;
// Get current conversation
return conversationsApi.getConversation(currentConversationId);
})
Get the agent alias
To get the agent alias, use the getAgentAlias()
function, which is available only via the UI integration guide script file.
function getAgentAlias(){
return fetch(`https://api.${config.genesysCloud.region}/api/v2/users/${userId}/profile?fl=*`, {
method: `GET`,
headers: {
`Authorization`: `bearer ${client.authData.accessToken}`
},
})
.then(response => response.json())
.then(data => {
return data.agent ? data.agent.name[0].value : null;
})
.catch(e => console.error(e));
}
Get the conversation details
The current conversation details enable us to get all the cross-referenced participant details that the chat translation assistant application needs.
To get these details, we call the getConversation()
function of the Conversations API. We assign the conversation details to the global variable currentConversation
. We also get the customer name and assign it to the variable customerName
.
.then(agentName => {
agentAlias = agentName ? agentName : agentAlias;
// Get current conversation
return conversationsApi.getConversation(currentConversationId);
}).then((conv) => {
currentConversation = conv;
customerName = conv.participants.find(p => p.purpose == 'customer').name;
return setupChatChannel();
})
Set up the notification channel for chat interactions
The Genesys Cloud Notification Service enables your application to view Genesys Cloud updates on topics such as incoming chat interactions. You can manage your topic subscriptions with notification endpoints within the Genesys Cloud Platform API.
The docs/scripts/notifications-controller.js
file handles all calls to the Notification service. This controller is imported in docs/scripts/main.js
file and is consumed in the setupChatChannel()
function. The setupChatChannel()
function is called after getting the agent, customer, and conversation details.
.then((conv) => {
currentConversation = conv;
customerName = conv.participants.find(p => p.purpose == `customer`).name;
return setupChatChannel();
})
import controller from `./notifications-controller.js`;
...
function setupChatChannel(){
return controller.createChannel()
.then(data => {
// Subscribe to incoming chat conversations
return controller.addSubscription(
`v2.users.${userId}.conversations.chats`,
subscribeChatConversation(currentConversationId));
});
}
The controller.createChannel()
calls the postNotificationsChannels
function of the Notifications API to create a new channel.
Note: There is a limit of 20 channels per user/app combination. Creating a 21st channel removes the channel with oldest last used date. Channels without an active connection are removed first.
// docs/scripts/notifications-controller.js
createChannel(){
return notificationsApi.postNotificationsChannels()
.then(data => {
console.log(`---- Created Notifications Channel ----`);
console.log(data);
channel = data;
ws = new WebSocket(channel.connectUri);
ws.onmessage = onSocketMessage;
});
}
The call returns the following response body. You use connectUri
to create a WebSocket connection and id
with other API requests. We store the returned data in the channel
variable for future use.
{
"connectUri": "wss://streaming.mypurecloud.com/channels/streaming-0-fmtdmf8cdis7jh14udg5p89t6z",
"id": "streaming-0-fmtdmf8cdis7jh14udg5p89t6z",
"expires": "2020-08-12T12:41:54.707Z"
}
You can open a WebSocket connection to the notification channel by copying the connectUri
into a WebSocket tool.
Tip: You can test calls with WebSocket tools such as the Google Chrome Simple WebSocket Client.
After the channel becomes active, the WebSocket displays heartbeat messages. For more information about manual health checks, see WebSocket manual health check in the Genesys Cloud Developer Center.
{
"topicName": "channel.metadata",
"eventBody":{
"message":"WebSocket Heartbeat"
}
}
The onSocketMessage()
function is called every time the WebSocket receives a message. We can use this for notification event-handling to reference the subscriptionMap
to determine what function to run when triggered.
// docs/scripts/notifications-controller.js
function onSocketMessage(event){
let data = JSON.parse(event.data);
subscriptionMap[data.topicName](data);
}
The WebSocket can also display any topics that your channel is subscribed to. We use this feature to subscribe to get notifications for agents' active chats and and incoming chats.
After creating a notification channel, we can now subscribe to incoming chat conversation notifications by calling the controller.addSubscription()
function. The addSubscription()
function calls the postNotificationsChannelSubscriptions function of the Notifications API. To get notifications for the agent's active chats, we should subscribe to the v2.users.${userId}.conversations.chats
topic. The subscribeChatConversation()
is the callback function for notifications on this topic.
// docs/scripts/main.js
controller.addSubscription(
`v2.users.${userId}.conversations.chats`,
subscribeChatConversation(currentConversationId));
// docs/scripts/notifications-controller.js
addSubscription(topic, callback){
let body = [{`id`: topic}]
return notificationsApi.postNotificationsChannelSubscriptions(
channel.id, body)
.then((data) => {
subscriptionMap[topic] = callback;
console.log(`Added subscription to ${topic}`);
});
}
When an incoming chat interaction is answered, the v2.users.${userId}.conversations.chats
topic has a notification and subscribeChatConversation()
callback is triggered. This callback function allows us to subscribe and receive notifications for incoming chats, we again call the addSubscription()
function and use the topic v2.conversations.chats.${conversationId}.messages
. The onMessage
is the callback function for notifications on this topic.
// docs/scripts/main.js
function subscribeChatConversation(conversationId){
return controller.addSubscription(
`v2.conversations.chats.${conversationId}.messages`,
onMessage);
}
The onMessage
callback function is responsible for handling chat events. This function uses AWS to translate the chat from the customer to the agent's language. This function is also responsible for displaying the translated chat to the application's UI. This starting guide provides more details about AWS Translate in Module 5.
let onMessage = (data) => {
switch(data.metadata.type){
case `typing-indicator`:
break;
case `message`:
// Values from the event
let eventBody = data.eventBody;
let message = eventBody.body;
let senderId = eventBody.sender.id;
// Conversation values for cross reference
let participant = currentConversation.participants.find(p => p.chats[0].id == senderId);
let name = participant.name;
let purpose = participant.purpose;
// Wait for translate to finish before calling addChatMessage
translate.translateText(message, genesysCloudLanguage, function(translatedData) {
view.addChatMessage(name, translatedData.translated_text, purpose);
translationData = translatedData;
});
break;
}
};
We now have created a notification channel and subscribed to topics we need. The steps we've covered so far is a positive scenario where the application is already opened by the agent before a chat interaction comes in.
Get the chat transcript for a chat interaction
Because we are embedding this application as an Interaction Widget and Interaction Widgets are lazy loaded, we now need to cover the scenario when an agent already has an active chat interaction before opening the application.
When the setupChatChannel()
function finishes, we call the showChatTranscript()
function.
}).then((conv) => {
currentConversation = conv;
customerName = conv.participants.find(p => p.purpose == `customer`).name;
return setupChatChannel();
}).then(data => {
// Get current chat conversations
return showChatTranscript(currentConversationId);
}).then(data => {
console.log(`Finished Setup`);
})
This function makes a request to the getConversationsChatMessages endpoint of the Conversations API to retrieve the chat transcript between the agent and the customer. This function goes through every chat and calls AWS to translate each chat to the receiver's language before displaying the translated chat.
function showChatTranscript(conversationId){
return conversationsApi.getConversationsChatMessages(conversationId)
.then((data) => {
// Show each message
data.entities.forEach((msg) => {
if(msg.hasOwnProperty('body')) {
let message = msg.body;
// Determine the name by cross referencing sender id
// with the participant.chats.id from the conversation parameter
let senderId = msg.sender.id;
let name = currentConversation
.participants.find(p => p.chats[0].id == senderId)
.name;
let purpose = currentConversation
.participants.find(p => p.chats[0].id == senderId)
.purpose;
// Wait for translate to finish before calling addChatMessage
translate.translateText(message, genesysCloudLanguage, function(translatedData) {
view.addChatMessage(name, translatedData.translated_text, purpose);
translationData = translatedData;
});
}
});
});
}
Next steps
To see how the translated text is sent from the agent to the customer using the Chat Translate application, continue with Send outbound chats.
Additional resources
- Genesys Cloud Platform API Client SDK - JavaScript in the Genesys Cloud Developer Center
- Users API in the Genesys Cloud Developer Center
- Conversations API in the Genesys Cloud Developer Center
- Notification Service in the Genesys Cloud Developer Center
- Notifications API in the Genesys Cloud Developer Center
- Websocket manual health check in the Genesys Cloud Developer Center
- Interaction Widget Integration in the Genesys Cloud Resource Center