WxCC Configuration and script to create Voice Call records
To get the full value of Salesforce Service Cloud Voice, the call flow in Webex Contact Center 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 about the used APIs, see Service Cloud Voice API Wrapper
Pre-requisites
Create Certificate
Ensure that you've already created a digital certificate as per your organization's security policy.
To generate a digital certificate, see the Salesforce documentation at https://developer.salesforce.com/docs/atlas.en-us.voice_pt_developer_guide.meta/voice_pt_developer_guide/voice_pt_generate_certificate.htm
Example
openssl genrsa -des3 -passout pass:<password> -out server.pass.key 2048
openssl rsa -passin pass:<password> -in server.pass.key -out server.key
rm server.pass.key
openssl req -new -key server.key -out server.csr
Country Name (2 letter code) [AU]:CH
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []: my-api-user@my-example-org.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:<password>
An optional company name []:
openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
server.crt => Certificate for the Salesforce Connected App
server.key => Private key for the Salesforce Connector in Webex Control Hub
Salesforce Connected App
In order to use the Service Cloud Voice API Wrapper, a Salesforce Connected App for IVR integration must be configured.
Configure the Salesforce Connector in Webex Control Hub
Set Up the Salesforce Integration Connectors for Webex Contact Center as described in the article at https://help.webex.com/en-us/article/7fuy63/Set-Up-Integration-Connectors-for-Webex-Contact-Center#id_133211
- Log in to your customer organization at https://admin.webex.com and navigate to Services > Contact Center > Connectors.
- On the Salesforce card, click Set Up or Add More.
- Client ID: Connected App Consumer Key (see Create a new Connected App, Step 5)
- Salesforce Email ID: Salesforce username of the "SCV Integration" (see SCV Integration User)
- URL: for production use https://login.salesforce.com or if you are setting up a dev/sandbox use https://test.salesforce.com
- Private Key: content of file
server.key(see Create Certificate)

If you click done, and the connector wont save
- Check to see if you have any spaces before/after your entries.
- Make sure that your Private key (
server.key) matches yourserver.crt. If you are setting up multiple org's and switch the certificates, they will not work. - make sure your Server.key starts with.
----- Begin RSA Private Key -----
Webex Contact Center Main Flow
Flow Variables
Flow variable for Vendor Call Key
Unique Id to identify the call. Required to create the Voice Call record.
Format: wxcc_<Interaction Id>
Example: wxcc_fc4ec7d8-4c91-49aa-b764-081fbba344a8
- Name:
SCV_VendorCallKey - Type: String
- Make Agent Viewable: Enabled
Flow variable for Voice Call record ID
Salesforce Voice Call Record Id
- Name:
SCV_VoiceCallRecordId - Type: String
- Make Agent Viewable: Enabled
- Agent Editable: Enabled
Flow variable for Voice Call record ID and Vendor Call Key (optional)
The record ID of the created Voice Call record and the Vendor Call Key are used in the agent connector to open the Voice Call when the call is answered by the agent. The variable name must be configured in the Contact Center definition in Salesforce.
The variable must contain the Voice Call record Id and Vendor Call Key, separated by a semicolon (;).
Format: <Voice Call record id>;<Vendor Call Key>
Example: 0LQ06000002KMNS;wxcc_fc4ec7d8-4c91-49aa-b764-081fbba344a8
- Name:
SCV_VoiceCallReference - Type: String
- Make Agent Viewable: Enabled
- Agent Editable: Enabled
Note: This variable is only required if your Contact Center does not have the field "Call Variable for the Vendor Call Key".
Local variable for the call start Time
Used to create the Voice Call record and when updating the voice call
- Name:
SCV_CallStartTime - Type: String
- Make Agent Viewable: no
Local variable for Queue name/id:
Returned by Execute Omni Flow, used for call routing.
This variable is only required when using Execute Omni Flow
- Name:
SCV_OmniFlowQueue - Type: String
- Make Agent Viewable: no
Local variable for Agent name/id:
Returned by Execute Omni Flow, used for call routing.
This variable is only required when using Execute Omni Flow
- Name:
SCV_OmniFlowAgent - Type: String
- Make Agent Viewable: no
Main Flow overview

