Recebendo Webhooks de Chat

Para cada mensagem enviada da interface Kommo para o canal de chat, um webhook é enviado para um endereço especificado. Ao receber um webhook, é crucial processá-lo e enviar a mensagem para o mensageiro.

📘

Cada webhook é enviado apenas uma vez; se a integração falhar ao processá-lo ou recebê-lo, ele não será reenviado.

O tempo de resposta para o webhook é limitado, portanto, recomenda-se verificar imediatamente a assinatura da solicitação ao recebê-la e lidar com a lógica de negócios em segundo plano. Por exemplo, você pode colocar a tarefa em uma fila para processamento e responder prontamente ao webhook.

Se uma mensagem não puder ser aceita pelo mensageiro integrado, você deve atualizar seu status para Erro. Em seguida, em modo assíncrono, você pode processar a mensagem, executar sua lógica de negócios e enviar a mensagem conforme necessário.

📘

Atualmente, a janela de resposta para o webhook é de no máximo 5 segundos. Para que o webhook seja considerado enviado com sucesso, sua integração deve responder com um código HTTP 200.

A API de Chat utiliza mecanismos de priorização; se a integração demorar muito para responder ou falhar, ela poderá ser movida para um fluxo mais lento, resultando em atrasos na entrega do webhook. Essa prioridade é calculada dinamicamente com base em vários fatores, permitindo que a integração mude entre filas mais rápidas e mais lentas conforme necessário.

Além disso, eventos de “digitando” do gerente exigem assinaturas separadas de webhook para cada canal, que podem ser organizadas por meio do Suporte Técnico.

Webhook v2

A Kommo envia webhooks quando uma mensagem é enviada. Para recebê-los, você precisa especificar um URL de webhook no campo "webhook_url" ao registrar um canal.

Cada webhook contém um cabeçalho X-Signature, gerado a partir do corpo da solicitação usando o método HMAC-SHA1. O segredo do canal serve como a chave secreta, permitindo que você verifique a autenticidade dos webhooks recebidos.

Para fazer isso, calcule o hash do corpo da solicitação recebida e compare-o com o valor no cabeçalho X-Signature.

Enviando uma mensagem

