{
  1. Introduction
  2. Sending messages
  3. Receiving messages
  4. Control routing
    1. Mutation requests
      1. Hand-over
      2. Take-over
      3. Hand-back
    2. Position request
    3. Reset request

TwoWay

TwoWay is an internal format which aims to solve some limitations of the traditional BusinessMessaging format. Parties that are allowed to use this format should be limited because TwoWay will eventually be replaced with the BusinessMessaging 2.0 format. Please note that the current status of the TwoWay adapter is alpha so some things may change.

Concepts and Terminology

  • Client: The client that initiates the conversation with the host
  • Host: The third party system that hosts the conversation. The host can be an automated system like a chatbot, customer service platform or any other third party that is interested in receiving messages from the client.
  • ClientOriginated: The message was sent by and thus originated from the client.
  • ClientTerminated: The message was sent by the host and should be terminated on the client.

Sending messages via TwoWay

Visit the bot configuration application and select a rule set in order to get your TwoWay url endpoint.

POST https://api.cm.com/conversational/twoway/v1/accounts/{BotRouterAccountId}/adapters/{AdapterId}

The webhook must return 201 Created to indicate it has received the message (and an error status code if it didn't). Please provide the exact address of this webhook to your CM.com contact.

Authentication

TwoWay requires the X-Cm-Producttoken header to be present on the request. The Business Messaging API documentation contains instructions on retrieval of this producttoken

Receiving messages via TwoWay

In order to receive messages from the bot router, you must implement a JSON webhook. This webhook needs to implement the TwoWay format.

Format

This format can be used for both sending and receiving messages. The TwoWay format consists of two properties

chat

Field Description Required
id The hash of the channel + from + to fields transposed to a guid yes
sessionId The unique identifier for the current session no
accountId The BotRouterAccountId yes
channel Specific protocol (WhatsApp, Apple Business Chat) being used for communication yes
conversationClientId The unique identifier of the client. Usualy a MSISDN but a longer hash in case of Apple Business Chat yes
conversationHostId The unique identifier for the third party system that hosts the conversation. Like the conversationClientId. This can be an MSISDN depending on the channel yes
conversationClientName The display name of the client's profile on the channel no

conversationMessages

A list of messages. TwoWay supports different types of messages but they all share the following properties

Field Description Required
id The unique identifier of the message yes
$type The type of message (Text, Media, Location). More types are described below yes
direction The direction the message is being send towards. ClientOriginated is used for MO messages (towards the client) while ClientTerminated is used for MT (towards the hosting third party) yes

Message types

Text

{
    "chat": {
        "id": "47e755ad-69a2-4139-a610-c53d0c8deb4b",
        "sessionId": "20210126185202",
        "accountId": "00000000-0000-0000-0000-000000000000",
        "channel": "WhatsApp",
        "conversationClientId": "+316012345678",
        "conversationHostId": "00316012345678",
        "conversationClientName": null
    },
    "conversationMessages": [
        {
            "$type": "text",
            "text": "Hi",
            "id": "28c477f4-4ffd-43c2-8149-52273ec83465",
            "direction": "ClientOriginated"
        }
    ]
}
Field Description Required
text The text message yes

Media

{
    "chat": {
        "id": "47e755ad-69a2-4139-a610-c53d0c8deb4b",
        "sessionId": "20210126185202",
        "accountId": "00000000-0000-0000-0000-000000000000",
        "channel": "WhatsApp",
        "conversationClientId": "+316012345678",
        "conversationHostId": "00316012345678",
        "conversationClientName": null
    },
    "conversationMessages": [
        {
            "$type": "media",
            "media": {
                "name": "Image name",
                "uri": "http://example.com/my-image.png",
                "mimeType": "image/jpeg"
            },
            "id": "f200b2f3-cd4e-404f-b7af-d36a3a010efc",
            "direction": "ClientOriginated"
        }
    ]
}
Field Description Required
media A media object yes

Location

{
    "chat": {
        "id": "47e755ad-69a2-4139-a610-c53d0c8deb4b",
        "sessionId": "20210126185202",
        "accountId": "00000000-0000-0000-0000-000000000000",
        "channel": "WhatsApp",
        "conversationClientId": "+316012345678",
        "conversationHostId": "00316012345678",
        "conversationClientName": null
    },
    "conversationMessages": [
        {
            "$type": "location",
            "location": {
                "latitude": 51.6035675548752,
                "longitude": 4.77079096460324,
                "label": "CM.com",
                "searchQuery": "Konijnenberg 30, Breda, Noord-Brabant 4825 BD"
            },
            "id": "a021106e-6414-4187-85c6-65b1ecc7c332",
            "direction": "ClientOriginated"
        }
    ]
}
Field Description Required
location A location object yes

Apple Pay

note: Only supported in Apple Business Chat

{
    "chat": {
        "id": "47e755ad-69a2-4139-a610-c53d0c8deb4b",
        "sessionId": "20210126185202",
        "accountId": "00000000-0000-0000-0000-000000000000",
        "channel": "WhatsApp",
        "conversationClientId": "+316012345678",
        "conversationHostId": "00316012345678",
        "conversationClientName": null
    },
    "conversationMessages": [{
        "$type": "applePay",
        "merchantName": "Merchant",
        "description": "Test payment",
        "orderReference": "733182a9-9ee3-40e9-81dc-12680df7555c",
        "recipientEmail": "[email protected]",
        "currencyCode": "eur",
        "recipientCountryCode": "nl",
        "languageCountryCode": null,
        "billingAddressRequired": true,
        "shippingContactRequired": false,
        "lineItems": [{
            "label": "My product",
            "type": "My type",
            "amount": 1.10
        }],
        "id": "6e131344-2a6d-487f-b9d2-020cdd7adb81",
        "direction": "ClientOriginated"
    }]
}
Field Description Required
merchantName The merchant name yes
description A description of the product or service being purchased yes
orderReference A reference for the product or service being purchased yes
recipientEmail The recipient's email address yes
currencyCode A 3 character code according t ISO 4217 yes
recipientCountryCode A 2 character code according to ISO 3166-1 Alpha 2 no
languageCountryCode A 2 character code according to ISO 639-1 Code no
billingAddressRequired Whether the billing address is required for this product or service yes
shippingContactRequired Whether shipping contact is required for this product or service yes
lineItems A list of LineItem objects yes

List picker

note: Not supported in whatsapp

{
    "chat": {
        "id": "47e755ad-69a2-4139-a610-c53d0c8deb4b",
        "sessionId": "20210126185202",
        "accountId": "00000000-0000-0000-0000-000000000000",
        "channel": "WhatsApp",
        "conversationClientId": "+316012345678",
        "conversationHostId": "00316012345678",
        "conversationClientName": null
    },
    "conversationMessages": [{
        "$type": "listPicker",
        "title": "My title",
        "subTitle": "Select an option",
        "mediaUri": "https://example.com/media.jpg",
        "options": {
            "MyOption1": "https://example.com/option1.jpg",
            "MyOption2": "https://example.com/option2.jpg"
        },
        "id": "f3aeed9c-f8a2-4861-8827-dd7659675a7f",
        "direction": "ClientOriginated"
    }]
}
Field Description Required
title The displayed title (maximum of 40 characters) yes
subTitle The displayed subtitle (maximum of 40 characters) yes
mediaUri The media uri yes
options An object where the keys will be displayed as labels and the values as media yes

Text with url

{
    "chat": {
        "id": "47e755ad-69a2-4139-a610-c53d0c8deb4b",
        "sessionId": "20210126185202",
        "accountId": "00000000-0000-0000-0000-000000000000",
        "channel": "WhatsApp",
        "conversationClientId": "+316012345678",
        "conversationHostId": "00316012345678",
        "conversationClientName": null
    },
    "conversationMessages": [{
        "$type": "textWithUrl",
        "text": "Example",
        "url": {
            "uri": "https://example.com/1",
            "label": "test"
        },
        "media": {
            "name": "test",
            "uri": "https://example.com/media.jpg",
            "mimeType": "image/jpg"
        },
        "id": "b5184cf0-39a7-4242-94df-c927b6073535",
        "direction": "ClientOriginated"
    }]
}
Field Description Required
url An url object yes
media A media object yes