XML Descriptions for Integration Template
When you build a custom CRM or Helpdesk integration for Cloud Voice, you describe it in an XML template. The template declares the connection details the phone system needs, API endpoints, data fields, authentication, and the functional scenarios that drive each integration feature. This page documents every element, attribute, and variable you can use in that template.
Template conventions
Section titled “Template conventions”Templates conform to the XML 1.1 specification. The sections below explain the variable, function, and element syntax you will work with throughout a template.
Variables
Section titled “Variables”A template can reference variables so that data is resolved dynamically. Each variable is replaced with its actual value when Cloud Voice runs the template.
Variable values come from three places:
-
Predefined variables supplied by Cloud Voice.
-
Parameter values a user enters while configuring the integration.
-
Values extracted from an API response. You pull a value out of the response body with a JSON path, for example:
<Output Name="UserUniqueId" Path="data.#.id"></Output>To pull the first value that meets a condition:
<Output Name="BusinessNumber2" Path="identities.#(type=="phone_number")#|1.value"></Output>
Variables are referenced using Go’s text/template syntax:
| Form | Example |
|---|---|
| Standard variable | {{.varname}} |
| Conditional variable | {{ if .varname }} Welcome, member! {{ else }} Please sign up. {{ end }} |
| Function call on a variable | {{ Capitalize .varname }} |
Functions
Section titled “Functions”Functions transform or format a variable’s value inline. The following functions are available.
| Function | Purpose and example |
|---|---|
TimeFormat | Formats a timestamp. Format: {{ TimeFormat Timestamp_variable "format_string" "convert_to_UTC" }}Example: {{ TimeFormat .StartTimeUnix "yyyy-MM-ddTHH:mm:ss.000Zz" "1" }}. If .StartTimeUnix is 1672531199, the result is 2023-01-01T00:59:59.000Z. |
ToMillis | Converts a seconds timestamp to milliseconds. Format: {{ ToMillis Timestamp_variable }}Example: {{ ToMillis .StartTimeUnix }}. If .StartTimeUnix is 1672531199, the result is 1672531199000. |
Capitalize | Capitalizes the first letter of a string. Format: {{ Capitalize variable_string }}Example: if the value is hello world, the result is Hello world. |
UrlEncode | URL-encodes a string (replaces spaces and other reserved characters with percent-escapes so the value is safe inside a URL). Format: {{ UrlEncode .variable }}Example: if the value is hello world!, the result is hello%20world%21. |
ToMinutes | Converts an hh:mm:ss duration to a total number of minutes.Format: {{ ToMinutes duration_variable }}Example: {{ ToMinutes .ChatDuration }} (used in the Chat journal scenario). |
TsSecToMilliSec | Converts a seconds timestamp to a milliseconds timestamp (same result as ToMillis).Format: {{ TsSecToMilliSec Timestamp_variable }}Example: {{ TsSecToMilliSec .EndTimeUnix }} (used in the Chat journal scenario). |
Elements
Section titled “Elements”These are the main building blocks of a template. Together they define how Cloud Voice connects to the third-party system and processes the data each feature needs.
The overall structure looks like this:
<Information> <Scenarios> <Scenario Id="1" Type="REST"> <Parameters> <Parameter Name="example" Value="example"></Parameter> ... </Parameters> <Requests> <Request Name="ExampleRequest" Method="GET" URL="https://api.example.com/getuser"> <Outputs> <Output Name="ContactId" Path="data.#.id" Type="string"></Output> ... </Outputs> </Request> </Requests> </Scenario> </Scenarios></Information>| Element | Description |
|---|---|
<Information> | The root element. Its attributes carry the template’s basic information and configuration overview (see Template property), and it holds the <Scenarios> child that defines each integration capability. |
<Scenarios> | A collection of <Scenario> elements. Each scenario holds children such as <Parameters>, <Requests>, and <Outputs> that describe one functional capability. Cloud Voice loads the configured scenarios and runs the HTTP requests or operations they define. Supported scenarios: Authentication, User association, Automatic contact synchronization, Automatic contact creation, Automatic ticket creation (Helpdesk only), Call journal, and Chat journal. |
<Parameters> | A collection of parameters tied to a scenario or request, dynamic values or configuration settings needed to run it. Depending on the case, they are passed in the request URL, body, or headers. |
<Requests> | A collection of requests a scenario issues to implement its feature. |
<Outputs> | A list of <Output> elements that define which fields to extract from the API response. |
Template property
Section titled “Template property”The <Information> element’s attributes describe the template as a whole.
| Attribute | Description |
|---|---|
Provider | Template type. Fixed as crm or helpdesk. |
Name | Template name. |
Key | Unique identifier for the template. |
Logo | Filename of the logo. |
Remark | A description or note about the template. |
Version | Template version, for example 1.0.0. |
AuthType | Authentication method: none, basic, oauth2, or bearertoken. |
MaxConcurrentRequest | Maximum number of concurrent HTTP requests allowed to the CRM/Helpdesk. |
UserAssociation | Whether user association is enabled. 0 disabled, 1 enabled. |
CallJournal | Whether call journaling is enabled. 0 disabled, 1 enabled. |
CreateNewContact | Whether automatic contact creation is enabled. 0 disabled, 1 enabled. |
CreateNewTicket | Whether automatic ticket creation is enabled. 0 disabled, 1 enabled. |
ChatJournal | Whether chat journaling is enabled. 0 disabled, 1 enabled. |
Authentication scenario
Section titled “Authentication scenario”This scenario defines how Cloud Voice authenticates to the CRM/Helpdesk.
<Scenario Id="AuthMethod" Type="AUTH"> <Presets></Presets> <Parameters> <Parameter Name="AuthMethod" Value="oauth2"></Parameter> <Parameter Name="AuthEndPoint" Value="https://api.example.com/oauth/v2/auth?client_id={{.client_id}}"></Parameter> <Parameter Name="TokenEndPoint" Value="https://api.example.com/oauth/v2/token?client_id={{.client_id}}&client_secret={{.client_secret}}"></Parameter> <Parameter Name="ContentType" Value="application/json"></Parameter> <Parameter Name="AdditionalQueryString"></Parameter> <Parameter Name="Scope" Value="contacts.read,contacts.write,calls.read,calls.write,user.read,user.write"></Parameter> <Parameter Name="CredentialType"></Parameter> <Parameter Name="Base64EncodedCredential"></Parameter> <Parameter Name="TokenRefreshInterval" Value="25"></Parameter> <Parameter Name="TokenRefreshBody" Value="grant_type=refresh_token&refresh_token={{.refresh_token}}"></Parameter> <Parameter Name="TokenRefreshEndpointMethod" Value="post"></Parameter> <Parameter Name="TokenRefreshEndpoint" Value="https://api.example.com/oauth2/token"></Parameter> <Parameter Name="TokenRefreshContentType" Value="application/x-www-form-urlencoded"></Parameter> <Parameter Father="CustomFieldList" Name="client_id" Editor="password" Title="Client ID" Value="" IsDelete="0" IsRequired="1"></Parameter> <Parameter Father="CustomFieldList" Name="client_secret" Editor="password" Title="Client Secret" Value="" IsDelete="0" IsRequired="1"></Parameter> <Parameter Father="CustomFieldList" Name="application_id" Editor="string" Title="Application ID" Value="" IsDelete="0" IsRequired="1"></Parameter> <Parameter Father="CustomFieldList" Name="server_address" Editor="string" Title="Server Address" Value="" IsDelete="0" IsRequired="1"></Parameter> <Parameter Father="PopulateTemplateString" Name="Content-Type" Type="Header" Value="application/json" Description="The format of the request body"/> <Parameter Father="PopulateTemplateString" Name="Accept" Type="Header" Value="application/json" Description="The expected response data format from the server"/> <Parameter Father="PopulateTemplateString" Name="X-CSRF-Token" Type="Header" Value="f3e1a2b4c5d6e7f8g9h0" Description="Prevent Cross-Site Request Forgery (CSRF) attacks"/> <Parameter Father="PopulateTemplateString" Name="X-Client-Id" Type="Header" Value="{{.client_id}}" Description="for client identification"/> <Parameter Father="FollowUpList" Name="ffb425cb-565d-49cd-92be-3290d0ab5129" Type="FollowUpRequest" Value="" IsDelete="0"> <Parameter Name="TriggeredEvent" Value="token_retrieved"></Parameter> <Parameter Name="RequestMethod" Value="post"></Parameter> <Parameter Name="Url" Value="https://api.example.com/v1/install/verify"></Parameter> <Parameter Name="Headers" Value="{"Content-Type":"application/json","X-Request-ID":"550e8400-e29b-41d4-a716-446655440000","User-Agent":"YourApp-Integration/1.0.0"}"></Parameter> <Parameter Name="Body" Value="{"app_id":"your_unique_app_identifier","webhook_url":"https://your-app.com/api/webhooks"}"></Parameter> <Parameter Name="ResponseFieldPath" Value=".data.access_token, .tokens[0].value"></Parameter> <Parameter Name="TargetVariable" Value="token,refresh"></Parameter> </Parameter> <Parameter Name="AuthMode" Value="pkce"></Parameter> <Parameter Name="CodeChallengeMethod" Value="S256"></Parameter> <Parameter Name="EnableKeepalive" Value="1"></Parameter> <Parameter Name="KeepaliveInterval" Value="5"></Parameter> </Parameters> <Requests></Requests></Scenario>Scenario element
Section titled “Scenario element”| Attribute | Description |
|---|---|
Id | Scenario identifier. Fixed as AuthMethod. |
Type | Scenario type. AUTH, the scenario performs authentication. |
Parameter element
Section titled “Parameter element”| Attribute | Description |
|---|---|
Name | Name of the authentication setting (see Authentication settings). |
Value | Value of the authentication setting. |
Father | The parent parameter that groups related child parameters. The authentication scenario has three parent types: CustomFieldList, PopulateTemplateString, and FollowUpList. |
The three parent parameters act as containers that organize child parameters into setting groups:
-
CustomFieldList, Defines the fields users fill in with their authentication credentials (Client ID, Client Secret, and so on) in the configuration UI. -
PopulateTemplateString, Defines custom HTTP headers to attach to every predefined CRM/Helpdesk request (user association, contact synchronization, and so on). -
FollowUpList, Defines one or more automated requests that fire after a specific event, such as after a token is retrieved.
Parent parameter attributes
Section titled “Parent parameter attributes”CustomFieldList (authentication credential inputs):
| Attribute | Description |
|---|---|
Name | Variable name of the field, usable in the template. For example, client_id is referenced as {{.client_id}}. |
Editor | Field type: string (plain text), password (masked input), or list (selectable options). |
Title | Label shown above the field in the configuration UI. |
Value | The predefined list of options. Available only when Editor is list. Separate options with commas, for example option1,option2. |
IsRequired | Whether the field is mandatory: 0 optional, 1 required. Available only when AuthMethod is oauth2. |
PopulateTemplateString (custom HTTP headers):
| Attribute | Description |
|---|---|
Type | Parameter type. Fixed as Header. |
Name | Name of the custom header. |
Value | Header value, a literal value or a variable. You can reference an authentication field variable, for example {{.client_id}}. |
Description | A short note describing the header’s purpose. |
FollowUpList (follow-up requests):
| Attribute | Description |
|---|---|
Type | Parameter type. Fixed as FollowUpRequest. |
Name | For the parent parameter, the system generates an ID automatically. For child parameters, the name of the follow-up request setting (see Follow-up request settings). |
Value | Value of the follow-up request setting. |
Authentication settings
Section titled “Authentication settings”| Setting | Description |
|---|---|
AuthMethod | Authentication method. none, no authentication, or only relevant variables (an API key, a webhook URL) are exchanged. basic, credentials such as a username/password or API key are base64-encoded and sent in a header on every request. oauth2, tokens grant access without sharing credentials; the header and other parameters (such as the access token) are obtained through specific API requests. bearertoken, every request carries a header of the form Authorization: Bearer {{.AccessToken}}, where {{.AccessToken}} is the token granted by the CRM/Helpdesk. |
AuthMode | Authorization mode (OAuth2 only). authorization_code, the standard code flow; use it when the CRM/Helpdesk expects a client_secret. pkce, Authorization Code with PKCE; use it when PKCE is supported, for an extra layer of security. In PKCE mode Cloud Voice generates a code_verifier, hashes it with SHA256 and Base64URL-encodes it into a code_challenge, sends the challenge upfront, and later presents the original verifier during token exchange. The server hashes the submitted verifier and compares it to the stored challenge; a match proves the client holds the original verifier, which prevents interception attacks. |
AuthEndPoint | Authorization URL to open to start the authorization process (OAuth2 only). |
TokenEndPoint | API URL for obtaining the access token and refresh token (OAuth2 and bearer token only). |
ContentType | Content type of the token retrieval request: application/json or application/x-www-form-urlencoded. |
CodeChallengeMethod | How the code_verifier is transformed into the code_challenge (available only when AuthMode is pkce). S256, SHA256 hash + Base64URL encoding (recommended). plain, use the verifier directly, for systems that do not support SHA256. |
AdditionalQueryString | Query variables to add when the CRM/Helpdesk authenticates with query parameters instead of a scope (OAuth2 only). |
Scope | The scope of CRM/Helpdesk data Cloud Voice may access (OAuth2 only). |
CredentialType | Credential type (Basic only): username_password or api_key. |
Base64EncodedCredential | The combination format used to build the basic authentication string (Basic only), for example {{.username}}:{{.password}} or {{.api_key}}. |
TokenRefreshEndpointMethod | HTTP method for the token refresh API: get or post (OAuth2 and bearer token only). |
TokenRefreshEndpoint | API URL for refreshing the access token (OAuth2 and bearer token only). |
TokenRefreshContentType | Content type of the refresh request: application/json, application/x-www-form-urlencoded, or multipart/form-data (OAuth2 and bearer token only). |
TokenRefreshInterval | How often the token is refreshed automatically, in minutes (OAuth2 and bearer token only). |
TokenRefreshBody | Request body for the refresh API (OAuth2 and bearer token only). |
EnableKeepalive | Whether to keep the connection alive: 0 disabled, 1 enabled (keep-alive requests are sent at the configured interval). |
KeepaliveInterval | Interval for keep-alive requests, in minutes. |
Follow-up request settings
Section titled “Follow-up request settings”| Setting | Description |
|---|---|
TriggeredEvent | The event that fires the request. token_retrieved, after an access token is retrieved. token_refreshed, after an access token is refreshed. |
RequestMethod | HTTP method: get or post. |
Url | Endpoint URL for the follow-up operation, for example https://api.example.com/rest-services/login. |
Headers | Request headers in JSON. Use {{.varname}} for dynamic values, for example {"Content-Type":"application/json", "X-Custom-Header": "{{.DynamicValue}}"}. |
Body | Request payload in JSON. Use {{.varname}} for dynamic values, for example {"lastName":"{{.LastName}}","ownerId":"{{.Id}}","phone":"{{.BusinessNumber}}"}. |
ResponseFieldPath | JSON path(s) to extract from the response. Separate multiple paths with commas, for example .data.access_token, .tokens[0].value. |
TargetVariable | Names of the system variables that store the extracted values. These can be existing or new custom variables and are stored globally for use across the integration. Separate multiple names with commas, for example token,refresh. Values are assigned in the same order as the paths in ResponseFieldPath. |
User association scenario
Section titled “User association scenario”This scenario retrieves the list of users from the CRM/Helpdesk.
<Scenario Id="UserAssociation" Type="REST"> <Parameters></Parameters> <Requests> <Request Name="UserAssociation" Method="GET" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v1/users?type=ActiveUsers"> <Parameters> <Parameter Name="PaginationEnabled" Value="0" /> <Parameter Name="PaginationType" Value="" /> <Parameter Name="VarPageName" Value="page" /> <Parameter Name="VarPageValue" Value="1" /> <Parameter Name="VarPageSizeName" Value="page_size" /> <Parameter Name="VarPageSizeValue" Value="10" /> <Parameter Name="VarOffsetName" Value="from" /> <Parameter Name="VarOffsetValue" Value="1" /> <Parameter Name="VarLimitName" Value="limit" /> <Parameter Name="VarLimitValue" Value="10" /> <Parameter Name="VarNextPagePath" Value="links.next" /> </Parameters> <Outputs> <Output Name="UserUniqueId" Path="users.#.id" Type=""></Output> <Output Name="FirstName" Path="users.#.First_Name" Type=""></Output> <Output Name="LastName" Path="users.#.Last_Name" Type=""></Output> <Output Name="Email" Path="users.#.Email" Type=""></Output> </Outputs> </Request> </Requests></Scenario>Scenario element
Section titled “Scenario element”| Attribute | Description |
|---|---|
Id | Scenario identifier. Fixed as UserAssociation. |
Type | Scenario type. REST, the scenario runs a REST API through an HTTP request. |
Request element
Section titled “Request element”| Attribute | Description |
|---|---|
Name | Request name, used to identify the request within the scenario. Fixed as UserAssociation. |
Method | HTTP method. Defaults to GET; change it if needed. |
ResponseType | Expected response format, in JSON (application/json). |
RequestEncoding | How the request is encoded. Empty in this scenario. |
URLFormat | Request URL of the API endpoint. |
Parameter element
Section titled “Parameter element”The <Parameter> element sets pagination behavior with a Name (a pagination setting) and its Value.
| Setting | Description |
|---|---|
PaginationEnabled | Whether pagination is enabled: 0 disable, 1 enable. |
PaginationType | Pagination mode. page_based, by page number and page size. offset_based, by starting index and record limit. link_based, by following the next-page URL in the response. |
VarPageName | Parameter name that specifies the page number (page-based only). |
VarPageValue | Initial page number to query from (page-based only). |
VarPageSizeName | Parameter name that specifies records per page (page-based only). |
VarPageSizeValue | Maximum records to return per page (page-based only). |
VarOffsetName | Parameter name that specifies the start position (offset-based only). |
VarOffsetValue | Starting position, as the number of records to skip (offset-based only). For example, 1 starts at the first record; 100 starts at the 100th. |
VarLimitName | Parameter name that specifies records per page (offset-based only). |
VarLimitValue | Maximum records to return per page (offset-based only). |
VarNextPagePath | JSON path (for example links.next) to the next-page link (link-based only). |
Output element
Section titled “Output element”| Attribute | Description |
|---|---|
Name | Output variable name, the value to retrieve from the response. |
Path | Location of the field in the response, using path syntax for nested data (for example users.#.id). |
Type | Data type of the output variable. Fixed as string. |
The scenario retrieves these variables:
| Variable | Description |
|---|---|
UserUniqueId | Unique ID of the CRM/Helpdesk user. |
FirstName | User’s first name. |
LastName | User’s last name. |
Email | User’s email. |
Automatic contact synchronization scenario
Section titled “Automatic contact synchronization scenario”This scenario searches for contacts in the CRM/Helpdesk. Its results drive contact search, automatic contact synchronization, and the call pop-up.
<Scenario Id="SyncContactAuto" Type="REST"> <Presets></Presets> <Parameters> <Parameter Name="ContactUrlType" Value="retrieve_from_contact"></Parameter> <Parameter Name="URLFormat"></Parameter> <Parameter Name="ContactFieldForUri" Value="data.#.contactUrl"></Parameter> <Parameter Name="ContactsIdEnable" Value="1"></Parameter> <Parameter Name="FirstNameEnable" Value="1"></Parameter> <Parameter Name="BusinessNumberEnable" Value="1"></Parameter> <Parameter Name="CustomValueEnable" Value="0"></Parameter> </Parameters> <Requests> <Request Name="Contacts" Method="GET" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v1/Contacts/search?criteria=((Phone:equals:{{.Phone}})or(Home_Phone:equals:{{.Phone}})or(Mobile:equals:{{.Phone}})or(Asst_Phone:equals:{{.Phone}}))"> <Parameters></Parameters> <Outputs> <Output Name="ContactsId" Path="data.0.id" Type=""></Output> <Output Name="FirstName" Path="data.0.First_Name" Type=""></Output> <Output Name="BusinessNumber" Path="data.0.Phone" Type=""></Output> ... <Output Name="CustomValue" Path="data.0.Owner" Type=""></Output> </Outputs> </Request> </Requests></Scenario>Scenario element
Section titled “Scenario element”| Attribute | Description |
|---|---|
Id | Scenario identifier. Fixed as SyncContactAuto. |
Type | Scenario type. REST, the scenario runs a REST API through an HTTP request. |
Parameter element
Section titled “Parameter element”The <Parameter> element carries the scenario’s configuration settings as Name/Value pairs.
| Setting | Description |
|---|---|
ContactUrlType | How the contact URL for the call pop-up is obtained. specify_url_format, build the URL from a format string with variables. retrieve_from_contact, pull the URL directly from a field in the contact search response. |
URLFormat | The expression for the contact URL. You can use variables captured during the authentication process, plus ContactSyncType (contact type, taken from the search request’s name), ContactId, and CustomValue (both retrieved from this scenario’s response). For example: {{.crm_url}}/crm/{{.CustomValue}}/tab/{{Capitalize .ContactSyncType}}/{{.ContactId}}. If the provided variables are not enough, define extra requests to retrieve what you need (see Retrieve additional variables for global use). |
ContactFieldForUri | JSON path to the contact URL field in the response, for example .data.#.contactUrl. |
ContactsIdEnable | Whether to retrieve the contact’s ID. Set to 1 (required). |
FirstNameEnable | Whether to retrieve the contact’s first name. Set to 1 (required). |
BusinessNumberEnable | Whether to retrieve the contact’s business phone number: 0 no, 1 yes. At least one phone number is required. |
CustomValueEnable | Whether to enable a custom variable that can be used to build the contact URL: 0 disable, 1 enable. |
The remaining fields are optional retrieval toggles. Each takes 0 (do not retrieve) or 1 (retrieve):
| Setting | Retrieves |
|---|---|
LastNameEnable | Contact’s last name |
CompanyEnable | Contact’s company |
EmailEnable | Contact’s email |
BusinessNumber2Enable | Second business phone number |
BusinessFaxNumberEnable | Business fax number |
MobileNumberEnable | Mobile number |
MobileNumber2Enable | Second mobile number |
HomeNumberEnable | Home number |
HomeNumber2Enable | Second home number |
HomeFaxNumberEnable | Home fax number |
OtherNumberEnable | Other number (not business or home) |
ZipCodeEnable | Zip code |
StreetEnable | Street |
CityEnable | City |
StateEnable | State/province |
CountryEnable | Country |
RemarkEnable | Remark |
Request element
Section titled “Request element”| Attribute | Description |
|---|---|
Name | Request name. Set it to the actual name of the contact type being searched in the CRM/Helpdesk; it is exposed as the ContactSyncType variable. |
Method | HTTP method. Defaults to GET; change it if needed. |
ResponseType | Expected response format, in JSON (application/json). |
RequestEncoding | How the request is encoded. Empty in this scenario. |
URLFormat | Request URL of the API endpoint. |
Output element
Section titled “Output element”Each <Output> uses Name, Path, and Type (fixed as string), as described under User association.
| Variable | Description |
|---|---|
ContactsId | (Required) Unique ID of the contact. |
FirstName | (Required) Contact’s first name. |
LastName | Contact’s last name. |
Company | Contact’s company. |
Email | Contact’s email. |
BusinessNumber | Business phone number. At least one phone number is required. |
BusinessNumber2 | Second business phone number. |
BusinessFaxNumber | Business fax number. |
MobileNumber | Mobile number. |
MobileNumber2 | Second mobile number. |
HomeNumber | Home number. |
HomeNumber2 | Second home number. |
HomeFaxNumber | Home fax number. |
OtherNumber | Other phone number. |
ZipCode | Zip code. |
Street | Street. |
City | City. |
State | State or province. |
Country | Country. |
Remark | Remark. |
CustomValue | Custom variable used to build the contact URL. |
Automatic contact creation scenario
Section titled “Automatic contact creation scenario”This scenario creates a new contact in the CRM/Helpdesk when a caller’s number does not match any existing contact.
<Scenario Id="CreateNewContact" Type="REST"> <Parameters></Parameters> <Requests> <Request Name="Contacts" Method="POST" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v1/Contacts"> <Parameters> <Parameter Name="Data" Type="Body" Value="{"data": [{"Last_Name":"{{.LastName}}","First_Name":"{{.FirstName}}","Phone":"{{.BusinessNumber}}"}]}"></Parameter> </Parameters> <Outputs></Outputs> </Request> </Requests></Scenario>Scenario element
Section titled “Scenario element”| Attribute | Description |
|---|---|
Id | Scenario identifier. Fixed as CreateNewContact. |
Type | Scenario type. REST, the scenario runs a REST API through an HTTP request. |
Request element
Section titled “Request element”| Attribute | Description |
|---|---|
Name | Request name. Set it to the actual name of the contact type to create in the CRM/Helpdesk. |
Method | HTTP method. POST in this scenario. |
ResponseType | Expected response format, in JSON (application/json). |
RequestEncoding | How the request is encoded. Empty in this scenario. |
URLFormat | Request URL of the API endpoint. |
Parameter element
Section titled “Parameter element”The <Parameter> nested inside <Request> defines the request body.
| Attribute | Description |
|---|---|
Name | Parameter name. Fixed as Data. |
Type | Parameter type. Fixed as Body. |
Value | The parameters passed in the request body, inside a data structure. Values can come from Cloud Voice’s predefined variables. |
Only the required variables appear below. For more, see Retrieve additional variables for global use.
| Variable | Description |
|---|---|
Variables from the AuthMethod scenario | Variables captured from the authentication credential inputs during authentication. |
| Target variables from follow-up requests | Values extracted from the responses of follow-up requests. |
{{.LastName}} | Contact’s last name. |
{{.FirstName}} | Contact’s first name. |
{{.BusinessNumber}} | Contact’s phone number. |
Automatic ticket creation scenario (Helpdesk only)
Section titled “Automatic ticket creation scenario (Helpdesk only)”This scenario creates a new ticket in the Helpdesk.
<Scenario Id="CreateNewTicket" Type="REST"> <Presets></Presets> <Parameters> <Parameter Name="EnableSubject" Value="1"></Parameter> <Parameter Name="Subject" Value="{{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}}"></Parameter> <Parameter Name="EnableDescription" Value="1"></Parameter> <Parameter Name="Description" Value="{{.Time}} {{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}} {{.Talk_Duration}}"></Parameter> </Parameters> <Requests> <Request Name="CreateNewTicket" Method="POST" Weight="0" ResponseType="application/json" RequestEncoding="" URLFormat="https://{{.domain}}/api/v1/tickets"> <Parameters> <Parameter Name="Data" Type="Body" Value="{"subject":"{{.Subject}}","contactId":"{{.ContactId}}","phone":"{{.ContactNumber}}","description":"{{.Description}}"}"></Parameter> </Parameters> <Outputs></Outputs> </Request> </Requests></Scenario>Scenario element
Section titled “Scenario element”| Attribute | Description |
|---|---|
Id | Scenario identifier. Fixed as CreateNewTicket. |
Type | Scenario type. REST, the scenario runs a REST API through an HTTP request. |
Parameter element
Section titled “Parameter element”Configuration settings for the scenario, as Name/Value pairs:
| Setting | Description |
|---|---|
EnableSubject | Whether the ticket subject is customizable: 0 disable, 1 enable. |
Subject | Default subject value. Default: {{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}}. See the variable list for supported variables. |
EnableDescription | Whether the ticket description is customizable: 0 disable, 1 enable. |
Description | Default description value. Default: {{.Time}} {{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}} {{.Talk_Duration}}. See the variable list for supported variables. |
Request element
Section titled “Request element”| Attribute | Description |
|---|---|
Name | Request name. Fixed as CreateNewTicket. |
Method | HTTP method. POST in this scenario. |
ResponseType | Expected response format, in JSON (application/json). |
RequestEncoding | How the request is encoded. Empty in this scenario. |
URLFormat | Request URL of the API endpoint. |
Parameter element (request body)
Section titled “Parameter element (request body)”The <Parameter> nested inside <Request> defines the request body, with Name fixed as Data, Type fixed as Body, and Value holding the body content built from predefined variables.
Only the required variables are listed. For more, see Retrieve additional variables for global use.
| Variable | Description |
|---|---|
Variables from the AuthMethod scenario | Variables captured from the authentication credential inputs. |
| Target variables from follow-up requests | Values extracted from follow-up request responses. |
{{.Subject}} | Ticket subject, taken from the Subject parameter. |
{{.Description}} | Ticket description, taken from the Description parameter. |
{{.LinkedId}} | Unique ID of the call. |
{{.Time}} | Time the call was made or received (in the system’s time format). |
{{.StartTimeUnix}} | Unix timestamp of the call start time. |
{{.EndTimeUnix}} | Unix timestamp of the call end time. |
{{.Call_From}} | Name and number of the calling party. Format: Caller's name <Caller's number>. |
{{.CallerName}} | Caller’s name. |
{{.CallerNumber}} | Caller’s number. |
{{.CalleeName}} | Callee’s name. |
{{.CalleeNumber}} | Callee’s number. |
{{.CrmId}} | Unique ID of the CRM/Helpdesk user associated with a Cloud Voice extension. |
{{.ExtensionFirstName}} | Extension user’s first name. |
{{.ExtensionLastName}} | Extension user’s last name. |
{{.ExtensionEmail}} | Extension user’s email. |
{{.ContactSyncType}} | Contact type. |
{{.ContactNumber}} | Contact’s number. |
{{.ContactId}} | Unique ID of a contact. |
{{.TicketId}} | Unique ID of the ticket created from a call. To obtain it, add extra settings (see Retrieve the ticket ID for further operations). |
{{.CallDuration}} | Time between the call starting and ending. |
{{.Talk_Duration}} | Time between the call being answered and ending, in hh:mm:ss. |
{{.Talk_Duration_Sec}} | Time between the call being answered and ending, in seconds. |
{{.Communication_Type}} | Call direction: Inbound or Outbound. |
{{.Call_Status}} | Processing status: Missed (not answered) or Completed (connected and finished). |
{{.Call_Log_Status}} | Call status: Missed Call, Outgoing Call, Incoming Call, or Voicemail. |
{{.CallDisposition}} | Call disposition: MISSED, VOICEMAIL, BUSY, ANSWERED, or NO ANSWER. |
Call journal scenario
Section titled “Call journal scenario”This scenario logs the call activity of associated users to the CRM/Helpdesk.
<Scenario Id="CallJournal" Type="REST"> <Presets></Presets> <Parameters> <Parameter Name="EnableSubject" Value="1"></Parameter> <Parameter Name="Subject" Value="Extension Call"></Parameter> <Parameter Name="EnableDescription" Value="1"></Parameter> <Parameter Name="Description" Value="Call: {{.Time}} {{.Call_Log_Status}} from {{.Call_From}} to {{.Call_To}} {{.Talk_Duration}}"></Parameter> <Parameter Name="EnablePlayCallRecording" Value="1"></Parameter> <Parameter Name="PlayCallRecording" Value="0"></Parameter> <Parameter Name="EnableForwardCallLogForAnsweredAgent" Value="0"></Parameter> <Parameter Name="ForwardCallLogForAnsweredAgent" Value="0"></Parameter> </Parameters> <Requests> <Request Name="CallJournal" Method="POST" Weight="0" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v2/Calls" RefreshTime="" IsDelete="0"> <Parameters> <Parameter Name="Data" Type="Body" Value="{
 "data": [
 {
 "{{.Owner}}{{.WhoModule}}": {
 "Description": "{{.Description}}",
 "Voice_Recording__s": "{{.RecordPath}}",
 "Call_Start_Time": "{{TimeFormat .StartTimeUnix 'yyyy-MM-ddTHH:mm:ss-z' '1'}}",
 "Subject": "{{.Subject}}",
 "Call_Type": "Inbound",
 "Call_Result": "{{.Call_Log_Status}}",
 "Call_Duration": "{{.Talk_Duration_Sec}}"
 }
 }
 ]
}"></Parameter> </Parameters> <Outputs></Outputs> </Request> <Request Name="CallJournalUpdate" Method="PUT" Weight="0" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v2/Calls/{{.CallId}}" RefreshTime="" IsDelete="0"> <Parameters> <Parameter Name="Data" Type="Body" Value="{
 "data": [
 {
 "{{.Owner}}{{.WhoModule}}": {
 "Description": "{{.Description}}",
 "Voice_Recording__s": "{{.RecordPath}}",
 "Call_Start_Time": "{{TimeFormat .StartTimeUnix 'yyyy-MM-ddTHH:mm:ss-z' '1'}}",
 "Subject": "{{.Subject}}",
 "Call_Type": "Inbound",
 "Call_Result": "{{.Call_Log_Status}}",
 "Call_Duration": "{{.Talk_Duration_Sec}}",
 "AI_Transcription": "{{.AI_Transcription}}",
 "AI_Summary": "{{.AI_Summary}}",
 "Call_Note": "{{.Call_Note}}"
 }
 }
 ]
}"></Parameter> </Parameters> <Outputs></Outputs> </Request> </Requests></Scenario>Scenario element
Section titled “Scenario element”| Attribute | Description |
|---|---|
Id | Scenario identifier. Fixed as CallJournal. |
Type | Scenario type. REST, the scenario runs a REST API through an HTTP request. |
Parameter element
Section titled “Parameter element”Configuration settings for the scenario, as Name/Value pairs:
| Setting | Description |
|---|---|
EnableSubject | Whether the call log subject is configurable in the integration: 0 disable, 1 enable. |
Subject | Default subject value. Default: Extension Call. You can also use supported variables (see the variable list). |
EnableDescription | Whether the call log description is configurable: 0 disable, 1 enable. |
Description | Default description value. Default: {{.Time}} {{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}} {{.Talk_Duration}}. See the variable list. |
EnablePlayCallRecording | Whether playing call recordings within the CRM/Helpdesk is configurable: 0 disable, 1 enable. |
PlayCallRecording | Default state of the recording-playback option: 0 disable, 1 enable. |
EnableForwardCallLogForAnsweredAgent | Whether the option to suppress missed-call logs for non-answering agents (on queue or ring group calls) is configurable in the integration. |
ForwardCallLogForAnsweredAgent | Default state of that option. 0 disable. 1 enable, for queue and ring group calls, the log syncs only to the CRM/Helpdesk of the agent who answered, and missed-call logs for the same call are not synced to agents who did not answer. |
Request element
Section titled “Request element”| Attribute | Description |
|---|---|
Name | Request name. CallJournal creates a new call log in the CRM/Helpdesk. CallJournalUpdate updates an existing call log with additional information. |
Method | HTTP method: POST or PUT. |
ResponseType | Expected response format, in JSON (application/json). |
RequestEncoding | How the request is encoded. Empty in this scenario. |
URLFormat | Request URL of the API endpoint. |
Parameter element (request body)
Section titled “Parameter element (request body)”The <Parameter> nested inside <Request> defines the request body, with Name fixed as Data, Type fixed as Body, and Value holding the body content built from predefined variables.
The request body accepts every call variable listed for Automatic ticket creation, plus the following recording and AI fields:
| Variable | Description |
|---|---|
{{.EnableCallRecording}} | Whether call recording is enabled: 0 disabled, 1 enabled. |
{{.AI_Transcription}} | AI-generated call transcript. |
{{.AI_Summary}} | AI-generated call summary. |
{{.Call_Note}} | Call note content. |
Only the required variables are documented here. For more, see Retrieve additional variables for global use.
Chat journal scenario
Section titled “Chat journal scenario”This scenario syncs the chat messages exchanged between associated users and contacts to the CRM/Helpdesk.
<Scenario Id="ChatJournal" Type="REST"> <Presets></Presets> <Parameters> <Parameter Name="EnableSubject" Value="1"/> <Parameter Name="Subject" Value="PhoneSystem External Chat Session"/> <Parameter Name="EnableCreateType" Value="0"/> <Parameter Name="CreateType" Value=""/> </Parameters> <Requests> <Request Name="ChatJournalDefault" Method="POST" Weight="0" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/crm/v7/Tasks" RefreshTime="" IsDelete="0"> <Parameters> <Parameter Name="Data" Type="Body" Value="{ "data": [ { "Owner": { "id": "{{.OwnerId}}" }, "Who_Id": "{{.ContactEntityId}}", "Subject": "{{.Subject}}", "Due_Date": "{{ TimeFormat .StartTimeUnix "yyyy-MM-dd" "0" }}", "Closed_Time": "{{ TimeFormat .EndTimeUnix "yyyy-MM-ddTHH:mm:ss.000Zz" "0" }}", "Status": "Completed", "Priority": "Normal", "Description": "Message Channel Type: {{.Channel_Display}}\n\n{{.Messages}}" } ] }"/> </Parameters> <Outputs/> </Request> </Requests></Scenario>Scenario element
Section titled “Scenario element”| Attribute | Description |
|---|---|
Id | Scenario identifier. Fixed as ChatJournal. |
Type | Scenario type. REST, the scenario runs a REST API through an HTTP request. |
Parameter element
Section titled “Parameter element”Configuration settings for the scenario, as Name/Value pairs:
| Setting | Description |
|---|---|
EnableSubject | Whether the subject of the synced record is configurable: 0 disable, 1 enable. |
Subject | Default subject value. Default: PhoneSystem External Chat Session. You can also use supported variables (see the variable list). |
EnableCreateType | Reserved field (not applicable). |
CreateType | Reserved field (not applicable). |
Request element
Section titled “Request element”| Attribute | Description |
|---|---|
Name | Request name. Fixed as ChatJournalDefault. |
Method | HTTP method: POST or PUT. |
ResponseType | Expected response format, in JSON (application/json). |
RequestEncoding | How the request is encoded. Empty in this scenario. |
URLFormat | Request URL of the API endpoint. |
Parameter element (request body)
Section titled “Parameter element (request body)”The <Parameter> nested inside <Request> defines the request body, with Name fixed as Data, Type fixed as Body, and Value holding the body content built from predefined variables.
Only the required variables are listed. For more, see Retrieve additional variables for global use.
| Variable | Description |
|---|---|
Variables from the AuthMethod scenario | Variables captured from the authentication credential inputs. |
| Target variables from follow-up requests | Values extracted from follow-up request responses. |
{{.ContactNumber}} | Phone number of the CRM/Helpdesk contact. |
{{.ContactEmail}} | Email address of the CRM/Helpdesk contact. |
{{.ContactName}} | Name of the CRM/Helpdesk contact. |
{{.ContactEntityId}} | Entity ID of the matched contact, lead, or account. |
{{.ContactEntityType}} | Type of the matched entity (contact, lead, or account). |
{{.QueueName}} | Name of the message queue, included when the chat is routed to a queue. |
{{.Messages}} | The messages sent and received during the session, including time, senders, and content. |
{{.ExtensionNumber}} | Extension number of the extension or agent who handled the messages or closed the session. If the system closes the session automatically, this is PBX System. |
{{.ExtensionFirstName}} | First name of the extension or agent who handled the messages or closed the session. If the system closes it automatically, this is PBX System. |
{{.ExtensionLastName}} | Last name of the extension or agent who handled the messages or closed the session. If the system closes it automatically, this is PBX System. |
{{.ExtensionEmail}} | Email address of the extension or agent who handled the messages. |
{{.ChatDuration}} | Chat session duration, in hh:mm:ss. To convert to total minutes, use {{ToMinutes .ChatDuration}}. |
{{.StartTimeUnix}} | Unix timestamp (seconds) of the session start. Format it as a local time string with {{ TimeFormat .StartTimeUnix "yyyy-MM-ddTHH:mm:ss.000Zz" "0" }}, as UTC with "1" instead of "0", or convert to milliseconds with {{ToMillis .StartTimeUnix}}. |
{{.EndTimeUnix}} | Unix timestamp (seconds) of the session end. Format it as a local time string with {{ TimeFormat .EndTimeUnix "yyyy-MM-ddTHH:mm:ss.000Zz" "0" }}, as UTC with "1" instead of "0", or convert to milliseconds with {{TsSecToMilliSec .EndTimeUnix}}. |
Extended configurations
Section titled “Extended configurations”Beyond the scenarios you set on the configuration page, you can add custom configurations by editing the template directly.
Set custom request headers
Section titled “Set custom request headers”To add custom request headers, add one or more parameters with Type set to Header. In the example below, an X-Auth-Token header carries the API key. Father (fixed as PopulateTemplateString) groups the related parameters, Type (fixed as Header) marks the parameter as an HTTP header, and Name and Value set the header. The request then includes X-Auth-Token:{{.api_key}}.
<Requests> <Request Name="contacts" Method="GET" ResponseType="application/json" URLFormat="https://api.example.com/contacts/search?number={{.Phone}}"> <Parameters> <Parameter Father="PopulateTemplateString" Name="X-Auth-Token" Type="Header" Value="{{.api_key}}" /> </Parameters> <Outputs> ... </Outputs> </Request></Requests>Identify token errors
Section titled “Identify token errors”In the AuthMethod scenario, add a TokenInvalid parameter to help distinguish a token problem from other errors. Set its Value to the token-related error code or specific content. If the HTTP status is not 200 and the response body contains that content, the error is recognized as TokenInvalid.
<Scenario Id="AuthMethod" Type="AUTH"> <Presets /> <Parameters> <Parameter Name="AuthMethod" Value="oauth2" /> ... <Parameter Father="TokenErrorMap" Type="TokenInvalid" Name="TokenInvalid" Value="INVALID_TOKEN" /> ... </Parameters> <Requests /> <Responses /></Scenario>Retrieve additional variables for global use
Section titled “Retrieve additional variables for global use”If you need variables beyond the built-in ones, for example common information you want to reuse globally, define a GetGlobalInfo scenario with the requests that retrieve those values.
When the integration completes or Cloud Voice starts, the requests inside GetGlobalInfo are sent to the CRM/Helpdesk and the values are stored in the Output elements. Each output’s name maps directly to a variable name, making it available in other scenarios (except the authentication scenario). In the example below, GetGlobalInfo retrieves DepartmentId and PortalName.
<Scenario Id="GetGlobalInfo" Type="REST"> <Presets /> <Parameters /> <Requests> <Request Name="GetDepartments" Method="GET" ResponseType="application/json" URLFormat="https://desk.example.{{.domain_suffix}}/api/v1/departments"> <Parameters /> <Outputs> <Output Name="DepartmentId" Path="data.#.id" /> </Outputs> </Request> <Request Name="GetOrganizations" Method="GET" ResponseType="application/json" URLFormat="https://desk.example.{{.domain_suffix}}/api/v1/organizations"> <Parameters /> <Outputs> <Output Name="PortalName" Path="data.#(portalName!="").portalName" /> </Outputs> </Request> </Requests></Scenario>Supplement contact query information
Section titled “Supplement contact query information”If the first contact query does not return everything you need, run a further query using the returned contact ID or other fields. In the example below, the initial contact-sync query does not return the phone numbers:
<Scenario Id="SyncContactAuto" Type="REST"> <Presets /> <Parameters> <Parameter Name="ContactUrlType" Value="specify_url_format" /> ... </Parameters> <Requests> <Request Name="contacts" Method="GET" ResponseType="application/json" URLFormat="https://{{.subdomain}}.example.com/api/v2/users?query=phone:{{UrlEncode .Phone}}&role[]=end-user"> <Parameters /> <Outputs Next="GetIdentities"> <Output Name="ContactsId" Path="users.#.id" /> <Output Name="FirstName" Path="users.#.name" /> <Output Name="BusinessNumber" Path="users.#.phone" /> ... <!-- The following phone number fields return empty. --> <Output Name="BusinessNumber2" Path=""></Output> <Output Name="BusinessFaxNumber" Path=""></Output> <Output Name="MobileNumber" Path=""></Output> <Output Name="MobileNumber2" Path=""></Output> <Output Name="HomeNumber" Path=""></Output> <Output Name="HomeNumber2" Path=""></Output> ... </Outputs> </Request> </Requests></Scenario>To retrieve the missing numbers, chain scenarios:
-
Add a
Nextattribute to the original scenario. In the contact-sync scenario, add aNextattribute to the<Outputs>element of the initial query request. Its value is the name of the request you will define in theCommonscenario, here,GetIdentities.<Outputs Next="GetIdentities"> -
Create a
Commonscenario. Create a scenario namedCommonwith typeREST(both are fixed), then add a request namedGetIdentitiesthat queries the extra contact information using{{.ContactsId}}from the initial request.<Scenario Id="Common" Type="REST"><Presets></Presets><Parameters></Parameters><Requests><Request Name="GetIdentities" Method="GET" URLFormat="https://{{.subdomain}}.example.com/api/v2/users/{{.ContactsId}}/identities" ResponseType="application/json"><Parameters></Parameters><Outputs><Output Name="BusinessNumber2" Path="identities.#(type=="phone_number")#|1.value"></Output><Output Name="BusinessFaxNumber" Path="identities.#(type=="phone_number")#|2.value"></Output><Output Name="MobileNumber" Path="identities.#(type=="phone_number")#|3.value"></Output><Output Name="MobileNumber2" Path="identities.#(type=="phone_number")#|4.value"></Output><Output Name="HomeNumber" Path="identities.#(type=="phone_number")#|5.value"></Output><Output Name="HomeNumber2" Path="identities.#(type=="phone_number")#|6.value"></Output><Output Name="HomeFaxNumber" Path="identities.#(type=="phone_number")#|7.value"></Output><Output Name="OtherNumber" Path="identities.#(type=="phone_number")#|8.value"></Output></Outputs></Request></Requests></Scenario>Because the request is referenced through the
Nextattribute of the original scenario, the variable from the initial query is passed to it. The request runs and backfills itsOutputsinto the initial response to complete the record.
Retrieve the ticket ID for further operations
Section titled “Retrieve the ticket ID for further operations”In a Helpdesk template, you can retrieve the ticket ID for later operations, such as updating the ticket or referencing it in the call journal. For example, when a ticket is created before the call (when the phone rings), it may be missing information you can fill in later using its TicketId.
<Scenario Id="CreateNewTicket" Type="REST"> <Presets /> <Parameters> <Parameter Name="EnableSubject" Value="1" /> ... <Parameter Name="NeedSyncContact" Value="1" /> </Parameters> <Requests> <Request Name="CreateNewTicket" Method="POST" ResponseType="application/json" URLFormat="https://{{.domain}}/api/v1/tickets"> <Parameters> <Parameter Name="Data" Type="Body" Value="{"departmentId":"{{.DepartmentId}}","subject":"{{.Subject}}","contactId":"{{.ContactId}}","phone":"{{.ContactNumber}}","description":"{{.Description}}"}" /> </Parameters> <Outputs> <Output Name="TicketId" Path="id" /> </Outputs> </Request> <Request Name="UpdateTicket" Method="POST" ResponseType="application/json" URLFormat="https://{{.domain}}/api/v1/tickets/{{.TicketId}}/comments"> <Parameters> <Parameter Name="Data" Type="Body" Value="{"isPublic":"true","content":"{{.Description}}"}" /> </Parameters> <Outputs /> </Request> </Requests></Scenario>-
Retrieve the ticket ID. In the
CreateNewTicketscenario, add an<Output>element to extract the ID from theCreateNewTicketrequest’s response. This stores theTicketIdfor later use.<Outputs><Output Name="TicketId" Path="id" /></Outputs> -
Update the ticket. Add a request that updates the ticket in the corresponding call record using the retrieved ID. The ticket is then completed with all necessary data after its initial creation.
<Request Name="UpdateTicket" Method="POST" ResponseType="application/json" URLFormat="https://{{.domain}}/api/v1/tickets/{{.TicketId}}/comments"><Parameters><Parameter Name="Data" Type="Body" Value="{"isPublic":"true","content":"{{.Description}}"}" /></Parameters><Outputs /></Request>