Receiving Chat webhooks

For each message sent from the Kommo interface to the chat channel, a webhook is sent to the specified address.

After receiving a webhook, you need to process it and send a message to the messenger. Webhook is sent only once and will not be sent again if the integration couldn’t process or receive it.

The response time to the webhook is limited, so we suggest to only check the request signature when receiving the webhook, and perform the business logic in the background outside the context of the request. For example, queue a task for processing and send a response to the webhook.

If you receive a message that the integrated messenger cannot accept, you need to update the message status to “error”.

Further, already in asynchronous mode, you process the message, produce your business logic and send the message.

Currently, we wait for a response to the webhook no more than 5 seconds. In order for us to consider the webhook successfully sent, your integration should respond to the request with a 200 http code.

The Chat API has prioritization mechanisms if the integration takes a long time to respond to hooks or does not respond at all, we can move it separately from the main message stream to a slow stream where hooks can arrive with a delay.

The priority is calculated dynamically and depends on various factors, the integration can go both to a faster queue and to a slower one.

The manager “typing” events require separate webhook subscriptions for each channel via tech support.

Webhook v2

Let’s analyze the webhook that Kommo sent you, and explain its method, authentication and the body.

Method

POST Your webhook url specified when registering the channel in the filed webhook_url

Description

This webhook is sent if the v2 was set when connecting the chat channel.

Headers & Authorization type

Each webhook contains an X-Signature header, which is calculated only from the request body using the HMAC-SHA1 method. The channel secret is used as a secret key, and this is how you can verify the authenticity of incoming webhooks.

To do this, you need to calculate the hash from the body of the incoming request and compare it with the one that comes in the X-Signature header.

PHP example
$secret = 'fb50586ff7b68cd831fe0ef356345903f644c0d2'; 
$str = file_get_contents('php://input'); 
$signature = hash_hmac('sha1', $str, $secret); 
if (isset($_SERVER['HTTP_X_SIGNATURE']) && $signature === $_SERVER['HTTP_X_SIGNATURE']	) 
{ 
   //The webhook is valid 
}

Example of the body

In cace of sending a text message
{
   "account_id": "52fd2a28-d2eb-4bd8-b862-b57934927b38",
   "time": 1670571014,
   "message": {
       "receiver": {
           "id": "9c2ccde3-a3ab-4695-832c-919dbfc598ea",
           "phone": "+18305803077",
           "email": "",
           "client_id": "b0bc49f0-ec21-4463-965f-1fe1d4cd5a90"
       },
       "sender": {
           "id": "b0bc49f0-ec21-4463-965f-1fe1d4cd5b89"
       },
       "conversation": {
           "id": "14723c64-c40d-4efc-9f78-9625adac414c",
           "client_id": "62ef74a4-80c5-403d-93d9-bada6302810d"
       },
       "timestamp": 1670571014,
       "msec_timestamp": 1670571014414,
       "message": {
           "id": "3419eef6-2aa3-464c-b6e4-4386d0f8f3ca",
           "type": "text",
           "text": "Hello Adam! \nLet's arrange a call for next week. ",
           "markup": null,
           "tag": "",
           "media": "",
           "thumbnail": "",
           "file_name": "",
           "file_size": 0
       }
   }
}
The Message body entity in case of sending a file
       "message": {
           "id": "8fe1174e-af30-4184-95a2-6ad193c95bca",
           "type": "file",
           "text": "Hello Adam\nI am sending you the prices. Please take a look.",
           "markup": null,
           "tag": "",
           "media": "https://amojo.kommo.com/attachments/52fd2a28-d2eb-4bd8-b862-a67934927b38/14723c64-c40d-4efc-9f78-9625adac414c/xjXgl_Prices-lists.odt",
           "thumbnail": "",
           "file_name": "Prices-lists.odt",
           "file_size": 9603
      }
The message entity with media in case of sending a markup
        "message": {
            "id": "8fe1174e-af30-4184-95a2-6ad193c95bca",
            "type": "picture",
            "text": "Conversation text #15926745",
            "markup": {
                "mode": "inline",
                "buttons": [
                    [
                        {
                            "text": "Confirm order"
                        },
                        {
                            "text": "Delete order"
                        }
                    ]
                ]
            },
            "tag": "",
            "media": "https://amojo.kommo.com/attachments/image.jpg",
            "thumbnail": "https://amojo.kommo.com/attachments/image_320x200.jpg",
            "file_name": "",
            "file_size": 0,
            "template": {
                "id": 7103,
                "external_id": "my_external_id",
                "content": "Conversation text {{lead.name}}",
                "params": [
                    {
                        "key": "{{lead.id}}",
                        "value": "15926745"
                    }
                ]
            }
        }

Body parameters

Optional fields may not come in the hook.

It is important to note that a message can arrive simultaneously with media, text, and buttons, and when sending multiple attachments at once, the message will be split into several hooks, but they will have a common message[message][media_group_id]

