
When integrating Computer Telephony Integration (CTI) with SAP Service Cloud Agent Desktop, ensuring that the required payloads are constructed and processed correctly is a critical step. This blog intents to walk you through creating a Proof of Concept (POC) widget designed to provide a clear and interactive way to validate payload structures and test the seamless integration of various common CTI scenarios.
It’s important to note that it is the responsibility of the customer and CTI integrators to create their own widgets and ensure that the correct payloads are sent to the parent window using the window.parent.postMessage() method. This is in line with the guidance provided in the Widget Integration SAP Help Online Documentation.
This approach applies universally—whether you are working with the Agent Desktop Add-On or the Stand-Alone Agent Desktop in Service Cloud V2, as well as with Live Activity in SAP Customer Cloud (C4C).
To System Integrators, we recommend considering the SAP CTI Certification Process to ensure compliance and compatibility. Would you like to know more about the SAP Certification Process? Please check out the Knowledge Base Article KBA 3307629 for detailed information.
The primary expectation is that CTI integrators will use this POC to understand the required parameters and payload formats, ultimately ensuring they meet the integration requirements. This POC demonstrates what payloads are expected, how they can be constructed, and how they integrate with SAP Service Cloud Agent Desktop.
By the end of this blog, you'll gain insights into:
Support for Multiple Interaction Types:
Easy Payload Customization:
Real-time Validation:
Extensible Design:
The widget provides fields for all interactions (CALL, CHAT, and MESSAGE), and all fields are displayed regardless of the selected interaction type. While not all fields are relevant for every interaction, you can selectively populate the fields needed for your scenario.
The payloads below follow the format and structure outlined in the SAP Help Portal Widget Integration Guide. These examples demonstrate how the widget generates XML payloads for common CTI interaction scenarios.
1. Notify (Inbound Call):
The NOTIFY action informs the system of an incoming phone call.
<payload>
<Type>CALL</Type>
<EventType>INBOUND</EventType>
<Action>NOTIFY</Action>
<ANI>+12345678910</ANI>
<ExternalReferenceID>ED4E4730D1C711EAAA5EBC019352B05E</ExternalReferenceID>
</payload>
2. Accept (Call Accepted by Agent):
The ACCEPT action indicates that the agent has accepted the call. Note that in some cases, when sending the the Action = ACCEPT does not work, then send action with null value. In the below example, the <Action> tag is left empty.
<payload>
<Type>CALL</Type>
<EventType>INBOUND</EventType>
<Action></Action>
<ANI>+12345678910</ANI>
<ExternalReferenceID>ED4E4730D1C711EAAA5EBC019352B05E</ExternalReferenceID>
</payload>
3. End (Call Concluded):
The END action marks the conclusion of the phone interaction.
<payload>
<Type>CALL</Type>
<EventType>UPDATEACTIVITY</EventType>
<Action>END</Action>
<ANI>+12345678910</ANI>
<ExternalReferenceID>ED4E4730D1C711EAAA5EBC019352B05E</ExternalReferenceID>
<RecordingId>REC_1234567890</RecordingId>
</payload>
4. Transfer (Call Transferred to Another Agent):
The TRANSFER event indicates that the call has been transferred.
<payload>
<Type>CALL</Type>
<EventType>TRANSFER</EventType>
<Action>NOTIFY</Action>
<ANI>+12345678910</ANI>
<ExternalReferenceID>ED4E4730D1C711EAAA5EBC019352B05E</ExternalReferenceID>
<ExternalOriginalReferenceID>ED4E4730D1C711EAAA5EBC019352B05F</ExternalOriginalReferenceID>
</payload>
1. Notify (New Chat Interaction):
The NOTIFY action notifies the system of a new chat interaction.
<payload>
<Type>CHAT</Type>
<EventType>INBOUND</EventType>
<Action>NOTIFY</Action>
<Email>Road.Runner@test.com</Email>
<ExternalReferenceID>ED4E4730D1C711EAAA5EBC019352B05E</ExternalReferenceID>
</payload>
2. Accept (Chat Interaction Accepted):
The ACCEPT action indicates that the chat has been accepted by the agent.
<payload>
<Type>CHAT</Type>
<EventType>INBOUND</EventType>
<Action></Action>
<Email>Road.Runner@test.com</Email>
<ExternalReferenceID>ED4E4730D1C711EAAA5EBC019352B05E</ExternalReferenceID>
</payload>
3. End (Chat Interaction Concluded):
The END action uploads the transcript and concludes the chat interaction.
<payload>
<Type>CHAT</Type>
<EventType>UPDATEACTIVITY</EventType>
<Action>END</Action>
<Email>mike.ross@test.com</Email>
<ExternalReferenceID>ED4E4730D1C711EAAA5EBC019352B05E</ExternalReferenceID>
<Transcript>
support@sap.com: Hello Mike
Road.Runner@test.com: Hello
Road.Runner@test.com: I need to book an appointment for fixing my washing machine
support@sap.com: Sure, will tomorrow 12.00 PM work for you?
Road.Runner@test.com: Yes, thanks! Bye.
support@sap.com: Bye.
</Transcript>
</payload>
1. Notify (New Message Interaction):
The NOTIFY action indicates that a new message has been received.
<payload>
<Type>MESSAGE</Type>
<EventType>INBOUND</EventType>
<Action>NOTIFY</Action>
<ANI>+12345678910</ANI>
<Text>This is SMS text</Text>
<ExternalReferenceID>77FB2990D24411EAAA5EBC019352B05E</ExternalReferenceID>
</payload>
2. Accept (SMS Acknowledged):
The ACCEPT action indicates that the SMS message has been acknowledged by the agent. Note that the <Action> tag is left empty.
<payload>
<Type>MESSAGE</Type>
<EventType>INBOUND</EventType>
<Action></Action>
<ANI>+12345678910</ANI>
<Text>This is SMS text</Text>
<ExternalReferenceID>77FB2990D24411EAAA5EBC019352B05E</ExternalReferenceID>
</payload>
3. End (SMS Interaction Concluded):
The END action marks the conclusion of the SMS interaction.
<payload>
<Type>MESSAGE</Type>
<EventType>UPDATEACTIVITY</EventType>
<Action>END</Action>
<ANI>+12345678910</ANI>
<Text>Thank you for your assistance!</Text>
<ExternalReferenceID>77FB2990D24411EAAA5EBC019352B05E</ExternalReferenceID>
</payload>
Before configuring the widget in SAP Service Cloud or SAP Customer Cloud (C4C), you need to ensure that the widget files (index.html, style.css, and script.js) are hosted on a web server that supports HTML hosting.
Choose a web server that supports hosting HTML, CSS, and JavaScript files. Examples include:
Upload the following files to the server:
Ensure that the files are publicly accessible via a URL. For example:
Test the widget by opening the URL in a browser to confirm that it loads correctly.
Once the files are hosted and accessible, proceed with the following configuration steps. The hosting step applies to all scenarios below.
Scenario 1: Agent Desktop in Service Cloud V2
Host the Widget Files:
Update the Content Security Policy (CSP):
Configure in SAP Service Cloud V2:
Test the Integration:
Host the Widget Files:
Configure in SAP Customer Cloud (C4C):
Access Agent Desktop Configuration:
Select Widget and Provider Configuration:
Enter Provider Details:
Validate Add-On Behavior:
Save the Configuration:
Test the Widget:
Host the Widget Files:
Configure for Live Activity:
Test Live Activity:
This POC is a simple but useful tool for SAP Service Cloud developers and testers to validate CTI integrations quickly and efficiently. By retaining all fields and providing flexibility in payload construction, this widget serves as a versatile testing framework for a variety of interaction types.
With the provided configuration steps, you can integrate the widget into multiple SAP platforms, including Service Cloud V2 and C4C, while also extending its functionality to new use cases like Live Activity.
Let us know how you’re using this POC to streamline your integration workflows. If you have questions about the SAP CTI Certification Process, make sure to refer to the SAP KBA 3307629 for additional guidance. 🚀
=================================================================================
Below is the complete code for the POC widget. You can copy and paste it into your own HTML, CSS, and JavaScript files. The widget consists of three main parts: index.html, style.css, and script.js.
1. index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Service Cloud Widget POC</title>
<meta name="author" content="Lloyd Goveia">
<meta name="description" content="Service Cloud Widget POC created by Lloyd Goveia. Provided AS IS with no support.">
<!-- Link to the external CSS file -->
<link rel="stylesheet" href="style.css">
<!-- Link to the external JavaScript file -->
<script defer src="script.js"></script>
</head>
<body>
<!-- Main form for the Service Cloud Widget -->
<form id="callForm" onsubmit="handleSendCall(event)">
<h1>Service Cloud Widget POC</h1>
<table>
<!-- Dropdown to select interaction type -->
<tr>
<td><label for="type">Type:</label></td>
<td>
<select id="type" name="type" required>
<option value="CALL">CALL</option>
<option value="CHAT">CHAT</option>
<option value="MESSAGE">MESSAGE</option>
</select>
</td>
</tr>
<!-- Dropdown to select event type -->
<tr>
<td><label for="eventType">Event Type:</label></td>
<td>
<select id="eventType" name="eventType" required>
<option value="INBOUND">INBOUND</option>
<option value="OUTBOUND">OUTBOUND</option>
<option value="UPDATEACTIVITY">UPDATEACTIVITY</option>
<option value="TRANSFER">TRANSFER</option>
</select>
</td>
</tr>
<!-- Dropdown to select action -->
<tr>
<td><label for="action">Action:</label></td>
<td>
<select id="action" name="action" required>
<option value="NOTIFY">NOTIFY</option>
<option value="ACCEPT">ACCEPT</option>
<option value="END">END</option>
</select>
</td>
</tr>
<!-- Phone number field -->
<tr>
<td><label for="ani">ANI (Phone Number):</label></td>
<td><input id="ani" name="ani" type="text" placeholder="+1234567890" value="+14165551234"></td>
</tr>
<!-- Email field -->
<tr>
<td><label for="email">Email:</label></td>
<td><input id="email" name="email" type="email" placeholder="example@test.com"></td>
</tr>
<!-- Subject field -->
<tr>
<td><label for="subject">Subject:</label></td>
<td><input id="subject" name="subject" type="text" placeholder="Enter subject"></td>
</tr>
<!-- Text field -->
<tr>
<td><label for="text">Text:</label></td>
<td><textarea id="text" name="text" placeholder="Enter text"></textarea></td>
</tr>
<!-- External Reference ID field -->
<tr>
<td><label for="externalReferenceID">External Reference ID:</label></td>
<td>
<input id="externalReferenceID" name="externalReferenceID" type="text">
<button type="button" onclick="generateRandomGUID('externalReferenceID')">Generate Random GUID</button>
</td>
</tr>
<!-- Call recording field -->
<tr>
<td><label for="recordingId">Call Recording:</label></td>
<td><input id="recordingId" name="recordingId" type="text"></td>
</tr>
<!-- Submit and Reset buttons -->
<tr>
<td colspan="2">
<button type="submit">Post Payload to Parent Window</button>
<button type="button" onclick="resetForm()">Reset Form</button>
</td>
</tr>
</table>
<!-- Section to display the generated XML payload -->
<div class="payload-message" id="payloadMessage"></div>
</form>
</body>
</html>
2. style.css
/* Style for the body of the widget */
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
/* Style for the form container */
form {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 600px;
}
/* Styling for the form header */
h1 {
text-align: center;
font-size: 1.5em;
}
/* Styling for input labels */
label {
font-size: 0.85em;
font-weight: bold;
margin-bottom: 5px;
display: block;
}
/* Styling for input, textarea, and dropdown fields */
input, textarea, select {
width: calc(100% - 10px);
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
/* Styling for buttons */
button {
padding: 6px 15px;
font-size: 0.85em;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
/* Hover effect for buttons */
button:hover {
background-color: #0056b3;
}
/* Styling for the payload display section */
.payload-message {
background-color: #e8e8e8;
color: #333;
padding: 10px;
margin-top: 15px;
border-radius: 4px;
font-size: 0.9em;
word-wrap: break-word;
}
3. script.js
// Define the global c4c object for CTI integration
var c4c = c4c || {};
c4c.cti = c4c.cti || {};
c4c.cti.integration = function () { };
/**
* Constructs an XML payload from form parameters
* {Object} parameters - Key-value pairs to include in the payload
* @returns {string} - XML payload as a string
*/
c4c.cti.integration.prototype._formXMLPayload = function (parameters) {
var sPayload = "<?xml version=\"1.0\" encoding=\"utf-8\"?><payload>";
Object.entries(parameters).forEach(([key, value]) => {
if (key === "Action" && value === "ACCEPT") {
value = ""; // Leave Action empty for ACCEPT
}
if (value && value.trim() !== "") {
sPayload += `<${key}>${value}</${key}>`;
}
});
sPayload += "</payload>";
console.log("Constructed Payload:", sPayload);
return sPayload;
};
/**
* Handles form submission and sends the payload to the parent window
* {Event} event - Form submission event
*/
function handleSendCall(event) {
event.preventDefault();
var parameters = {
Type: document.getElementById("type").value,
EventType: document.getElementById("eventType").value,
Action: document.getElementById("action").value,
ANI: document.getElementById("ani").value,
Email: document.getElementById("email").value || "",
Subject: document.getElementById("subject").value || "",
Text: document.getElementById("text").value || "",
ExternalReferenceID: document.getElementById("externalReferenceID").value || "",
RecordingId: document.getElementById("recordingId").value || ""
};
var integration = new c4c.cti.integration();
integration.sendIncomingCalltoC4C(parameters);
}
/**
* Generates a random GUID and assigns it to the specified field
* {string} fieldId - ID of the field to populate
*/
function generateRandomGUID(fieldId) {
var guid = crypto.randomUUID().replace(/-/g, '').toUpperCase().substring(0, 35);
document.getElementById(fieldId).value = guid;
}
/**
* Resets the form and clears displayed messages
*/
function resetForm() {
document.getElementById("callForm").reset();
document.getElementById("payloadMessage").innerText = "";
}
/**
* Displays the constructed XML payload
* {string} payload - XML payload to display
*/
function displayPayloadMessage(payload) {
var payloadDiv = document.getElementById("payloadMessage");
payloadDiv.innerText = payload;
payloadDiv.style.display = "block";
}
Demo:
https://sapvideo.cfapps.eu10-004.hana.ondemand.com/?entry_id=1_zu1o64u0
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
4 | |
2 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |