CCX Script to create Voice Call records
To get the full value of Salesforce Service Cloud Voice, the call flow in Cisco CCX must be modified to create the Voice Call record in Service Cloud Voice as soon as the call arrives in the Contact Center.
An optional Omni-Flow can be executed, for routing decisions and automation in Salesforce.
For details the APIs used, see Service Cloud Voice API Wrapper
Pre-requisites
In order to use the Service Cloud Voice API Wrapper, a Salesforce Connected App for IVR integration must be configured.
Cisco CCX Sample Script
Download
Download latest Cisco CCX Sample Script
High-level call flow:
- Initialize
- Get Access Token
- Create Voice Call Record
- Assign voice call record ID to the PeripheralVariable as configured in the Contact Center (parameter Call Variable for the Voice Call Record Id)
- Assign the ImplementationID, which is used as Vendor Call Key, to the PeripheralVariable as configured in the Contact Center (parameter Call Variable for the Vendor Call Key)
- Execute Omni-Flow (optional)
- Welcome message
- Route to Agent or route to queue
- Queue message and music
- If caller hangs-up while in queue
- Clear Routing
- Update Voice Call Record
Step-by-Step
Initialize
Handle abandoned calls
If the caller hangs-up the call before it is answered by an agent, we have to update Service Cloud Voice and terminate the call
- If Execute Omni-Flow was used, send Clear Routing to delete the Pending Service Routing (PSR)
- Send Update Voice Call, to update the start and end times on the Voice Call record and to change the status from New to Completed
Register for event when caller hangs-up call before being answered by the agent. Jump to ABANDONED CALL
label at the end of the flow
Accept call and set start time varialbe
startTime = D[now].toInstant().toString()
Read call related data:
- ImplementationID = Get Contact Info > Implementation ID
- ANI: CalledNumber = Get Call Contatct Info > Called Number
- DNIS CallingNumber = Get Call Contatct Info > Calling Number
Get Access Token
URL
sfAuthorizeEndpointURL
Content Type:
"application/json"
URL Parameters
"grant_type" = "client_credentials"
"client_id" = sfClientId
"client_secret" = sfClientSecret
Body
""
Variables
Variable name | Variable value |
---|---|
sfAuthorizeEndpointURL | https://<your-domain-name>.my.salesforce.com/services/oauth2/token |
sfClientId | Connected App "Consumer Key" |
sfClientSecret | Connected App "Consumer Secret" |
Return Values
Body value | Write into variable |
---|---|
$.access_token | sfAccessToken |
$.instance_url | sfInstanceURL |
Create Voice Call record
This step is required for every call. After the Voice Call record is created, the Voice Call record ID must be passed with the call to the agent in a PeripheralVaraible. Configure the used PeripheralVariable in the Contact Center configuration in Service Cloud Voice.
URL:
sfInstanceURL + "/services/apexrest/cnxscv/voice/v1/createVoiceCall"`
Content Type
"application/json"
URL Parameters
"Authorization" = "Bearer " + sfAccessToken
Body
When creating the Voice Call record, you can also updata custom fields on the Voice Call record with call data. Below are two examples of the request body, one with all the required fields but without updating custom fields, and one with custom fields.
Without updating custom fields on Voice Call record:
u"{\"callCenterDevName\":\""
+ sfCallCenterDevName
+u"\",\"certDevName\":\""
+ sfCertDevName
+u"\",\"vendorCallKey\":\""
+ ImplementationID
+u"\",\"to\":\""
+ CalledNumber
+u"\",\"from\":\""
+ CallingNumber
+u"\",\"initiationMethod\":\"Inbound\",\"startTime\":\""
+ startTime
+u"\",\"participants\":[{\"participantKey\":\""
+ CallingNumber
+u"\",\"type\":\"END_USER\"}]"
+"}"
Example with updating custom fields on Voice Call record:
u"{\"callCenterDevName\":\""
+ sfCallCenterDevName
+u"\",\"certDevName\":\""
+ sfCertDevName
+u"\",\"vendorCallKey\":\""
+ ImplementationID
+u"\",\"to\":\""
+ CalledNumber
+u"\",\"from\":\""
+ CallingNumber
+u"\",\"initiationMethod\":\"Inbound\",\"startTime\":\""
+ startTime
+u"\",\"participants\":[{\"participantKey\":\""
+ CallingNumber
+u"\",\"type\":\"END_USER\"}]"
+u",\"callAttributes\":\"{"
+u"\\"Service__c\\":\\"" + callerInfoSelectedService + u"\\","
+u"\\"Language__c\\":\\"" + callerInfoSelectedLanguage + u"\\","
+u"\\"Customer_ID__c\\":\\"" + callerInfoCustomerId + u"\\"}\""
+"}"
Variables
Variable name | Variable value |
---|---|
sfCallCenterDevName | Contact Center Developer Name |
sfCertDevName | API Name of Certificate (as configured in Contact Center) |
ImplementationID | Get Contact Info > Implementation ID |
CalledNumber | Get Call Contact Info > Called Number (= DNIS) |
CallingNumber | Get Call Contact Info > Calling Number (= ANI) |
startTime | D[now].toInstant().toString() (to be set right after the call is accepted in the script) |
Example using custom fields on Voice Call object:
Custom field on Voice Call object | Variable name | Variable value |
---|---|---|
Service__c | callerInfoSelectedService | <depends on use case> |
Language__c | callerInfoSelectedLanguage | <depends on use case> |
Customer_ID__c | callerInfoCustomerId | <depends on use case> |
Return Values
Body value | Write into variable |
---|---|
$.data.voiceCallId | sfVoiceCallRecordId |
Set Enterprise Call Info
Call Variable (example) | Call Variable value |
---|---|
Call.PeripheralVariable7 | sfVoiceCallRecordId (PeripheralVariable as configured in Contact Center, parameter Call Variable for the Voice Call Record Id) |
Call.PeripheralVariable6 | ImplementationID (PeripheralVariable as configured in Contact Center, parameter Call Variable for the Vendor Call Key) |
Note: To reduce the number of Peripheral Variables, required for Service Cloud Voice, it is possible store the Voice Call record ID and the Vendor Call Key in one Peripheral Variable. See Combine Voice Call record ID and Vendor Call Key in one Peripheral Variable for more details
Execute Omni-Flow (optional step)
Use the Execute Omni-Flow when you want to
- run automated tasks, for example search for or create records, and link the records with the Voice Call record
- search for records and do screen-pop
- synchronize Salesforce and Cisco queues
- let Service Cloud Voice make the routing decision
This request always returns the "queue" or "agent" to where the call must be routed.
After executing this request, make sure you send Clear Routing if the caller hangs-up before being answered by an agent.
URL
sfInstanceURL + "/services/apexrest/cnxscv/voice/v1/executeOmniFlow"
Content Type
"application/json"
URL Parameters
"Authorization" = "Bearer " + sfAccessToken
Body
Apart from the required fields, it is possible to pass additional data as input variables to the Omni-Flow. Below are two examples of the request body. First without additional flow parameters, required fields only, the second with two input variables.
Without Omni-Flow parameters:
u"{\"callCenterDevName\":\""
+ sfCallCenterDevName
+u"\",\"certDevName\":\""
+ sfCertDevName
+u"\",\"voiceCallId\":\""
+ sfVoiceCallRecordId
+u"\",\"dialedNumber\":\""
+ CalledNumber
+u"\",\"flowDevName\":\""
+ sfFlowName
+u"\",\"fallbackQueue\":\""
+ sfFallbackQueueId
+u"\""
+u"\"}"
Example with Omni-Flow parameters:
u"{\"callCenterDevName\":\""
+ sfCallCenterDevName
+u"\",\"certDevName\":\""
+ sfCertDevName
+u"\",\"voiceCallId\":\""
+ sfVoiceCallRecordId
+u"\",\"dialedNumber\":\""
+ CalledNumber
+u"\",\"flowDevName\":\""
+ sfFlowName
+u"\",\"fallbackQueue\":\""
+ sfFallbackQueueId
+u"\""
+u",\"flowInputParameters\":{"
+u"\"param1\":\""
+ sfFlowParam1
+u"\",\"param2\":\""
+ sfFlowParam2
+u"\"}"
Variables
Variable name | Variable value |
---|---|
sfCallCenterDevName | Contact Center Developer Name |
sfCertDevName | API Name of Certificate (as configured in Contact Center) |
sfVoiceCallRecordId | ID of the voice call record, created in the previous step |
CalledNumber | Get Call Contact Info > Called Number (= DNIS) |
sfFlowName | Developer name of the omni-flow to execute |
sfFallbackQueueId | Queue ID or Queue API name of the fallback queue |
Example using Omni-Flow parameters:
Omni-Flow parameter variable name | Variable name | Variable value |
---|---|---|
param1 | sfFlowParam1 | <depends on use case> |
param2 | sfFlowParam2 | <depends on use case> |
Return Values
Body value | Write into variable |
---|---|
$.data.queue | |
$.data.agent |
Clear Routing (only if customer call is abandoned in queue)
If the caller hangs the call up before it is answered by an agent, we have to update Service Cloud Voice and terminate the call
- If Execute Omni-Flow was used, send Clear Routing to delete the Pending Service Routing (PSR)
- Send Update Voice Call, to update the start and end times on the Voice Call record and to change the status from New to Completed
When entering this script, register for the event when caller hangs-up call before being answered by the agent and jump into this section here in the script.
URL
sfInstanceURL + "/services/apexrest/cnxscv/voice/v1/clearRouting"
Content Type
"application/json"
URL Parameters
"Authorization" = "Bearer " + sfAccessToken
Body
u"{\"callCenterDevName\":\""
+ sfCallCenterDevName
+u"\",\"certDevName\":\""
+ sfCertDevName
+u"\",\"voiceCallId\":\""
+ sfVoiceCallRecordId
+u"\"}"
Variables
Variable name | Variable value |
---|---|
sfCallCenterDevName | Contact Center Developer Name |
sfCertDevName | API Name of Certificate (as configured in Contact Center) |
sfVoiceCallRecordId | ID of the voice call record, created in a previous step |
Update Voice Call (after "Clear Routing" to update status of the Voice Call record)
URL
sfInstanceURL + "/services/apexrest/cnxscv/voice/v1/updateVoiceCall"
Content Type
"application/json"
URL Parameters
"Authorization" = "Bearer " + sfAccessToken
Body
u"{\"callCenterDevName\":\""
+ sfCallCenterDevName
+u"\",\"certDevName\":\""
+ sfCertDevName
+u"\",\"voiceCallId\":\""
+ sfVoiceCallRecordId
+u"\",\"startTime\":\""
+ startTime
+u"\",\"endTime\":\""
+ endTime
+u"\"}"
Variables
Variable name | Variable value |
---|---|
sfCallCenterDevName | Contact Center Developer Name |
sfCertDevName | API Name of Certificate (as configured in Contact Center) |
sfVoiceCallRecordId | ID of the voice call record, created in a previous step |
startTime | |
endTime | D[now].toInstant().toString() |