{ "account_id": "XXXXXXXX-d2eb-4bd8-b862-b57934927b38", "time": 1670571014, "message": { "receiver": { "id": "XXXXXXXX-a3ab-4695-832c-919dbfc598ea", "name": "Diego", "phone": "+123456789", "email": "example@gmail.com", "client_id": "XXXXXXXX-ec21-4463-965f-1fe1d4cd5a90" }, "sender": { "id": "XXXXXXX-ec21-4463-965f-1fe1d4cd5b89", "name": "Gerente" }, "conversation": { "id": "XXXXXXXX-c40d-4efc-9f78-9625adac414c", "client_id": "XXXXXXX-80c5-403d-93d9-bada6302810d" }, "source": { "external_id": "ChatSourceId" }, "timestamp": 1670571014, "msec_timestamp": 1670571014414, "message": { "id": "XXXXXXXX-2aa3-464c-b6e4-4386d0f8f3ca", "type": "text", "text": "Olá João! Vamos agendar uma chamada semana que vem", "markup": null, "tag": "", "media": "", "thumbnail": "", "file_name": "", "file_size": 0 } } }
{ "account_id": "XXXXXXXX-d75c-4ee0-a443-9adbb902f98d", "time": 1730732453, "message": { "receiver": { "id": "XXXXXXX-1bc4-457f-b941-9b699c958165", "name": "Diego", "phone": "+1234567890", "client_id": "XXXXXXX-d95e-121212-3c0eeea9d897" }, "sender": { "id": "XXXXXXXXX-fadd-4995-8026-36fcc0c806bd", "name": "Nick" }, "source": { "external_id": "chatapi2externalid" }, "conversation": { "id": "XXXXXXXXX-4ccc-48a5-8bf3-68fed3cc74ba", "client_id": "12-122131" }, "timestamp": 1730732453, "msec_timestamp": 1730732453229, "message": { "id": "XXXXXXXXXXX-2d28-4853-baec-5f8f7e5e4f8a", "type": "picture", "text": "", "markup": null, "tag": "", "media": "https://drive-g.kommo.com/download/XXXXXXXX-fc00-5826-901a-6c9c06f128f0/1261ee39-232a-4433-a245-00b29ffbca97/a521d24e-52c2-4f99-9a3b-7741567f0529/Screenshot-1.png", "thumbnail": "https://drive-g.kommo.com/download/XXXXXXXX-fc00-5826-901a-6c9c06f128f0/1261ee39-232a-4433-a245-00b29ffbca97/a521d24e-52c2-4f99-9a3b-7741567f0529/13fcba3b-d8c2-4ac9-b2b0-270a1a9f5671/Screenshot-1_320_130.png", "file_name": "Screenshot_1.png", "file_size": 24246 } } }
{ "account_id": "XXXXXX-d75c-4ee0-a443-9adbb902f98d", "time": 1730734321, "message": { "receiver": { "id": "XXXXXX-1bc4-457f-b941-9b699c958165", "name": "Diego", "phone": "+18305803077", "client_id": "XXXXXXXX-d95e-121212-3c0eeea9d897" }, "sender": { "id": "XXXXXXXX-fadd-4995-8026-36fcc0c806bd", "name": "Nick" }, "source": { "external_id": "chatapi2externalid" }, "conversation": { "id": "XXXXXXXX-4ccc-48a5-8bf3-68fed3cc74ba", "client_id": "XXXXXXX-adlw23d21-sad21d-221svr" }, "timestamp": 1730734321, "msec_timestamp": 1730734321314, "message": { "id": "XXXXXXX-81b4-4880-9f39-c890a1c011a9", "type": "picture", "text": "Olá João! Como você está?", "markup": { "mode": "inline", "buttons": [ [ { "text": "Fine!" } ], [ { "text": "I'm fine" } ] ] }, "tag": "", "media": "https://drive-g.kommo.com/download/XXXXXXX-fc00-5826-901a-6c9c06f128f0/b4b1fc59-1825-48af-b378-ab433aa7f53a/9c882236-6825-4269-a527-b11534f8561b/Screenshot-1.png", "thumbnail": "https://drive-g.kommo.com/download/XXXXXXXX-fc00-5826-901a-6c9c06f128f0/b4b1fc59-1825-48af-b378-ab433aa7f53a/9c882236-6825-4269-a527-b11534f8561b/0c349685-3a7c-4e16-91b1-114eb93ccd3b/Screenshot-1_320_130.png", "file_name": "picture.png", "file_size": 24249, "template": { "id": 34788, "content": "Olá {{contact.name}}! Como você está?", "params": [ { "key": "{{contact.name}}", "value": "John" } ] } } } }
{ "account_id": "XXXXXXXX-d75c-4ee0-a443-9adbb902f98d", "time": 1730742708, "message": { "receiver": { "id": "XXXXXXXX-1bc4-457f-b941-9b699c958165", "name": "Diego", "phone": "+18305803077", "client_id": "XXXXXXXX-d95e-121212-3c0eeea9d897" }, "sender": { "id": "XXXXXXXXX-fadd-4995-8026-36fcc0c806bd", "name": "Nick" }, "source": { "external_id": "chatapi2externalid" }, "conversation": { "id": "XXXXXXX-4ccc-48a5-8bf3-68fed3cc74ba", "client_id": "XXXXXXX-adlw23d21-sad21d-221svr" }, "timestamp": 1730742708, "msec_timestamp": 1730742708539, "message": { "id": "XXXXXXXX-628c-41ac-bdaa-a26b0372c27a", "type": "text", "text": "Olá!", "markup": null, "tag": "", "media": "", "thumbnail": "", "file_name": "", "file_size": 0, "reply_to": { "message": { "id": "XXXXXXXX-832f-413b-b3f8-019fa2a5d274", "msgid": "XXXXXXX-2sd21we12-f45665432", "type": "text", "text": "Hi!", "timestamp": 1730367735, "msec_timestamp": 1730367735000, "sender": { "id": "XXXXXX-1bc4-457f-b941-9b699c958165", "name": "John", "phone": "+18305803077", "client_id": "XXXXXXXX-d95e-121212-3c0eeea9d897" } } } } } }
{ "account_id": "52e591f7-c98f-4255-8495-827210138c81", "time": 1639572261, "message": { "receiver": { "id": "2ed64e26-70a1-4857-8382-bb066a076219", "phone": "79161234567", "email": "example.client@example.com", "client_id": "my_int-1376265f-86df-4c49-a0c3-a4816df41af8" }, "sender": { "id": "76fc2bea-902f-425c-9a3d-dcdac4766090" }, "conversation": { "id": "8e4d4baa-9e6c-4a88-838a-5f62be227bdc", "client_id": "my_int-d5a421f7f218" }, "source": { "external_id": "78001234567" }, "timestamp": 1639572260, "msec_timestamp": 1639572260980, "message": { "id": "0371a0ff-b78a-4c7b-8538-a7d547e10692", "type": "text", "text": "Lead #15926745 Texto da mensagem", "markup": { "list_message": { "header": "Que tipo de serviço você deseja receber?", "body": "Por favor, selecione uma das opções de resposta no menu clicando no botão abaixo.", "footer": "Atenciosamente, Empresa Teste", "button": "Serviços", "sections": [ { "title": "Serviços disponíveis", "rows": [ { "callback_data": "vG9ujre8N7", "title": "Serviço 1", "description": "Descrição do Serviço 1" } ] } ] } } } } }

