CRM and CX Blogs by SAP
Stay up-to-date on the latest developments and product news about intelligent customer experience and CRM technologies through blog posts from SAP experts.
cancel
Showing results for 
Search instead for 
Did you mean: 
lloyd_goveia
Product and Topic Expert
Product and Topic Expert
991

Introduction

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:

  • How to construct payloads for interactions like calls, chats, and messages.
  • How to push these payloads during integration testing with SAP Service Cloud Agent Desktop.
  • How to extend this POC for additional use cases, including Live Activity.

Key Features of the POC

  1. Support for Multiple Interaction Types:

  • Select the different variables to start building the payload.
  • Handles CALL, CHAT, and MESSAGE interaction types.
    • EventTypes like INBOUND, OUTBOUND, UPDATEACTIVITY, and TRANSFER.
    • Actions like Notify, Accept and END
  1. Easy Payload Customization:

    • XML payloads are automatically generated based on user inputs.
    • Fields like ANI, Email, Transcript, ExternalReferenceID and custom fields are included dynamically.
    • Option to Generate Random GUID (max of 35 characters, no hyphens or spaces and all in UPPERCASE)
    • Copy to Call Recording from previously generated GUID. This is typically the same when generated by many CTI providers.
  2. Real-time Validation:

    • Review payloads in real-time before sending them to the parent window.
  3. Extensible Design:

    • Easily add new fields or extend the payload structure for more complex use cases.

Using the POC

Screen.png



 

 

 

 

 



Interaction Types

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.

Event Types

  • INBOUND: For incoming interactions.
  • OUTBOUND: For outgoing interactions.
  • UPDATEACTIVITY: Used to update existing activities.
  • TRANSFER: Handles interaction transfers between agents.

Example Payloads

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.

Phone Call Payloads

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>

 

Chat Payloads

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>

 

Message Payloads

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>

 

Preparing the Widget for Use

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.

Step 1: Upload the Widget Files to a Web Server

  1. Choose a web server that supports hosting HTML, CSS, and JavaScript files. Examples include:

    • Apache
    • Nginx
    • IIS (Windows Server)
    • Any cloud-based static hosting service such as AWS S3, Azure Blob Storage, or Netlify.
  2. Upload the following files to the server:

    • index.html
    • style.css
    • script.js
  3. Ensure that the files are publicly accessible via a URL. For example:

  4. 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 

  1. Host the Widget Files:

    • Use the steps outlined above to ensure the files are hosted and accessible.
  2. Update the Content Security Policy (CSP):

  3. Configure in SAP Service Cloud V2:

    • Navigate to Administrator > General Settings > CTI Settings.
    • Enter the URL of the hosted widget in the Agent Desktop URL field.
  4. Test the Integration:

    • Open the Agent Desktop in Service Cloud V2 and interact with the widget.
    • Validate that payloads are sent and received correctly.

Scenario 2: Agent Desktop Add-On in C4C

  1. Host the Widget Files:

    • Follow the hosting steps outlined above.
  2. Configure in SAP Customer Cloud (C4C):

    1. Access Agent Desktop Configuration:

    2. Select Widget and Provider Configuration:

      • In the Configure Agent Desktop settings, click on Configure Widget and Provider.
    3. Enter Provider Details:

      • Provider Name: Enter the name of your communication provider (e.g., "Custom CTI Provider").
      • Provider ID: Assign a unique ID to the provider for identification purposes.
      • Provider URL: Input the URL where the widget is hosted (e.g., https://yourserver.com/path-to-widget/index.html).
      • Communication System ID: Specify the ID of the communication system being used.
  3. Validate Add-On Behavior:

    • Test interactions using the widget and confirm that the payloads are processed correctly within the Add-On.
  4. Save the Configuration:

    • Click Save to apply the provider configuration.
  5. Test the Widget:

    • Ensure that the widget loads correctly in the Agent Desktop by testing interactions such as inbound and outbound calls or chats.

Scenario 3: Live Activity in C4C

  1. Host the Widget Files:

    • Ensure the widget files are hosted on a secure server accessible to the C4C system.
  2. Configure for Live Activity:

    • In SAP Customer Cloud, go to Administrator > General Settings > Live Activity Configuration.
    • Provide the URL of the widget in the appropriate field for the Live Activity panel.
  3. Test Live Activity:

    • Initiate a Live Activity interaction and validate that the widget sends payloads correctly.

Conclusion

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. 🚀
=================================================================================

Full Code for the POC Widget

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";
}

 

How to Use This Code

  • Copy the respective code sections into three separate files: index.html, style.css, and script.js.
  • Follow the steps to configure the widget in SAP Service Cloud or SAP Customer Cloud (C4C).
  • Use the POC widget to validate your CTI payloads.

Demo:
https://sapvideo.cfapps.eu10-004.hana.ondemand.com/?entry_id=1_zu1o64u0 

3 Comments
Saurabh_Kabra
Participant
0 Kudos

Hi @lloyd_goveia ,

The demo video that you shared (https://video.sap.com/media/t/1_zu1o64u0) seems to be internal only. Can you pls share the publicly accessible URL?

Best
Saurabh

lloyd_goveia
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Surabh,

thanks for the heads up! It should be public now.

cheers,
LG

 

Saurabh_Kabra
Participant
0 Kudos

Dear @lloyd_goveia ,

Unfortunately, video is still not accessible. I tried accessing it using https://sapvideo.cfapps.eu10-004.hana.ondemand.com/?entry_id=1_zu1o64u0, and I was unable to load it. Can you pls check one more time?

FYI...https://video.sap.com/ is SAP internal only website.