Integrate third-party dialers with Dynamics 365 conversation intelligence (preview)

[This article is prerelease documentation and is subject to change.]

With this integration, Dynamics 365 users can use dialers provided by third-party telephony companies such as Twilio Flex, to make and receive phone calls in Dynamics 365, and get real-time AI-generated insights and rich post-call analysis of their calls. Learn more about Dynamics 365 conversation intelligence

Important

  • This is a preview feature.
  • Preview features aren’t meant for production use and might have restricted functionality. These features are subject to supplemental terms of use, and are available before an official release so that customers can get early access and provide feedback.

How the integration works

At a high-level, the integration consists of three parts:

  1. Register the provider: Register the provider details and get the users list to be recorded by using the conversation intelligence API.

  2. Fork the media: Fork the audio stream to the conversation intelligence recorders using a SIPREC protocol.

  3. Send real-time events: To enable real-time transcription and call insights experience, send UI events from the provider's client UI to Dynamics 365 conversation intelligence.

For an example integration between Dynamics 365 conversation intelligence and a third-party telephony provider, Twilio Flex, see Integrate Twilio Flex with Dynamics 365 conversation intelligence.

The following diagram illustrates how the integration works:

Diagram depicting the integration flow

Step 1: Register the provider

  1. Create a Microsoft Entra ID application.

  2. Add API permission for media recording:

    1. In the Microsoft Entra ID application that you created, go to API permissions.

    2. Select Add a permission.

    3. Under APIs my organization uses search for Media Recording for Dynamics 365 Sales and select it: Screenshot of the media recording option

    4. Add Users.Read.All permission and select Add permission

    Note

    Make sure to get the admin consent for the permission to be able to call the conversation intelligence API in app context. Learn more about permissions and consent.

  3. Get the token to run the Conversation Intelligence APIs using the app created in the previous section:

    curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token -d 'client_id=<your app id>' -d 'grant_type=client_credentials' -d 'scope=00001111-aaaa-2222-bbbb-3333cccc4444/.default' -d 'client_secret=<your app secret>'

    The scope parameter specifies the application ID of the Conversation intelligence app. Don't change this value.

    For more information about the curl command, see Get Microsoft Entra ID tokens for service principals.

  4. Call the following conversation intelligence API to register the third-party service provider:
    POST /api/v1.0/providers/tenants

    Specify the following parameters in the request body:

    • orgID: Specify the Dynamics 365 org ID.

    • Type: Specify "custom" for third-party dialers.

    • hosting: Specify the hosting type of the telephony provider. For example, "cloud" or "on-premises".

    • AccountId: Specify the account ID of the telephony provider.

    • CerfificateSubjectName and CertificateIssuer: Specify the certificate details of the telephony provider.

    • SourceIPNetwork: Specify the IP address of the SIPREC client. Specify "0.0.0.0" if you don't want to restrict the IP address.
      The following snippet is an example of the request body:

      
      {
         "orgId": "ad3dca46-962a-4895-9f85-d25f3828781f",
         "Type": "custom",
         "hosting": "cloud",
         "displayName": "Test Custom Provider",
         "AuthenticationDetails": 
         {
             "AccountId":"adxxxxx-xxxx-xxxx-xxxx-xxxxxxxx",
             "CertificateSubjectName": "certSubject",
             "CertificateIssuer": "issuer",
             "SourceIPNetwork": "0.0.0.0"
         }
      }
      

    For more information about the API, see the Swagger documentation.

  5. Call the following conversation intelligence API to get the list of users to record:
    GET /api/v1.0/providers/users

After the Dynamics 365 Sales admin creates the recording policy, the provider can use this endpoint to filter the media that will be forked to conversation intelligence recorders.

Step 2: Fork the media (SIPREC integration)

Conversation Intelligence recorders implement the standard SIPREC protocol.