Parâmetros do corpo do webhook

📘

Uma mensagem pode ser recebida junto com mídia, texto e botões simultaneamente. Quando vários anexos são enviados de uma vez, a mensagem será dividida em vários webhooks, mas todos compartilharão um message[message][media_group_id] comum.

ParâmetroTipo de dadoDescrição
account_idstringID da conta amojo
timeintTimestamp ao gerar o webhook no formato de Unix Timestamp
messageobjUm array contém os componentes da mensagem.

message

ParâmetroTipo de dadoDescrição
receiverobjReceptor da mensagem
senderobjRemetente da mensagem
conversationobjDetalhes da conversa
sourceobjInformações da origem do chat
timestampintTimestamp da mensagem no formato de Unix Timestamp
msec_timestampintTimestamp da mensagem em milissegundos
messageobjO conteúdo da mensagem

message.receiver

ParâmetroTipo de dadoDescrição
idstringID do participante do chat no lado da integração
namestringNome do participante do chat no lado da API de Chats
phonestringNúmero de telefone. O campo não é retornado se o perfil não foi passado
emailstringEndereço de e-mail. O campo não é retornado se o perfil não foi passado
client_idstringID do participante do chat no lado da API de Chats

message.sender

ParâmetroTipo de dadoDescrição
idstringID do participante do chat no lado da integração
namestringNome do participante do chat no lado da API de Chats

message.conversation

ParâmetroTipo de dadoDescrição
idstringID do chat na API de Chats
client_idstringID do chat no lado da integração

message.source

ParâmetroTipo de dadoDescrição
external_idstringID da origem do chat no lado da integração

message.message

ParâmetroTipo de dadoDescrição
idstringID amojo da mensagem
typestringTipo de mensagem, um dos seguintes: texto, arquivo, vídeo, imagem, voz, áudio, adesivo
textstringO campo é obrigatório para o tipo “text”, podendo estar vazio para outros tipos
markupobjO objeto de teclado para exibição com a mensagem
mediastringURL para o arquivo, vídeo, imagem, voz, áudio ou adesivo
thumbnailstringLink para a imagem de pré-visualização ou miniatura do vídeo
file_namestringNome do arquivo do campo de URL “media”
file_sizeintTamanho dos dados no campo “media”
templateobjObjeto de modelo, se a mensagem foi enviada usando um modelo
reply_toobjObjeto de mensagem de resposta
forwardsarr of objObjeto de mensagem encaminhada

