Unified Service Desk for Microsoft Dynamics CRM includes the ability to integrate with phone systems via CTI. In this post I will try to explain some of the basic concepts behind CTI and how to configure the generic listener. Hopefully a good starting point for anyone wanting to conduct a project making use of CTI. Beyond that point you may want to consider building your own bespoke listener but let’s start “simple”.
I guess I should kick this post off with answering the elephant in the room, what is CTI and what will it do for me? CTI stands for Computer Telephony Integration, a standard that allows integration between IP/ VOIP phone systems and applications running on the desktop. CISCO phone systems, for example will “publish” CTI events on a standard port (typically port 5000). CTI integration will listen for those events and automate the behaviour of the desktop application based upon them. For example: It might detect the phone number of the caller, search for their record using this number and pop the agent directly into that screen.
My description here will be making reference to the Microsoft supplied generic CTI listener. The walkthrough this post is based upon can be found here. I will follow the walkthrough but will add additional detail and information that hopefully you will find useful.
The Science Bit
I always think it is important to understand at least the basic concepts behind something before attempting to use the technology, I will give an explanation on how to configure Microsoft’s generic listener but before that a little science! (Don’t panic, this will be fairly high level concepts.)
UII standards for User Interface Integration, it provides a development framework for the creation of unified agent desktops. Unified Service Desk (USD) is built on the UII framework. In UII, all communications over a particular channel, whether chat, email, telephone, or others, occur directly from the organization’s CTI system to the UII desktop (such as Unified Service Desk). The diagram below shows this concept; you can see that the green line from the CTI server talks directly to the desktop. The desktop in turn interacts with the Microsoft Dynamics CRM server.
The CTI application framework provided by UII has three components, shown in red below. (CTI Connector, CTI Desktop Manager, and CTI controls)
CTI Connector provides the logic to connect to and communicate with the external CTI system. CTI Connector layer exposes the methods and events that will be called and listened to by the CTI Desktop Manager component. CTI Connector supports either a polling or instance-based connection model.
CTI Desktop Manager
CTI Desktop Manager provides the business logic for your CTI adapter. It responds to a call when it arrives in the UII desktop (such as Unified Service Desk), and performs the necessary steps to connect to the CTI Connector. CTI Desktop Manager is implemented as a hosted control that communicates between the UII desktop and the CTI system to raise events and route calls appropriately in the UII desktop. It might be worth understanding that this is a two-way communication, the listener will pick up CTI events and the application can then be made to respond accordingly. But this concept could be extended to feedback information, such as the availability of the agent etc. In this simple example we will just be reacting to a CTI event.
These are the user interface (UI) controls in a UII desktop that allow agents to interact with the CTI system (manage calls) and manage the agent status.
- Agent state management control: Displays the current state of the agent within a User Interface Integration (UII) desktop (such as Unified Service Desk. This control doesn’t need to be tied to the CTI system, but it allows you to map CTI agent states with the current agent state, which is the visual state of the agent desktop.
- Call control: Provides buttons that the agent can use to make a call, answer a call, put a call on hold, transfer a call to another agent, or hang up.
Create Testing Application
So, let’s move onto an example of making CTI work. The first thing you are going to need to do a create a test application that will simulate CTI events. This will then support your development of your interface within Unified Service Desk.
There is a prerequisite here, you are going to need Visual Studio 2012 or Visual Studio 2013 to build the test application.
Download the sample CTI Simulator Application Visual Studio project to your computer. Build the project, and run the application (.exe file) from the bin\debug folder of the sample application project. You must run the USD CTI Simulator application on the same computer where Unified Service Desk client is running to test the application. To do this;
Download the application from the link above.
Unpack the zip file.
In the USDCTICallTester directory find the project and load in Visual Studio 2012 or 2013.
Now build the solution.
Having built the application, in the bin/debug folder you will have an application call “USDCTICallTester”, you will be able to use this to simulate CTI events to test you USD application.
Configure Unified Service Desk
Now you have the application to simulate CTI events we can look at how to configure USD. The steps that are going to be involved are;
- Configure CTI Desktop Manager hosted control.
- Test CTI events are raised in USD.
- Define a window navigation rule to route the CTI lookup request.
- Test the adapter.
I am going to be using USD 2.0 and CRM 2016. But the same approach should work on earlier versions of Unified Service Desk and Microsoft Dynamics CRM.
As I mentioned in my introduction I will largely follow the Microsoft walkthrough here but I may add some detail / comments along the way. I won’t quite be following it parrot fashion!
Step One – Configure CTI Desktop Manager hosted control.
Guess what, step one (as almost always) with a USD configuration is to create a hosted control. This time it is going to be one of a “special” USD component type called, CTI Desktop Manager.
|USD Component Type||CTI Desktop Manager|
My hosted control then looked like this …..
Step Two – Test CTI events are raised in USD.
In this next step, I am going to make an assumption that you have already set-up the debugger in Unified Service Desk. Which I believe is reasonable as if you’ve gotten this far with USD I can be pretyy sure you’ve had to do quite a bit of debugging!! J
So load your USD instance and enter the debugger. Plus clear out any action calls by using the X.
Now you are going to use the CTI simulator application to generate a CTI event. Run the application you build and enter a key of “Phonenumber” or “Email” or anything! And enter a value.
The url, will be sending this event to port 5000. (5000 being the default port for CTI events from any CTI compliant phone system.)
Now click “Send To USD”.
Assuming everything is set-up correctly you should see something like the results below. If you do, relax, from here on in this is going to be plain sailing. Hopefully! J
It is worth thinking about this for a second. As when you move beyond testing with a simulator you are going to need to review and interpret the messages from your actual phone system. I haven’t done extensive testing but I think it’s safe to assume that the exact content of the messages will vary from system to system. So you’ll need to look for the name and format of field returned. Microsoft’s walkthrough example actually uses “Email” address not phone number. I have a suspicion this is for two reasons. Firstly; I think they want to show the multi-channel nature of CTI events. But mainly I think it could be because of phone number formats. You are going to need to look at how the phone number is returned by your actual phone system and compare this to how your phone numbers have been entered in your CRM organization. When we search for people you can imagine based on the format returned that search logic might need to be creative. But let’s keep things simple for now. After all this is just an example! J
Step Three – Define a window navigation rule to route the CTI lookup request
Next we’ll create a window navigation rule to react to the CTI event you have just seen generated. The first thing you need to do is generate some fetch XML that will be used for your search. You could just write this from scratch or use advanced find to make you task simpler.
So create yourself an advanced find that looks something like this. Basically you are looking for all contacts that have a match on a phone number. Obviously contact has quite a few phone number fields some of which you might not be using, so adjust this query to match your situation. Once you have done this use the “Download Fetch XML” button to save a copy of the fetch XML.
Now you need to create a Window navigation rule in Unified Service Desk. Mine looked like the one below.
|Name||CTI Window Navigation Rule|
|Order||50 (Can be anything really, if you have just one rule!)|
This is the name of the hosted control we created in step one.
Other options are incoming and outgoing. You can see that you might want to define different rules with different actions depending on the direction of the call.
Note: Initiating activity, I couldn’t find any documentation on this field in Microsoft’s USD documentation. But it is a link to an entity schema name. I suspect this relates to outgoing calls that you could have different rules depending on the entity that you are calling from. But I haven’t been able to prove / test this. When (or if) I do I will update this post.
Once you have save this rule you can add the search (or searches) you want to apply. Here you are going to use the fetch xml we produced earlier. Except you are going to edit it slightly to look at the details returned in the CTI event. My xml looked like the example below. You can see that I have inserted a replacement parameter in place of the phone number from my advanced find. [[cti.phonenumber]]
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"> <entity name="contact"> <attribute name="fullname" /> <attribute name="telephone1" /> <attribute name="contactid" /> <order attribute="fullname" descending="false" /> <filter type="and"> <filter type="or"> <condition attribute="telephone3" operator="like" value="%[[cti.phonenumber]]%" /> <condition attribute="mobilephone" operator="like" value="%[[cti.phonenumber]]%" /> <condition attribute="telephone1" operator="like" value="%[[cti.phonenumber]]%" /> <condition attribute="business2" operator="like" value="%[[cti.phonenumber]]%" /> <condition attribute="address1_telephone1" operator="like" value="%[[cti.phonenumber]]%" /> <condition attribute="telephone2" operator="like" value="%[[cti.phonenumber]]%" /> </filter> </filter> </entity> </fetch>
My search ended up looking like this ….
With the detail of my search looking like this …..
Notice that there is a direction field which I have left blank, as this search applies to both directions. You can however create a different search for inbound and outbound. Also I have given my search an order value of “1”. It is possible to have multiple searches, in which case the order would become significant. But I my simple example I only have one search so the order could be anything.
OK, all good so far? A quick recap, we have created a hosted control, then created a window navigation rule for when an event is triggered on the control. We have now added a search which will be run when the event happens. So now we need to decide what action(s) will happen depending on the results of the search.
In the window navigation rule you can define what happens if you find no matches, a single match or multiple matches.
Let’s consider a single match first. If I search for a contact and find one match to the person called then I want to create a session for that contact, load the contact and show the tab for the contact. Sounds complicated but this is actually quite simple. (See below)
Now if I have potential several matches to the incoming call I have decided to pop the user into a search screen. From there they can qualify who the contact is and progress accordingly.
Here I have simply said “Next Rule”, you can have multiple window navigation rules for CTI events which will be run in order. So next rule would trigger the next in sequence. I’ve just shown this as a design idea as I’m not going to cover all the possible combinations in this post. But if this rule that searches for contacts returned no results I might want to trigger a second rule that looks at accounts. And then maybe a third to look for leads etc. Hopefully you can see that you could get quite creative / complex with these rules.
Finally, I define what will happen following these actions. In my example I am searching for contacts so ultimately I want to show y contact tab. Hence my results looked like the example below.
Step Four – Test the adapter
Finally let’s test the application, so load you unified service desk application and load the CTI simulator test application.
I have already set-up one contact with the mobile number “07767207939”. So I now load simulator and enter the details below.
Clicking send to USD automatically triggers my contact to be loaded and the session started. (In my example the account related to this contact also loaded in the session, as I have already built that logic into the load of my contact tab!)
Hopefully this post has given you an introduction into CTI and it’s use with USD.
As you can see you’ll need to extend the capabilities beyond this concept to be tailored for your specific situation. Including searching multiple entities and making allowances for the specific phone system you’re working with. But I hope you can see how those things will be possible, with a little effort. Good luck. (I’d be interested to hear anyone’s experience of implementing this in real world situations.)
One disappointment I have is that the generic listener supplied by Microsoft doesn’t work with Skype based phone systems. This seems a real shame as I’m committed to using as much of the Microsoft stack as possible. But I have heard an unconfirmed rumor that Microsoft may (one day) release a listener capable of working with Skype. I will of course create a post about that if it becomes available. J