Solving the Multi-Number Calling Challenge in Dynamics 365 with a Custom Twilio Dialer
Introduction – The Client Challenge
While Dynamics 365 Sales provides native calling capabilities and supports Microsoft Teams calling, it assumes a single outgoing number per user, and only supports Teams-based telephony not Twilio or other programmable voice providers. Additionally, it does not support dynamic number routing based on Model-Driven App or Business Unit context.
Our client operates across multiple Business Units and Model-Driven Apps, each requiring calls to originate from a different Twilio number.
This created several limitations:
Calls were being logged against incorrect Business Units
Users had to manage numbers manually outside CRM
No support for multi-number routing in a single CRM instance
Teams’ integration does not support routing by app context
Why We Used Twilio and a Custom Dialer
To solve these gaps, we needed a solution that would:
Route calls dynamically based on the current App or Business Unit
Assign dedicated Twilio numbers per client / business unit
Embed a seamless dialer experience inside Dynamics 365
Handle both outgoing and incoming calls
Ensure secure, app-bound call sessions
Twilio was the ideal platform because it:
Allows provisioning of dedicated phone numbers
Enables programmable call logic via TwiML Functions
Supports secure token-based authentication
Integrates well via HTML, JavaScript, C#, and Dataverse APIs
Our Solution
We built a Custom Twilio Dialer embedded in Dynamics 365 using:
Web Resources (HTML/JavaScript/CSS)
C# Custom Actions for backend processing
Twilio Programmable Voice SDK
TwiML Functions for secure call routing
Token-based authentication (JWT)
Two Dataverse Configuration Tables
This allows us to support multi-client telephony within a single CRM system while delivering a seamless and secure user experience.
Project Overview
Our custom dialer supports:
Multiple Twilio phone numbers
Dynamic number selection based on Business Unit or App
Embedded custom UI with “Call From” and “Call To” fields
Real-time Twilio call handling
Automatic Phone Call Activity logging
Incoming call support with routing to correct App
Key Components
Custom Dialer UI & Workflow
1. Token-Based Authentication (Required)
This integration requires a JWT token for secure communication with Twilio. We generate a short-lived JWT token for each session using a secure server-side C# plugin and a Dataverse Custom Action.
Token Generation Flow:
User opens a record or clicks a call icon
JavaScript calls a Custom Action with App SID and number
Plugin generates a JWT with VoiceGrant
Token is returned and used to initialize Twilio.Device
C# Custom Action code
2. Initializing the Twilio Device
Include the required SDK in your HTML Web Resource:
Html [Twilio SDK]
Javascript inside HTML to initiate Twilio Device
3. Making Outgoing Calls
Calls can be initiated from:
The custom dialer UI
Clicking a custom phone icon next to number fields on any CRM form
Javascript
Call Routing with TwiML Functions
TwiML Functions are a core part of our custom calling logic. These are serverless functions hosted by Twilio, written in JavaScript, that define how to handle incoming or outgoing calls using Twilio Markup Language (TwiML).
We configure and use two types of TwiML Functions per client:
Outgoing Call Function
Our custom dialer does not dial phone numbers directly. Instead, it invokes a TwiML Function, which:
Accepts the destination number as input
Builds a dynamic TwiML response that either: Dials an external phone number, or Connects to a Twilio Client (CRM browser user)
This TwiML Function's public URL is attached to a TwiML Application, which we create and manage in Twilio.
We configure the TwiML Function URL in the associated TwiML Application.
When generating the JWT token for secure communication via the Twilio Client SDK, we pass the TwiML App SID to bind that token to the correct app and routing logic.
This approach ensures:
Centralized and secure routing for all outbound calls
Proper enforcement of app-specific call behavior
Seamless integration between JWT auth and TwiML execution
TwiML Function for Outgoing Call
4. Handling Incoming Calls
Each Twilio number is configured to point to a TwiML Function responsible for managing incoming call routing. When a call is received, Twilio invokes the Function URL, defined in the Voice settings of the Twilio phone number.
This function executes a set of TwiML instructions to:
Greet the caller
Forward the call to a specific Twilio Client (browser-based CRM user)
TwiML Function for Incoming Call
The Function URL is set as the Voice Webhook on the Twilio number's configuration.
The call is routed based on the client identity (clientId) specified in the dial.client() method. This identity must match the one used in the JWT token previously generated and used to initialize the Twilio Client SDK on the browser.
The incoming call reaches the correct authenticated CRM user within the right Model-Driven App.
Client-Side Behavior
On the client side, the Twilio Client SDK listens for incoming call events. When a call is detected:
The custom dialer UI automatically switches to the Incoming Call UI
The caller’s number is displayed
The user is prompted to accept or reject the call
Javascript
Additional Features
Auto-reject if the user is already on a call
30-second timeout if unanswered
UI dynamically updates based on call status
This end-to-end handling ensures a seamless and secure incoming call experience within Dynamics 365, fully embedded in the browser.
Call Logging in Dynamics 365
A Phone Call Activity is created automatically when a call ends, capturing:
From (calling user)
To (Lead/client engagement)
Duration & status
Regarding (linked record)
Usage Scenario
We did not embed the dialer on a form.
Instead:
We built a custom HTML Web Resource
Added custom phone icons on phone fields in forms like Lead or client engagement
When the user clicks the icon: The Twilio token is generated The dialer opens in the side pane The call is automatically initiated
This works on any entity form — Lead, Contact, Opportunity, etc.
No navigation or switching required.
Error Handling
Validates phone numbers
Catches token/auth errors
Shows user-friendly messages (no raw errors)
Benefits Delivered
Seamless, embedded calling in CRM
Supports dynamic, per-App or per-BU number routing
Secure with short-lived JWT tokens
Real-time incoming and outgoing call management
Automatic logging and auditing
Centralized, maintainable TwiML call logic
Conclusion
By designing a flexible, secure, and scalable Twilio-based custom dialer, we solved the multi-number, multi-business unit challenge inside Dynamics 365 CRM. The result is a powerful, seamless telephony solution tailored for multi-tenant CRM environments improving efficiency, call tracking, and user experience.