The communication is secured using SIPS (port 5061) and SRTP protocols. The authentication is done using mTLS in the SIPS message connection, and is based on the certificate provided to the API – which means that the provider must be registered for a tenant to establish SIPS connection.

The following screenshot illustrates the communication between the SIPREC client and SIPREC server:

Screenshot of a sample communication between the SIPREC client and SIPREC server.

The following metadata are required for conversation intelligence:

Headers:

Header Name Description Value Example
Call-ID Unique identifier of the call. This ID is used to correlate SIP signals and user actions such as start/stop recording. efxxxxxxxxxxxxx
X-AccountId Unique identifier of the account the call belongs to. This ID is used for authentication and authorization. This is the same account ID registered in the API for the tenant. ACxxxxxxxxxxxxxxxxxxxxxxx

Metadata

Metadata key name Description Value Example
Role Indicates whether it's an inbound or outbound call for the seller. ["inbound", "outbound"]
CallerDisplayName Caller display name. If not available, phone number is displayed. Kenny Smith
CalleeDisplayName Recipient's display name. If not available, phone number is displayed. Alex Baker

Here are examples of invite and bye messages with the required headers and metadata:

INVITE message:

INVITE sip:SRS@media.recording.dynamics.com:5061;transport=tls SIP/2.0 
Via: SIP/2.0/TLS 84.172.x.x:5061;branch=z9hG4bK4fa2.cdabfe83d76d3c41987802096d3b342a.0;received=172.16.x.x;rport=40334 
Via: SIP/2.0/UDP 172.25.x.x:5060;rport=5060;branch=z9hG4bK917ce574-0345-4c3d-9b63-d98c2c57dbe6_c3356d0b_599-10236398515455707148 
To: <sip:SRS@media.recording.dynamics.com:5061;transport=tls> 
From: <sip:SRC@sip.provider.com>;tag=66790678_c3356d0b_917ce574-0345-4c3d-9b63-d98c2c57dbe6 
Call-ID: efab0870bc597cb3fb56010921e2f57f 
CSeq: 1 INVITE 
Contact: <sip:SRC@172.25.x.x:5060;transport=udp>;+sip.src 
Max-Forwards: 67 
Record-Route: <sip:84.172.x.x:5061;transport=tls;r2=on;lr>,<sip:84.172.x.x;r2=on;lr> 
User-Agent: provider Gateway 
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,NOTIFY 
Require: siprec 
Content-Length: 3194 
Content-Type: multipart/mixed;boundary=\"----=_Part_1253_283419664.1674116473425\" 
Min-SE: 35 
X-AccountId: ACxxxxxxxxxxxxxxxxxxxx 
------=_Part_1253_283419664.1674116473425 

Content-Type: application/sdp 
v=0 
o=root 1176539620 1176539620 IN IP4 172.18.x.x 
s=provider Media Gateway 
c=IN IP4 84.172.x.x 
t=0 0 
m=audio 15352 RTP/SAVP 0 8 101 
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:<Encryption_key>
a=rtpmap:0 PCMU/8000 
a=rtpmap:8 PCMA/8000 
a=rtpmap:101 telephone-event/8000 
a=fmtp:101 0-16 
a=ptime:20 
a=maxptime:20 
a=sendonly 
a=label:inbound 
m=audio 16022 RTP/SAVP 0 8 101 
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:<Encryption_key> 
a=rtpmap:0 PCMU/8000 
a=rtpmap:8 PCMA/8000 
a=rtpmap:101 telephone-event/8000 
a=fmtp:101 0-16 
a=ptime:20 
a=maxptime:20 
a=sendonly 
a=label:outbound 
------=_Part_1253_283419664.1674116473425 