Parameter Data type Description
account_id string amojo account ID
time int Timestamp when generating the webhook in the format of Unix Timestamp
message object An array contains the message components. Description about the elements of the object.
Message entity
Parameter Data type Description
receiver object Message receiver. Description about the elements of the object.
sender[id] string Chat participant ID on the Chat API side
conversation object Conversation details. Description about the elements of the object.
timestamp int Message timestamp in the format of Unix Timestamp
msec_timestamp int Message timestamp in milliseconds
message object The content of the message. Description about the elements of the object.
Receiver entity
Parameter Data type Description
id string Chat participant ID on the integration side
phone string Phone number. The field is not returned if the profile wasn’t passed
email string Email address. The field is not returned if the profile wasn’t passed
client_id string Chat participant ID on the Chat API side
Conversation entity
Parameter Data type Description
id string Chat ID in the Chat API
client_id string Chat ID on the integration side
Message body entity
Parameter Data type Description
id string amojo ID of the message
type
required
string Message type, one of the following: text, file, video, picture, voice, audio, sticker
text string The field is mandatory for the “text” type, can be empty for other types
markup object The keyboard object to display with the message. Description about the elements of the object.
media string Url to the file, video, picture, voice, audio, or sticker.
thumbnail string Link to the preview picture or video thumbnail url.
file_name string The name of the file from the “media” field url
file_size int The size for the data in the “media” field
template object Template object, if the message was sent using a template. Description about the elements of the object.
Markup entity

The markup object is an array of arrays of buttons with the specified way to arrange them.

The location method is specified in the mode field. Currently, for integrations, an object’s mode always contains the value inline.

The inline value says that the keyboard should be below the message text.

At the moment, buttons of different types cannot come in the same object.

Parameter Data type Description
mode string Keyboard layout. Possible values: inline – buttons are displayed below the message text
button object Array of the button objects. Description about the elements of the object.
Markup buttons entity
Parameter Data type Description
text string Text. When a user clicks on a text button, the messenger should send a message with the text of this button to the chat
url string Link. When a user clicks on a link button, the messenger should follow that link. The property may be absent if a normal button is passed
Template entity
Parameter Data type Description
id string The template id in Kommo
content string The template text without interpreting the placeholders
params object An object of the placeholders. Details of the elements of the params object.
Template params entity
Parameter Data type Description
key string Key of the placeholder
value string Value of the placeholder
HTTP response codes

The address receiving this webhook must respond with a 200 http code, in which case we consider the hook to be successfully accepted.

Response code Condition
200 Webhook processed successfully

Typing webhook

The webhook is sent when the manager types a message in the Kommo interface.

The webhook is sent no more than once every 5 seconds.

Example of the body

{
   "account_id": "52fd2a28-d2eb-4bd8-b862-b57934927b38",
   "time": 1670585310,
   "action": {
       "typing": {
           "user": {
               "id": "b0bc49f0-ec21-4463-965f-1fe1d4cd5b89"
           },
           "conversation": {
               "id": "30477717-9f3c-4d3f-8101-60327e14dc48",
               "client_id": "62ef74a4-80c5-403d-93d9-bada6302810f"
           },
           "expired_at": 1670585315
       }
   }
}

Body parameters

Parameter Data type Description
account_id string amojo account ID
time int Timestamp when generating the webhook in the format of Unix Timestamp
action[user][id] string User ID who performs the writing in the Chat API
action[typing][conversation][id] string Chat ID in Chats API
action[typing][conversation][client_id] string Chat ID on the integration side. Optional field. If the chat was created using the “Write first” function, the field will be absent in the hook
action[typing][expired_at] int Timestamp when we think the user is no longer typing. We pass the typing end timestamp as the current print start time + 5 seconds
HTTP response codes

The address receiving this webhook must respond with a 200 http code, in which case we consider the hook to be successfully accepted.

Response code Condition
200 Webhook processed successfully

Finally, let’s see how we can disconnect a chat channel.

Webhook about a reaction

The webhook is triggered when the user reacts to a message or removes their reaction within the Kommo interface.

Body parameters

Parameter Data type Description
account_id string Chat API account ID
time int Webhook create time. Unix timestamp
action[reaction][message] object Object of the message. Details
action[reaction][user] object An object with information about the sender of the reaction. Details
action[reaction][conversation][id] string Chat ID in Chat API
action[reaction][conversation][client_id] string Chat ID on the integration side. Optional field. If the chat is created via the “Write first” Salesbot action, the field will not be in the webhook
action[reaction][type] string Event type: react, unreact
action[reaction][emoji] string Reaction provided by the user. Optional field. If the user removes the reaction, the field will not be in the webhook
Reaction message entity
Parameter Data type Description
id string Chat API message ID
client_id string Message ID on the integration side. Optional field. If the message was created on the Kommo side, the field will not be in the webhook
receiver object An object with information about the receiver of the message. Details
sender object An object with information about the sender of the message. Details
timestamp int Message create time, Unix timestamp
msec_timestamp int Message create time, Unix timestamp with milliseconds

Example of the request

{
    "account_id": "81ede28b-8952-4785-abe2-c8d93f5fcc7d",
    "time": 1637087558,
    "action": {
      "reaction": {
        "message":{
          "id": "a80fb604-9e04-4e1d-bee9-37c71924cd11",
          "client_id": "64ff3a9baeb11",
          "sender":{
            "id": "f1e4e02c-f502-4165-9377-8575c55c5ebd",
            "name": "John Smith",
            "phone": "+14255551212",
            "client_id": "14255551212"
          },
          "timestamp": 1694448283,
          "msec_timestamp": 1694448283000
        },
        "user": {
          "id": "fb0fb604-9e04-4e1d-bee9-37c71924cdc2"
        },
        "conversation": {
          "id": "f1e4e02c-f502-4165-9377-8575c55c5ebd",
          "client_id": "c7"
        },
        "type": "react",
        "emoji": "😍"
      }
    }
  }
  

HTTP response codes

The recipient address for this webhook must return a HTTP 200 status code as a response, at which point we consider the webhook to be successfully acknowledged.

Response code Condition
200 Webhook processed successfully