- Generate Vendor Call Key
- Set Call Start Time
- HTTP Request: Create Voice Call record
- Evaluate HTTP Response for Create Voice Call record
- Error handling for Create Voice Call record
- (optional) Save Voice Call record Id and Vendor Call Key in variable
SCV_VoiceCallReference - HTTP Request: Execute Omni Flow
- Evaluate HTTP Response for Execute Omni Flow
- Error handling for Execute Omni Flow
- Continue with call routing
1. Generate Vendor Call Key
Every call handled in Service Cloud Voice creates a Voice Call record in Salesforce and requires a unique ID called Vendor Call Key. For Voice Call records created in WxCC, the Vendor Call Key must be defined in the WxCC Flow and then passed along with the call to the Agent using a Flow Variable.
The vendorCallKey value must comply with the following rules:
- The value must be <= 255 characters long.
- The value can include alphanumeric characters plus the underscore (_), dash (-), and period (.).
- The value must begin with a letter, not include spaces, not end with an underscore, and not contain two consecutive underscores.
- Label: Generate_VendorCallKey
- Variable: SCV_VendorCallKey
- Variable Value - Set Value:
wxcc_{{NewPhoneContact.InteractionId}}
2. Set Call Start Time
UTC timestamp of the call start time. This timestamp is used to create the Voice Call record and to update the Voice Call record if the caller hangs up before being routed to the agent.
- Label: SetCallStartTime
- Variable: SCV_CallStartTime
- Variable Value - Set Value:
{{now() | replace({'[UTC]': ''})}}
3. HTTP Request: 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 variable, together with the Vendor Call Key. Configure the used variable in the Contact Center configuration in Service Cloud Voice.
HTTP Request Settings
- Label: CreateVoiceCall
- Use Authenticated Endpoint: Enabled
- Connector: <Salesforce Connector created in the previous step>
- Request Path:
/services/apexrest/cnxscv/voice/v1/createVoiceCall - Method: POST
- Request Content Type: Application/JSON
Request Body
When creating the Voice Call record, you can also update 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:
{
"callCenterDevName": "<Contact Center API name>",
"certDevName": "<cert dev name>",
"vendorCallKey": "{{SCV_VendorCallKey}}",
"to": "{{NewPhoneContact.DNIS}}",
"from": "{{NewPhoneContact.ANI}}",
"initiationMethod": "Inbound",
"startTime": "{{SCV_CallStartTime}}",
"participants": [
{
"participantKey": "{{NewPhoneContact.ANI}}",
"type" : "END_USER"
}
]
}
Example with updating custom fields on the Voice Call record:
{
"callCenterDevName": "<Contact Center API name>",
"certDevName": "<cert dev name>",
"vendorCallKey": "{{SCV_VendorCallKey}}",
"to": "{{NewPhoneContact.DNIS}}",
"from": "{{NewPhoneContact.ANI}}",
"initiationMethod": "Inbound",
"startTime": "{{SCV_CallStartTime}}",
"participants": [
{
"participantKey": "{{NewPhoneContact.ANI}}",
"type" : "END_USER"
}
],
"callAttributes": "{\"custfield1__c\": \"<value1>\",\"custfield2__c\": \"<value2>\",\"custfield3__c\": \"<value3>\"}"
}
Parameters
| Property name | Value |
|---|---|
| callCenterDevName | Contact Center Developer Name |
| certDevName | API Name of Certificate (as configured in Contact Center) |
| vendorCallKey | Unique call id: {{SCV_VendorCallKey}} |
| to | CalledNumber/DNIS: {{NewPhoneContact.DNIS}} |
| from | CallingNumber/ANI: {{NewPhoneContact.ANI}} |
| startTime | UTC timestamp {{SCV_CallStartTime}} (to be set right after the call is accepted in the script) |
| callAttributes | Represents additional standard and custom fields in the voice call record, where each key-value pair corresponds to a standard or custom field and its values. Example: custfield1__c, custfield2__c, custfield3__c: API name of custom field on Voice Call object value1, value2, value3: Value for the custom field |
Parse Settings
- Content Type: JSON
- Output Variable: SCV_VoiceCallRecordId
- Path Expression:
$.data.voiceCallId
Voice Call record id, to be passed to the agent.
4. Evaluate HTTP Response for Create Voice Call record
Check the HTTP Status of the Create Voice Call http request
- Label: statusCodeCreateVoiceCall
- Variable: CreateVoiceCall.httpStatusCode
If status code == 200 => successful else => request failed, error handling
5. Error handling for Create Voice Call record
For demo / debug only, play message depending on http status code.
If Create Voice Call was successful, continue with Execute Omni Flow. Otherwise, continue with call routing.
6. Save Voice Call record Id and Vendor Call Key in Flow variable (optional step)
Concatenate Voice Call record Id and Vendor Call Key and store the value in the SCV_VoiceCallReference variable.
- Label: Prepare_VoiceCallReference
- Variable: SCV_VoiceCallReference
- Variable Value - Set Value:
{{SCV_VoiceCallRecordId}};{{SCV_VendorCallKey}}
Note: This step is only required if your Contact Center does not have the field "Call Variable for the Vendor Call Key".
7. HTTP Request: Execute Omni Flow (optional step)
Use 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. See Webex Contact Center Event Flow
HTTP Request Settings
- Label: ExecuteOmniFlow
- Use Authenticated Endpoint: Enabled
- Connector: <Salesforce Connector created in the previous step>
- Request Path:
/services/apexrest/cnxscv/voice/v1/executeOmniFlow - Method: POST
- Request Content Type: Application/JSON
Request Body
Apart from the required fields, you can 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.
Example with Omni-Flow parameters:
{
"callCenterDevName": "<Contact Center API name>",
"certDevName": "<cert dev name>",
"voiceCallId": "{{SCV_VoiceCallRecordId}}",
"dialedNumber": "{{NewPhoneContact.DNIS}}",
"flowDevName": "<flow api name>",
"fallbackQueue": "<fallback queue name>"
}
Example with updating the custom fields on Voice Call record:
{
"callCenterDevName": "<Contact Center API name>",
"certDevName": "<cert dev name>",
"voiceCallId": "{{SCV_VoiceCallRecordId}}",
"dialedNumber": "{{NewPhoneContact.DNIS}}",
"flowDevName": "<flow api name>",
"fallbackQueue": "<fallback queue name>",
"flowInputParameters":
{
"param1": "value1",
"param2": "value2"
}
}
Parameters
| Property name | Value |
|---|---|
| callCenterDevName | Contact Center Developer Name |
| certDevName | API Name of Certificate (as configured in Contact Center) |
| voiceCallId | ID of the voice call record, created in the previous step: {{SCV_VoiceCallRecordId}} |
| dialedNumber | CalledNumber/DNIS: {{NewPhoneContact.DNIS}} |
| flowDevName | Developer name of the Omni-Flow to execute |
| fallbackQueue | Queue ID or Queue API name of the fallback Salesforce queue |
| flowInputParameters | Additional inputs to the Omni-Channel flow (key-value pair). Example: param1, param2: Name of the Omni-Flow input parameter value1, value2: Value for the parameter |
Parse Settings
Queue
- Content Type: JSON
- Output Variable: SCV_OmniFlowQueue
- Path Expression:
$.data.queue
"Queue" returned from Execute Omni-Flow, can be used for routing
Agent
- Content Type: JSON
- Output Variable: SCV_OmniFlowAgent
- Path Expression:
$.data.agent
"Agent" returned from Execute Omni-Flow, can be used for routing
8. Evaluate HTTP Response for Execute Omni Flow
Check the HTTP Status of the Execute Omni Flow http request
- Label: statusCodeExecuteOmniFlow
- Variable: ExecuteOmniFlow.httpStatusCode
If status code == 200 => successful else => request failed, error handling
9. Error handling for Execute Omni Flow
For demo / debug only, play message depending on http status code.
If Execute Omni Flow was successful, variables SCV_OmniFlowQueue and SCV_OmniFlowAgent are not set. Routing decision in call flow.
Continue with call routing.
10. Continue with call routing
Continue in call flow, route call to agent. Optional, use SCV_OmniFlowQueue and SCV_OmniFlowAgent to select queue and agent.
Webex Contact Center Event Flow
If the caller hangs the call up before it is answered by an agent, we must 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