message.message.markup

O objeto de marcação consiste em uma matriz de matrizes de botões organizados em um layout especificado

O método de organização é indicado no campo mode. Atualmente, para integrações, esse campo sempre contém o valor "inline".

O valor "inline" indica que o teclado deve ser posicionado abaixo do texto da mensagem.

Neste momento, botões de diferentes tipos não podem ser incluídos no mesmo objeto.

ParâmetroTipo de dadoDescrição
modestringLayout do teclado. Valor possível:" inline".
buttonobjMatriz de objetos botoes
list_messageobjObjeto de mensagem do tipo WhatsApp List. Estrutura do objeto de mensagem de lista

message.message.markup.buttons

ParâmetroTipo de dadoDescrição
textstringTexto. Quando um usuário clica em um botão de texto, o mensageiro deve enviar uma mensagem com o texto desse botão para o chat.
buttonobjLink. Quando um usuário clica em um botão de link, o mensageiro deve seguir esse link. A propriedade pode estar ausente se outro tipo de botão for passado.

message.message.markup.list_message

ParâmetroTipo de dadoDescrição
headerstringTítulo da mensagem. Uma string de até 60 caracteres (suporta emojis).
bodystringCorpo da mensagem. Uma string de até 1024 caracteres (suporta emojis e Markdown).
footerstringRodapé da mensagem. Uma linha de até 60 caracteres (suporta emojis, links e Markdown).
buttonstringNome do botão principal que será exibido ao usuário; ao clicar nesse botão, um menu com as seções transferidas é aberto.
sectionsarrayUm array de objetos (1 a 10 elementos) descrevendo elementos interativos (seções).
sections[0]objectUm objeto descrevendo uma seção interativa.
sections[0][title]stringNome da seção. Uma string de até 24 caracteres.
sections[0][rows]arrayUm array de objetos (1 a 10 elementos) descrevendo botões individuais na seção.
sections[0][rows][0]objectUm objeto que descreve um único botão em uma seção.
sections[0][rows][0][callback_data]stringUm identificador único a ser passado para o WhatsApp e enviado com o botão selecionado pelo usuário na propriedade callback_data do objeto da mensagem.
sections[0][rows][0][title]stringNome do botão
sections[0][rows][0][description]stringDescrição do botão

message.message.template

ParâmetroTipo de dadoDescrição
idstringID do modelo na Kommo
contentstringO texto do modelo sem interpretar os espaços reservados
paramsobjUm objeto dos espaços reservados

message.message.template.params

ParâmetroTipo de dadoDescrição
keystringChave do espaço reservado
valuestringValor do espaço reservado

message.message.reply_to

ParâmetroTipo de dadoDescrição
messageobjObjeto de mensagem de resposta. Descrição do objeto de mensagem incorporada

message.message.reply_to.message (mensagem incorporada)

ParâmetroTipo de dadoDescrição
idintO ID da mensagem citada na API de Chats. Se passado, os demais campos não precisam ser preenchidos, pois serão determinados automaticamente. Em caso de passagem do ID, o deslocamento para a mensagem também funcionará se o chat estiver no mesmo cartão.
msgidintO ID da mensagem citada no lado da integração. Se passado, os demais campos não precisam ser preenchidos, pois serão determinados automaticamente. Em caso de passagem do ID, o deslocamento para a mensagem também funcionará se o chat estiver no mesmo cartão.
typestringObrigatório se nenhum ID for passado. O tipo de mensagem pode ser um dos seguintes: texto, contato, arquivo, vídeo, imagem, áudio, voz, adesivo, localização.
textstringObrigatório para o tipo “texto” se nenhum ID for passado. Para outros tipos de mensagens, pode estar vazio.
file_namestringOpcional. Nome do arquivo
file_sizeintOpcional. Tamanho do arquivo em bytes
media_durationintOpcional. Duração para mensagens de vídeo/áudio/voz
locationobjCampo obrigatório para mensagens do tipo localização
location[lon]floatLongitude
location[lat]floatLatitude
senderobjInformações do remetente da mensagem. Descrição do objeto de remetente

