I have posted the video of incoming call using CIF here. It is a live working demo using Twilio trial account. I am going to share my experience of making this so anyone can easily setup the basic features and start exploring more awesomeness.
I have tested the public preview of Microsoft Dynamics 365 Channel Integration Framework. It was before Christmas and New Years holidays. Moving house over the holiday period kept me occupied for weeks.
Last week, I started to look into CIF again. During the public preview, I had issues with incoming and outgoing calls. I was able to connect to Twilio service. Outgoing/incoming calls that return pre-defined messages were successful. However, I couldn’t manage to figure it out to make a call to a real number.
In this post, I am going to cover D365 users responding to incoming calls directly from web interface – without leaving D365 at all.
Before we start, please go through followings
- Overview of CIF https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/channel-integration-framework/overview-channel-integration-framework
- Get CIF solution https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/channel-integration-framework/get-channel-integration-framework
- Sample code and configuration guide at https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/channel-integration-framework/sample-softphone-integration
- Create Twilio free trial account together with trial number
- Twilio documentation https://www.twilio.com/docs/voice/client/tutorials/how-to-set-up-a-server-for-twilio-client
- Visual Studio 2017 with ASP.NET Core 2.1
Now, we can begin!
You will find steps provided in Microsoft documentations are easy to follow. But I find problems with the section to create Twilio functions (https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/channel-integration-framework/sample-softphone-integration#create-function-to-use-with-the-app-service).
According to Readme included in the sample code, you have to create functions in Twilio. I followed the instructions and couldn’t manage to make it work. So, I started with creating a basic client and later add a couple of controllers to the sample code to setup a twilio client.
You can follow tutorials from https://www.twilio.com/docs/voice/client/tutorials/how-to-set-up-a-server-for-twilio-client to create a basic client including TokenController and VoiceController. Creating own controllers give us the whole capability of Web, flexibility and fine grain control of call processes, such as limiting the functionality, dynamic routing which could be stored somewhere else.
In Twilio console, it is very easy to get confused and lost in navigation. However, we can get the information we need from
– Twilio account dashboard at https://www.twilio.com/console
– TwiML apps at https://www.twilio.com/console/voice/twiml/apps
– Phone numbers at https://www.twilio.com/console/phone-numbers/incoming
In short, you need to
- generate Token using Twilio Account SID, Auth Token and SID of TwiML app (TokenController.cs and VoiceController.cs can be found at https://github.com/dynamicscode/ChannelIntegrationFramework_Sample/tree/master/TwilioSampleInteg)
Once you have deployed the sample code, you need to configure your trial Twilio Phone Number. First, let’s create a TwiML to route and store it in TwiML Bin. You can find TwiML bin under Runtime or at https://www.twilio.com/console/runtime/twiml-bins/. For testing purpose, let’s create following TwiML.
You may ask “What the heck ‘ak’ is sitting between Client tag?” Well, it directly relates to the client name of token generated from TokenController.cs
Once TwiML is saved, go to your phone number and configure its A CALL COMES IN setting by choosing TwiML and choosing the newly created TwiML from Bins.
That’s all you need to configure to receive and answer the call using CIF. It takes a while to get it right. Reading Twilio documentations will help you a lot.
You would notice that I use a static TwiML to route to the client in Phone Number configuration. In real world, I think Webhook is a better approach where you can return TwiML dynamically according to implementation of business rules. In addition, TokenController.cs could do similar thing which generates dynamic token for each login user. That way, the call could be routed to the correct client.
Reach out to me if you need any help and it is confusing.