1. Introduction
  2. Sending messages
  3. Receiving messages
  4. Supported messages
  5. Control routing
    1. Mutation requests
      1. Hand-over
      2. Take-over
      3. Hand-back
    2. Command request
    3. Position request
    4. Reset request
    5. ChatId construction

TwoWay

TwoWay is an internal format which aims to solve some limitations of the traditional BusinessMessaging format. It is therefor the preferred way to connect to the router as an external party.

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 three 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

targetAdaptersInfo (only on receiving messages)

A list of target adapters to which the conversationMessages were sent

Field Description
adapterId The unique identifier of the targetadapter
adapterType The type corresponding to that identifier

Supported channels

Business Messaging channels

  • Apple Business Chat
  • WhatsApp
  • Line
  • Push
  • RCS
  • SMS
  • Viber
  • Google Business Messages
  • Twitter
  • Facebook Messenger
  • Instagram
  • MobilePush
  • Telegram Messenger

Custom channels

  • CXWebConversations
  • WebChatbot
  • Robin

Feature matrix (WIP)

Not all features are supported across all channels. Make sure to check this matrix before going live to prevent unexpected behaviour.

WhatsApp SMS Twitter Facebook Messenger Google business message RCS
Suggestions.Reply.Description x x v x x x
Suggestions.Reply.Media x x x v x x
Media.RichCard.Carousel x x x v v v

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",
            "createdOn": "2021-07-12T06:59:59.2158043+00:00"
        }
    ]
}
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",
            "createdOn": "2021-07-12T06:59:59.2158043+00:00"
        }
    ]
}
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",
            "createdOn": "2021-07-12T06:59:59.2158043+00:00"
        }
    ]
}
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",
        "createdOn": "2021-07-12T06:59:59.2158043+00:00"
    }]
}
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

{
    "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",
        "header": "My title",
        "body": "Select an option",
        "buttonTitle": "Options",
        "footer": "My footer",
        "mediaUri": "https://example.com/media.jpg",
        "buttons": [
            {
                "id": "1",
                "title": "list option 1"
            },
            {
                "id": "2",
                "title": "list option 2"
            }
        ],
        "id": "f3aeed9c-f8a2-4861-8827-dd7659675a7f",
        "direction": "ClientOriginated",
        "createdOn": "2021-07-12T06:59:59.2158043+00:00"
    }]
}
Field Description Required
header The displayed title for ABC (maximum of 40 characters), header for WA yes
body The displayed subtitle for ABC (maximum of 40 characters), body for WA yes
buttonTitle WA list button title, not used for ABC No
footer WA only, list footer yes for WA, no for ABC
mediaUri The media uri yes for ABC no for WA
buttons Array of button definitions, (maximum for WA of 10 buttons) yes
buttons.id Media uri for ABC and unique identifier for WA (maximum for WA of 200 characters) yes
buttons.title labels/list titles (maximum for WA of 24 characters) yes

Reply Buttons

{
    "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": "replyButton",
        "header": "My title",
        "body": "Select an option",
        "footer": "My footer",
        "buttons": [
            {
                "id": "1",
                "title": "option 1"
            },
            {
                "id": "2",
                "title": "option 2"
            }
        ],
        "id": "f3aeed9c-f8a2-4861-8827-dd7659675a7f",
        "direction": "ClientOriginated",
        "createdOn": "2021-07-12T06:59:59.2158043+00:00"
    }]
}
Field Description Required
header Header for reply button (maximum of 20 characters) no
body Body for reply button (maximum of 1024 characters) yes
footer Footer for reply button (maximum of 60 characters) no
buttons Array of button definitions, (maximum of 3 buttons) yes
buttons.id Id for button (maximum for WA of 256 characters) yes
buttons.title Titles for button (maximum of 20 characters) 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",
        "createdOn": "2021-07-12T06:59:59.2158043+00:00"
    }]
}
Field Description Required
url An url object yes
media A media object yes

Pass-through

{
    "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": "passthrough",
            "PassthroughMessageType": "WATemplate",
            "JsonContent" : {}
        }
    ]
}
Field Description Required
PassthroughMessageType Type for passthrough message, currently only WATemplate yes
JsonContent The json content to pass through yes