Integration with IP telephony

The system includes out-of-the-box integrations with various IP telephony providers. If you cannot find the integration you need, you can use this API to create your own integration. To do this, you need to create a custom module and implement several functions in the module's scripts using TypeScript. Built-in and custom IP telephony integration modules are functionally equivalent. Your module will have the following capabilities:

  • Initiate an outgoing call from the system via the context menu of a Phone field;
  • Display a call page with brief client information and call control buttons, when a system user answers an incoming or makes an outgoing call;
  • Open a summary page for the client;
  • Automatically create and save an app item if the call was missed and the number is not in the database;
  • Register missed calls;
  • Save a message about an incoming or outgoing call to the object's activity stream. If the conversation took place, a link to the call recording is added to the message. It can be played back in the system interface, and you can also leave a comment, for example, containing a call summary;
  • Automatically create a Call app item in the Telephony workspace for each incoming and outgoing call;
  • Map telephony provider user accounts to system users for routing and
    correctly displaying the operator who received or made the call.

    Limitations

    Before implementing the integration module, please note the following API limitations:
  1. The system does not perform call routing to avoid conflicts with routing settings on the telephony provider side and on the system side. Almost every provider offers this capability: after the call is routed to an employee or group, the incoming call is displayed in the system for the selected users.
  2. Currently, telephony events are handled by sending messages to a specified HTTP link (Webhook). If your telephony provider does not allow specifying a URL to deliver messages, you need to set up an intermediate service that converts the provider's data into a system server request. To do this, you can create a [portable service in a module] (https://brix365.com/en/help/platform/portable-microservices.html).
  3. Only the link to the call recording file is stored. Usually, the recordings themselves are stored by the telephony provider. Only the link is provided. You should pay attention to the provider's file retention policy on the
    telephony provider's servers. Files may be available for a limited time.

    Implementation

    To create an integration module, you need to implement the following functions in your custom module scripts:
    // Test  the connection to telephony. Called when you click the Test Connection  button on the module page 
    // Returns the connection test status, which will  be displayed to the user on the module page 
    async function  VoipTestConnection(): Promise<VoipTestConnectionResult> { } 
    // Handle a  request from the IP telephony provider. Called when a webhook request to the  module is received 
    // The `request` parameter contains information about  the HTTP request, including headers and body 
    // The function returns the  request processing result, which is used by the system to show notifications  
    // for incoming calls, save call recordings, and so on. 
    async function  VoipParseWebhookRequest(request: FetchRequest):  Promise<VoipWebhookParseResult> { } 
    // Get a list of users from the IP  telephony provider 
    // Called when mapping telephony users to system users  after clicking the Configure button on the module page 
    // Returns a list of  the telephony provider's users 
    async function VoipGetMembers():  Promise<VoipMember[]> { } 
    // Generate an outgoing call. Called when a  system user clicks the call button 
    // in the context menu of a Phone field  or the Call back button on a call page. In the 
    // `srcPhone` parameter,  specify the caller's number; in `dstPhone`, specify the number to call; 
    //  `ext` is the extension number. We recommend configuring your PBX or SIP  softphone so that the extension 
    // is automatically dialed using DTMF after  the other party answers. 
    async function VoipGenerateCall (srcPhone: string, dstPhone: string, ext?: string): Promise<void> { } 
    //  Get a link to the call recording. Called when a system user plays a call  recording from 
    // the app item's activity stream or when saving the call  recording link to the context of a Call app item 
    // in the Telephony  workspace. The `callData` parameter contains the data provided when saving  
    // the call recording info from the `VoipParseWebhookRequest` function.  Must return a file link 
    async function VoipGetCallLink(callData: any):  Promise<string> { } 
    // Called automatically when the webhook link changes  (for example, when the token is updated) 
    // The `webhookUrl` parameter  specifies the absolute URL of the integration module's webhook.  Implementation optional 
    async function VoipOnWebhookUpdated (webhookUrl: string): Promise<void> { } 
    
    After implementing these functions and saving the script on the module page, you will find a new workspace called

Telephony Settings. This workspace will display the webhook link — when data is sent to this link, the VoipParseWebhookRequest function in your script will be called. In this function, you must handle the request and return a VoipWebhookParseResult instance, which the system will use to display incoming call notifications or save call recording information. You must set the webhook link in your telephony provider's settings. The link handles both GET and POST HTTP requests. Also, the link must include a required token parameter.

Implementing Call Page Button Support

When a system user receives an incoming or makes an outgoing call, a [page with current call information] (https://brix365.com/en/help/crm/work-with-call.html) appears in the bottom right corner. Depending on the call status, this page may show various buttons: Accept Call, End Call, Redirect, and so on. To display these buttons, implement the following functions in your custom telephony module:

// Accept a call. Called when a system user clicks  Accept Call in the call page 
// After this, voice data begins to be  transmitted between the operator and the client 
// The `srcPhone` parameter  specifies the caller's number; `dstPhone` is the destination number 
async  function VoipAcceptCall(srcPhone: string, dstPhone: string): Promise<void> {  } 
// End a call. Called when a system user clicks End Call in the call page  
// The call between the operator and client is terminated 
// The `srcPhone`  parameter specifies the caller's number; `dstPhone` is the destination  number 
async function VoipHangupCall(srcPhone: string, dstPhone: string):  Promise<void> { } 
// Redirect a call. Called when a system user clicks  Redirect in the call page 
// The current operator's call ends, and the  client connects to another operator 
// The `srcPhone` parameter specifies  the caller's number; `dstPhone` is the destination number; 
// `redirectTo`  is the internal number of the operator to whom the call is redirected 
async  function VoipRedirectCall (srcPhone: string, dstPhone: string, redirectTo: string): Promise<void> { }  
// Place a call on hold. Called when a system user clicks Hold in the call  page 
// Voice data transfer between the operator and client stops without  ending the call 
// The `srcPhone` parameter specifies the caller's number;  `dstPhone` is the destination number; 
// `hold` set to `true` means put on  hold, otherwise — remove from hold 
async function VoipHoldCall (srcPhone: string, dstPhone: string, hold: boolean): Promise<void> { } 

If a function is not implemented in your custom telephony module, the corresponding button will not be displayed in the call page.