message.message.reply_to.message.sender (usuário incorporado)

ParâmetroTipo de dadoDescrição
idstringID do remetente no lado da integração; se passado, os demais campos não precisam ser preenchidos, pois serão determinados automaticamente.
ref_idstringID do remetente na API de Chats; se passado, os demais campos não precisam ser preenchidos, pois serão determinados automaticamente.
namestringObrigatório se nenhum ID for passado. Nome do remetente

Webhook de digitação

O webhook é enviado quando o gerente digita uma mensagem na interface da Kommo.

📘

O webhook é enviado no máximo uma vez a cada 5 segundos.

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

Parâmetros do corpo

ParâmetroTipo de dadoDescrição
account_idstringID da conta amojo
timeintCarimbo de data/hora ao gerar o webhook no formato de Carimbo de data/hora Unix
action[typing][user][id]stringID do usuário que executa a escrita na API de bate-papo
action[typing][conversation][id]stringID do bate-papo na API de bate-papo
action[typing][conversation][client_id]stringCampo opcional. ID do bate-papo no lado da integração. Se o bate-papo foi criado usando a função escrever primeiro, o campo estará ausente no gancho
action[typing][expired_at]intCarimbo de data/hora em que achamos que o usuário não está mais digitando. Passamos o carimbo de data/hora do final da digitação como o horário atual de início da impressão + 5 segundos

Webhook de reação

O webhook é acionado quando o usuário reage a uma mensagem ou remove sua reação na interface Kommo.

{ "account_id": "XXXXXX-8952-4785-abe2-c8d93f5fcc7d", "time": 1637087558, "action": { "reaction": { "message":{ "id": "XXXXXXX-9e04-4e1d-bee9-37c71924cd11", "client_id": "64ff3a9baeb11", "sender":{ "id": "XXXXX-f502-4165-9377-8575c55c5ebd", "name": "Diego", "phone": "+123456789", "client_id": "14255551212" }, "timestamp": 1694448283, "msec_timestamp": 1694448283000 }, "user": { "id": "XXXXXX-9e04-4e1d-bee9-37c71924cdc2" }, "conversation": { "id": "XXXXXXXX-f502-4165-9377-8575c55c5ebd", "client_id": "c1234456" }, "type": "react", "emoji": "😍" } } }

Parâmetros do corpo

ParâmetroTipo de dadoDescrição
account_idstringID da conta da API de bate-papo
timeintHora de criação do webhook no formato de Carimbo de data/hora Unix
action[reaction][message][id]stringID da mensagem da API de bate-papo
action[reaction][message][client_id]stringCampo opcional. ID da mensagem no lado da integração. Se a mensagem foi criada no lado do Kommo, o campo não estará no webhook
action[reaction][message][receiver]objUm objeto com informações sobre o destinatário da mensagem.
action[reaction][message][sender]objUm objeto com informações sobre o remetente da mensagem.
action[reaction][message][timestamp]intHora de criação da mensagem no formato de Carimbo de data/hora Unix
action[reaction][message][msec_timestamp]intHora de criação da mensagem no formato de Carimbo de data/hora Unix com milissegundos
action[reaction][user]objUm objeto com informações sobre o remetente da reação.
action[reaction][conversation][id]stringID do bate-papo na API de bate-papo
action[reaction][conversation][client_id]stringCampo opcional. ID do bate-papo no lado da integração. Se o bate-papo foi criado usando a função escrever primeiro, o campo estará ausente no gancho
action[reaction][type]stringTipo de evento: "react", "unreact"
action[reaction][emoji]stringCampo opcional. Reação fornecida pelo usuário. Se o usuário remover a reação, o campo não estará no webhook