USD – CTI Generic Listener

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

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.

CTI Controls

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;

  1. Download the application from the link above.
  2. Unpack the zip file.

  3. In the USDCTICallTester directory find the project and load in Visual Studio 2012 or 2013.

  4. Now build the solution.

  5. 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;

  1. Configure CTI Desktop Manager hosted control.
  2. Test CTI events are raised in USD.
  3. Define a window navigation rule to route the CTI lookup request.
  4. 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.

Field Value
Name CTI
USD Component Type CTI Desktop Manager
Display Group HiddenPanel
Assembly URL Microsoft.Crm.UnifiedServiceDesk.GenericListener
Assembly Type Microsoft.Crm.UnifiedServiceDesk.GenericListener.DesktopManager

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

Side note:
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.

Field Description
Name CTI Window Navigation Rule
Order 50 (Can be anything really, if you have just one rule!)
From CTI

This is the name of the hosted control we created in step one.

Direction Both.

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]]

[[cti.phonenumber]]%" />

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.

Single Match

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)

Multiple matches

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.

No Matches

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.)

Side note:
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

26 thoughts on “USD – CTI Generic Listener

    • I understand your issue. I haven’t done exactly that in configuration. I agree my “simple” example has some limitations.

      When I have worked on real solutions implementing this type of code it has been covered off in a custom hosted control. Hence why I haven’t attempted this with just USD config.


  1. Pingback: USD – Window Navigation Rules Theory | Microsoft Dynamics CRM and Unified Service Desk

  2. Pingback: USD – Window Navigation Rules Theory - Microsoft Dynamics CRM Community

  3. Pingback: USD – The Book | Microsoft Dynamics CRM and Unified Service Desk

  4. Neil,

    Thanks for this (and all the other great articles on USD).

    Regarding the initiating activity field, this links to the ‘type’ field that is passed in via the querystring. This way you can have different Window navigation rules (and CTI searches) for different channels. Eg, if I’m sending a chat event through, I could search by email, if it’s a telephone event I can search by Phone. Apparently using chat here will also provide some extra functionality. Some of this is documented here:

    I can get this working for the first screen pop for a call, but how do I get it to process rules on secondary events (linked to that session)? For example, when a chat is assigned to a user, I want it to popup a contact window in a new session. If they accept that chat session, I want to popup the chat window on a new panel. Do you know how to handle the second event?


    Liked by 1 person

    • Thanks John really pleased you like my articles.

      Unfortunately I haven’t implemented Chat in USD. So I understand your challenge but I don’t have an answer. (Yet)

      I am just starting a new USD project that is going to need Chat functionality. So I hope to get time to “play” wit this VERY soon. I will of course blog about the technical details as soon as I have something operational. So please watch this space!! 🙂


  5. Neil,

    Great article. Regarding the condition of the rule it appears that only global data parameters are available and not parameters from the cti lookup object i.e [[cti.DNIS]]. Is this true ?

    I am attempting to create conditional logic for the CTI data to determine if a rule should fire or not. So far I have been unsuccessful .

    Is there a way to troubleshoot conditional logic, so far from the debugger and USD logs ti only presents where the condition was a failure or a success. ?


    • Thanks Ali

      I have seen some “limitations” on what I can do with conditions in window navigation rules. I think because of a timing “issue”.

      The condition can reference global replacement parameters or other items in the context BEFORE the navigation starts.

      BUT, say we are loading an account you can’t use any replacement parameters for the account being loaded. I think because the navigation rule is happening before the replacement parameters have been populated. (At least this is what I seem to have observed.) I think trying to reference CTI replacement parameters at this point would present the same issue.

      You can have actions on the navigation rule which use the replacement parameters BUT you need to keep in mind these will run after whatever action the rule was triggering has happened.

      This does mean you need to be creative if conditions are needed at this point. (Not easy!)

      I hope this makes sense. And believe my logic on this is correct but it has been formed just from experience of the product rather then reading anything concrete!



  6. Super cool article Neil, It has awesome information to start with CTI. About to start the Integration with the tool. Bless me 🙂

    One real quick info: the 5000 port to listen is a configurable setting. One can change the port by any chance if the port was busy in their machine. Here is the quick reference –
    (by any chance if any one else in the world are interested about this setting 😉 )

    Liked by 1 person

  7. Pingback: New Year’s Eve 2016 | Microsoft Dynamics CRM and Unified Service Desk

  8. Good morning Neil,
    do you have an example of to get the event from a real call from skype for business not from the callSimulator application ?
    thank you


  9. Hi Neil,

    Is it possible to open 1 session with 2 entities? for example if the script sends 2 keys (phonenumber =11111, marketinglistId = sampleid) but phone number is only found in contact and marketinglistid id is can only be found in marketinglist. I need to open both entities in 1 session.


    • Yes, you’d probably have an action to load the first entity. Then add sub actions to do anything else you would like. I commonly do this as I open a phone call activity, contact and related account from one navigation rules.


  10. Hi Neil,

    I have a created a hosted control (Name=CTI) of type ‘CTI Desktop Manager’ in CRM and when I tried to open USD I am getting error which say’s “The Hosted Application ‘CTI’ couldn’t be created. Please contact administrator”.

    So the rest of the part is not working I mean in simulator when I click on Send to USD I get error saying “Unable to connect to remote server”.

    Kindly need your help on this.



  11. Pingback: USD – CTI Generic Listener | Microsoft Dynamics 365 and Unified Service Desk – Danilo Capuano's CRM365 Blog

Leave a Reply

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

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

Facebook photo

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

Connecting to %s