- PhoneContactEnded - This event is triggered when a live call is disconnected, and all participants are removed.
- HTTP Request: Clear Routing
- HTTP Request: Update Voice Call
HTTP Request: Clear Routing
- Label: ClearRouting
- Use Authenticated Endpoint: Enabled
- Connector: <Salesforce Connector created in the previous step>
- Request Path:
/services/apexrest/cnxscv/voice/v1/clearRouting - Method: POST
- Request Content Type: Application/JSON
Request Body
{
"callCenterDevName": "<Contact Center API name>",
"certDevName": "<cert dev name>",
"voiceCallId": "{{SCV_VoiceCallRecordId}}"
}
Parameters
| Property name | Value |
|---|---|
| callCenterDevName | Contact Center Developer Name |
| certDevName | API Name of Certificate (as configured in Contact Center) |
| voiceCallId | ID of the voice call record, created in the previous step: SCV_VoiceCallRecordId |
Parse Settings
none
HTTP Request: Update Voice Call
- Label: UpdateVoiceCall
- Use Authenticated Endpoint: Enabled
- Connector: <Salesforce Connector created in the previous step>
- Request Path:
/services/apexrest/cnxscv/voice/v1/updateVoiceCall - Method: POST
- Request Content Type: Application/JSON
Request Body
{
"callCenterDevName": "<Contact Center API name>",
"certDevName": "<cert dev name>",
"voiceCallId": "{{SCV_VoiceCallRecordId}}",
"startTime": "{{SCV_CallStartTime}}",
"endTime": "{{now() | replace({'[UTC]': ''})}}",
"disconnectReason": { "value": "Abandoned in queue", "isError": true }
}
Parameters
| Property name | Value |
|---|---|
| callCenterDevName | Contact Center Developer Name |
| certDevName | API Name of Certificate (as configured in Contact Center) |
| voiceCallId | ID of the voice call record, created in the previous step: SCV_VoiceCallRecordId |
| startTime | UTC timestamp of call start {{SCV_CallStartTime}} (as used to create the Voice Call record) |
| endTime | Current UTC timestamp `{{now() |
| disconnectReason | Reason for disconnecting the call. The property isError needs to be set to true for it to display properly. |
Parse Settings
none
Reference
Create a Private Key and Self-Signed Digital Certificate
Configure Connected App for Webex Contact Center Salesforce Connector
Set Up Integration Connectors for Webex Contact Center - Salesforce
Cisco Webex Contact Center Setup and Administration Guide > Flow Designer