Omnichannel for Customer Service – “internal” chat

I recently had a requirement for internal users to chat with agents in the contact center. Maybe (for example) sales app users would want to speak to agents staffing the helpdesk. Dynamics 365 does include Teams integrations which may be useful for this scenario! But what-if you wanted to apply the same routing logic for these internal users as your external customers. Then it might be useful to leverage Omnichannel chat.

In this post I will explain how this requirement was tackled.

One of my requirements involved being able to link the conversations to a suitable contact. I say contact as currently Omnichannel conversations can only be linked to accounts or contacts. Linking directly to a user is not possible! But we could get round this limitation by creating a contact record for each of the internal users. However, we also wanted the correct contact to automatically be linked to the chat. (Without a pre-chat survey.)

It might have been possible to commence an authenticated chat and use that to identify the contact. That would have been “easy” if the users in question had been using a Dynamics 365 portal but they weren’t! I wanted to identify the contact directly from a model driven Power App. So, I decided that if I could pass the email address of the current Dynamics user into Omnichannel then it should be possible to find the correct contact.

As this scenario might be useful to others. And as it also serves as a useful example of how-to pas custom context values into a Omnichannel chat conversation, I thought it might be useful to document my final solution.

The steps involved are …

  1. Create a Live Chat Workstream (and routing).
  2. Add context variable(s) into the workstream.
  3. Create a web resource to populate the context variables and start the chat.
  4. Add the web resource into a Dynamics 365 model driven app.

Step One – Create a Live Chat Workstream.

First off, we needed to create a live chat workstream. This involved essentially following the same process as you normally would when creating any chat channel. So I won’t document that here!

The point here is I had a chat widget that included whatever routing I required. And also, that no pre-chat survey was being triggered.

Once my workstream was created I copied the code snippet. As that will be used later!

Step Two – Add context variable(s) into the Workstream.

Next, I manually added a context variable into my workstream.

Tip: I am adding just one context variable, but you could amend this approach and add more.

If I pass a context variable called “Email” into a workstream, Omnichannel will link any contact that matches on that email into the conversation. This is how I will automatically link my conversations to the right person. You typically achieve this by adding an “Email” field to you pre-chat survey. But I didn’t want the internal users to be forced into repeatedly entering their email address.

So, I’m deliberately not using a pre-chat survey! Instead of asking the visitor to enter their email address I want to pass it into my workstream context.

I this step I will explain how we define the context variable. We will look at how to populate it with data in a later step!

Below you can see that under the advanced settings in my workstream I have added a context variable. Importantly it is called “Email” and has a type of text.

Step Three – Create a web resource to populate the context variable and start the chat.

Next, I created a html web resource. I’ll show the code for it below. (And I will expand on its logic.) The idea here is to obtain the users email address, define a custom context value and trigger my chat widget.

My resulting web resource was added into my solution. And I change published!

Tip:
I am doing this in a web resource that will be rendered in a model driven app. But if you think about it this approach could be adapted for any custom web page as required.

In the header, I queried the email address of the current user. I also defined a custom context variable and used “window.addEventListener” to set that context when required.

I’ve shown the code I used below. But before that I will try and explain a little more about the code.

In the header section of the html, I run a script. That first uses “Xrm.Utility.getGlobalContext().userSettings.UserId” to return the GUID of the current user. I follow that with “Xrm.WebApi.online.retrieveRecord” command which is used to return the email address of the current user. So I now have the email address of the logged in user.

I then have a function called “contextProvider”. Here I define the name of my context variable, “Email”. And assign it a value. Which is the email address of the current user I just retrieved.

Next I have an “window.addEventListener” command. This is used to set the context when the chat widget becomes available. Notice I opted to comment out the line which says “Microsoft.Omnichannel.LiveChatWidget.SDK.startChat”. I did this because as didn’t want my chat to instantly start. I wanted the chat widget button saying Let’s chat to display as normal. You could of course experiment with this, as in some scenarios automatically starting the chat might be preferable.

Finally, we have the body section of my html. I added a message to my users here and pasted my chat widget script I’d copied earlier.

Note:
This was just a proof-of-concept test. So, I spent next to no time formatting the body of the html. Given time I hope you can see that we could create a more polished user interface.

<html>
<head>
<script>
  var internalemailaddress = null;
  var loggedinUserId = window.top.Xrm.Utility.getGlobalContext().userSettings.userId.replace("{","").replace("}","");
  window.top.Xrm.WebApi.online.retrieveRecord("systemuser", loggedinUserId , "?$select=internalemailaddress").then(
    function success(result) {
      internalemailaddress = result["internalemailaddress"];
    },
    function(error) {
      window.top.Xrm.Utility.alertDialog(error.message);
    });

  function contextProvider(){
    return {
      'Email': {'value' : internalemailaddress, 'isDisplayable' : true}
    };
  } 

  window.addEventListener("lcw:ready", function handleLivechatReadyEvent(){
    Microsoft.Omnichannel.LiveChatWidget.SDK.setContextProvider(contextProvider);
    // ** I commented out the startChat, you might like it!
    //Microsoft.Omnichannel.LiveChatWidget.SDK.startChat();
  });

  window.addEventListener("lcw:error", function handleLivechatErrorEvent(errorEvent){
    console.log(errorEvent);
  });

</script>
</head>

<body>
<p>Please use the "Let's Chat" button below to reach out to the next available agent!!</p>
<script 
id="Bla-bla-bla (I copied code here from my workstream!)" 
And more Bla bla bla!
></script>
</body>
</html>

Step Four – Add the web resource into a Dynamics 365 model driven app.

Finally, I added my web resource into the navigation on my model driven app.

Meaning I opened my “Sales Hub” app in the app design and simply added a subarea to the navigation. The content type of the new navigation item was “Web resource”. I then selected the web resource I’d already created and gave it a title.

After publishing my updated app I was ready to test!

Testing

Below you can see the experience when I tested my application. I opted to add my web resource into my sales hub. But you could do this with any model driven app.

My users now have an option called “Chat with an agent”. Clicking this opens the page below. Hopefully you can see that I could have enhanced the user interface significantly. My simple “Please use the Let’s Chat” message is functional but very basic!

Clicking “Let’s chat” will open a chat widget and begin a conversation with my Omnichannel agents. As we’d expect.

Tip: I am showing this operating from my desktop. I also tried the experience by loading the app in Power Apps on my mobile phone. That worked well and might (for example) make a nice addition to the Field Service mobile app.

When the agent gets an incoming chat they are able to see the name of the person call in the chat notification. This signified that the users email address must have resulted in a match to my contact record.

And as you can see below, my conversation has been correctly linked. Granted I had to create a contact for each user, which wasn’t ideal. But as we can’t link incoming chats to system user records this was a reasonable compromise.

Notice that I can view “Additional Details” in the conversation details section of the form. This is where we’d see any of the context values passed. (I just included the one context value of “Email” but I could have queried and passed other data as required.)

Hopefully you can see that this isn’t a standard use of Omnichannel chat functionality but I also hope you can see that it demonstrates a concept that might be “quite useful”. And even if you won’t want to chat with internal users you may also find the logic used to pass custom context values useful. Enjoy.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s