Content-Type: application/rs-metadata+xml 
Content-Disposition: recording-session 
<?xml version=\"1.0\" encoding=\"UTF-8\"?> 
<recording xmlns='urn:ietf:params:xml:ns:recording:1'> 
    <datamode>complete</datamode> 
    <session session_id=\"Wd/putWgTWCW2z1lI5Db9w==\"> 
            <ExtensionParameters  xmlns=\"http://provider.com/siprec\"> 
                    <Parameter name=\"Role\" value=\"inbound\"/> 
                    <Parameter name=\"CallerDisplayName\" value=\"Kiana Anderson\"/> 
                    <Parameter name=\"CalleeDisplayName\" value=\"Tomas Richardson\"/> 
            </ExtensionParameters> 
    </session> 
        <participant participant_id=\"bXCloPcETS6P/kfeeJtiow==\"> 
            <nameID aor=\"EE5C7EF0\"/> 
        </participant> 
        <participant participant_id=\"3nPi8XzBSzWrtSLlkU8Gjw==\"> 
            <nameID aor=\"230908\"/> 
        </participant> 
        <stream stream_id=\"9xff8FcdRUaJCSTxWFbV9g==\" session_id=\"Wd/putWgTWCW2z1lI5Db9w==\"><label>inbound</label></stream> 
        <stream stream_id=\"f/Qezx4jTMqiWSB1vW7oJA==\" session_id=\"Wd/putWgTWCW2z1lI5Db9w==\"><label>outbound</label></stream> 
    <sessionrecordingassoc session_id=\"Wd/putWgTWCW2z1lI5Db9w==\"> 
        <associate-time>2023-01-19T08:21:13.382512Z</associate-time> 
    </sessionrecordingassoc> 
        <participantsessionassoc participant_id=\"bXCloPcETS6P/kfeeJtiow==\" session_id=\"Wd/putWgTWCW2z1lI5Db9w==\"> 
            <associate-time>2023-01-19T08:21:13.382512Z</associate-time> 
        </participantsessionassoc> 
        <participantsessionassoc participant_id=\"3nPi8XzBSzWrtSLlkU8Gjw==\" session_id=\"Wd/putWgTWCW2z1lI5Db9w==\"> 
            <associate-time>2023-01-19T08:21:13.382512Z</associate-time> 
        </participantsessionassoc> 
        <participantstreamassoc participant_id=\"bXCloPcETS6P/kfeeJtiow==\"> 
                <send>9xff8FcdRUaJCSTxWFbV9g==</send> 
                <recv>f/Qezx4jTMqiWSB1vW7oJA==</recv> 
        </participantstreamassoc> 
        <participantstreamassoc participant_id=\"3nPi8XzBSzWrtSLlkU8Gjw==\"> 
                <send>f/Qezx4jTMqiWSB1vW7oJA==</send> 
                <recv>9xff8FcdRUaJCSTxWFbV9g==</recv> 
        </participantstreamassoc> 
</recording> 
------=_Part_1253_283419664.1674116473425--

BYE message:

BYE sip:SRS@media.recording.dynamics.com:5061;transport=tls SIP/2.0 
Via: SIP/2.0/TLS 84.172.x.x:5061;branch=z9hG4bK1fa2.d03c36b567136fcfae84281e926cda62.0;received=172.16.x.x;rport=40334 
Via: SIP/2.0/UDP 172.25.x.x:5060;rport=5060;received=84.144.x.x;branch=z9hG4bK917ce574-0345-4c3d-9b63-d98c2c57dbe6_c3356d0b_600-2513288074170844985 
To: <sip:SRS@media.recording.dynamics.com:5061;transport=tls>;tag=OXFWHPJQTL 
From: <sip:SRC@sip.provider.com>;tag=66790678_c3356d0b_917ce574-0345-4c3d-9b63-d98c2c57dbe6 
Call-ID: efab0870bc597cb3fb56010921e2f57f 
CSeq: 2 BYE 
Max-Forwards: 68 
User-Agent: provider Gateway 
Require: siprec 
Content-Length: 901 
Content-Type: multipart/mixed;boundary=\"----=_Part_29418_1017575873.1674116842924\" 
X-AccountId: ACxxxxxxxxxxxxx 

Recorder endpoints and regions supported

The following table lists the supported recorder endpoints and their regions. You can configure the recorders you want to use in your telephony provider settings. To learn about how this is done for Twilio Flex, see Step 2: Install the SIPREC connector and route the calls to Dynamics 365.

Endpoint Region
media.recording.dynamics.com Global (closest region)
southeastasia.media.recording.dynamics.com Southeast Asia
australiaeast.media.recording.dynamics.com Australia
sam.media.recording.dynamics.com South America
canadacentral.media.recording.dynamics.com Canada
switzerlandnorth.media.recording.dynamics.com Switzerland
eastus.media.recording.dynamics.com US
francecentral.media.recording.dynamics.com France
centralindia.media.recording.dynamics.com India
japaneast.media.recording.dynamics.com Japan
uae.media.recording.dynamics.com UAE
uksouth.media.recording.dynamics.com UK
westeurope.media.recording.dynamics.com West Europe
zaf.media.recording.dynamics.com South Africa

Step 3: Send real-time events (Dialer's client Integration)

To allow conversation intelligence to provide real-time transcription and insights, the third-party dialer can use two events to notify when a call starts or ends.

  • Call started event: When conversation intelligence gets the "call started" event,it will show the recording button and the real-time transcription and insights.

  • Call ended event: When conversation intelligence gets the "call ended" event, it will wrap up the call and show the Full summary button to get the AI-generated call summary and insights.

To send the events, use the raiseEvent API in Dynamics 365 Channel Integration Framework (CIF).

Here's a sample code snippet to send the events:

export interface CallStartedEvent { 
  callId: string; 
  startTime: Date; 
  isIncomingCall: boolean; 
  contactNumber: string; 
  contactName: string; 
} 

export interface CallEndedEvent { 
  callId: string; 
  callDurationInSeconds: number; 
  callTerminationReason: string; // ['success', 'error'] 
  callEndTime: Date; 
  isCallStarted: boolean; 
} 

dialer.Actions.addListener('onCallStarted', (payload: any) => { 
  const callStartedEvent : CallStartedEvent = { 
    callId: payload.call_sid, 
    startTime: new Date(), 
    isIncomingCall: payload.attributes.is_incoming_call, 
    contactName: payload.attributes.caller_name, 
    contactNumber: payload.attributes.caller_phone_number 
  }; 

  // @ts-ignore 
  Microsoft.CIFramework.raiseEvent('WIDGET_CALL_STARTED', callStartedEvent); 
}); 

dialer.Actions.addListener('onCallEnded', (payload: any) => { 
  const callEndedEvent : CallEndedEvent = { 
    callId: payload.call_sid, 
    callEndTime: new Date(), 
    callTerminationReason: 'success', 
    isCallStarted: true, 
    callDurationInSeconds: payload.attributes.call_length 
  }; 

  // @ts-ignore 
  Microsoft.CIFramework.raiseEvent('WIDGET_CALL_ENDED', callEndedEvent); 
});

Test the integration

After registering the new provider with the tenant and setting up the SIPREC forking and the client dialer events, you can test the integration by creating a new recording policy with the new provider.

  1. Log in as a System administrator in the Sales Hub app.

  2. From Change area, select Sales insights settings.

  3. Go to Global settings > Conversation intelligence. In the Call providers section, you'll see the third-party provider that you've registered.

  4. Create a recording policy for the new provider. For more information, see Set up Microsoft Teams for conversation intelligence

The following screenshot is an example of a recording policy for Twilio.

screenshot of a recording policy for Twilio

Now, call a user who is part of the selected security role (in our example, the policy is enabled for all security roles).

When Dynamics 365 receives the callStarted event from the dialer, you'll have the option to start the recording:

Screenshot of the notification to record calls

After selecting Record, you'll be able to see the real-time transcription during the call and a full summary and call insights at the end of the call.

View and understand the call summary page