Pular para o conteúdo principal

Webhooks

Os webhooks podem ser configurados através da interface da Turn.io. Eles permitem o encaminhamento automático de mensagens da Turn para um serviço de sua propriedade ou operação.

Assinaturas de Webhook

Cada webhook deve especificar pelo menos uma assinatura. Uma assinatura é um identificador para o tipo de eventos que um endpoint de webhook deve receber.

Atualmente, os seguintes tipos de assinaturas são suportados: whatsapp, turn e journey_outbound.

nota

O tipo engage era suportado, mas está descontinuado e será removido em breve.

O tipo de assinatura é enviado junto com a solicitação HTTP como um header HTTP.

X-Turn-Hook-Subscription: whatsapp

Assinaturas WhatsApp

Este é o tipo de assinatura padrão. Todos os eventos gerados pelo cliente do WhatsApp Enterprise são enviados para qualquer webhook inscrito nesse tipo de assinatura. Se você deseja receber mensagens recebidas ou notificações de entrega de mensagens do seu público-alvo, essa é a assinatura que você deve usar. Os detalhes desses eventos são documentados abaixo em Webhooks de Mensagens Recebidas e Notificações de Status de Mensagens Enviadas.

atenção

Recomendamos que qualquer pessoa que receba mensagens via webhook implemente uma verificação de exclusividade no ID da mensagem para evitar agir sobre entregas duplicadas.

Assinaturas Turn.io

X-WhatsApp-Id: <id-da-mensagem-do-whatsapp>

Este é um tipo de assinatura gerado para mensagens criadas através da API de mensagens que a Turn.io expõe. Se você deseja receber eventos de webhook sempre que um cliente da API enviar uma mensagem para alguém no WhatsApp, esta é a assinatura que você deve usar.

Os webhooks recebem o mesmo payload exato que foi enviada para o endpoint HTTP API.

Um header HTTP adicional X-WhatsApp-Id é fornecido junto com o payload original. O valor do header é o Id que o WhatsApp atribuiu a essa mensagem e ao qual qualquer atualização de status de entrega de mensagens fará referência.

nota

Observe que essas mensagens só são enviadas após o cliente WhatsApp Enterprise aceitar a mensagem para entrega.

Webhooks de Mensagens Recebidas

{
"contacts": [{
"profile": {
"name": "Kerry Fisher"
},
"wa_id": "16315551234"
}],
"messages": [{
"context": {
"from": "sender_wa_id_of_context_message",
"id": "message_id_of_context_message"
},

"from": "sender_wa_id",
"id": "message_id",
"timestamp": "message_timestamp",
"type": "audio | document | image | location | system | text | video | voice | contacts",

# Somente em caso de erro, o campo de erros (array) estará presente.
"errors": [ { ... } ],

"audio": {
"file": "absolute_filepath_on_coreapp",
"id": "media id",
"link": "link to audio file",
"mime_type": "media mime type",
"sha256": "checksum"
},

"document": {
"file": "absolute_filepath_on_coreapp",
"id": "media id",
"link": "link to document file",
"mime_type": "media mime type",
"sha256": "checksum",
"caption": "document caption"
},

"image": {
"file": "absolute_filepath_on_coreapp",
"id": "media id",
"link": "link to image file",
"mime_type": "media mime type",
"sha256": "checksum",
"caption": "image caption"
},

"location": {
"address": "1 hacker way, menlo park, ca, 94025",
"latitude": latitude,
"longitude": longitude,
"name": "location name"
},

"system": {
"body": "system message content"
},

"text": {
"body": "text message content"
},

"video": {
"file": "absolute_filepath_on_coreapp",
"id": "media id",
"link": "link to video file",
"mime_type": "media mime type",
"sha256": "checksum"
},

"voice": {
"file": "absolute_filepath_on_coreapp",
"id": "media id",
"link": "link to audio file",
"mime_type": "media mime type",
"sha256": "checksum"
}

"contacts": [{
"addresses": [{
"city": "Menlo Park",
"country": "United States",
"country_code": "us",
"state": "CA",
"street": "1 Hacker Way",
"type": "WORK",
"zip": "94025"
}],
"birthday": "2012-08-18",
"contact_image": "/9j/4AAQSkZJRgABAQEAZABkAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABgAGADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD1NLloxyc0j3bNUHDGgoCMVNkBbhutvVqc9yGHNZ3kOW4Wn/ZnQZzSsgLLXAA61Xn1O2t4zLcyJHGvV3OAKMADmvOviLq9m11a2bO/l2xLzoqnliF2j9f1NTLRXHGHM7Hb2vivSL+8e0s7yKaVeyHg/Q9D+FXWuHPOzivFodT0WZkeF44bheVdE2EH+Rr2+zuVuNPt7gqh86JX+TkcjPFTCdy6lNQ2dyr5+G5WpRe4HTFWWSOQfwioZbCIn5XNaXRmQPegjmqrKLh+...",
"emails": [{
"email": "kfish@fb.com",
"type": "WORK"
}],
"ims": [{
"service": "AIM",
"user_id": "kfish"
}],
"name": {
"first_name": "Kerry",
"formatted_name": "Kerry Fisher",
"last_name": "Fisher"
},
"org": {
"company": "Facebook"
},
"phones": [{
"phone": "+1 (940) 555-1234",
"type": "CELL"
}, {
"phone": "+1 (650) 555-1234",
"type": "WORK",
"wa_id": "16505551234"
}],
"urls": [{
"url": "https://www.facebook.com",
"type": "WORK"
}]
}]
}]
}

O formato geral do Webhook de notificações é mostrado. Você precisará criar um manipulador de endpoint que seja acionado pelo envio ou recebimento de uma mensagem. As seções a seguir fornecem mais detalhes para cada tipo de notificação.

Marcando mensagens recebidas como lidas

Você pode usar o endpoint /v1/messages/<id-da-mensagem> para alterar o status das mensagens recebidas para "lidas".

$ curl -X PUT "https://whatsapp.turn.io/v1/messages/<id-da-mensagem>" \
-H "Authorization: Bearer token" \
-d '
{
"status": "read"
}'
> {}

Certifique-se de substituir token pelo seu token de acesso.

Notificações de Status de Mensagens Enviadas

Mensagem foi sent

{
"statuses": [
{
"id": "ABGGFlA5FpafAgo6tHcNmNjXmuSf",
"status": "sent",
"timestamp": "1518694700",
"message": {
"recipient_id":"16315555555"
}
}
]
}

Mensagem foi read

{
"statuses": [
{
"id": "ABGGFlA5FpafAgo6tHcNmNjXmuSf",
"status": "read",
"timestamp": "1518694700",
"message": {
"recipient_id":"16315555555"
}
}
]
}

O cliente da API do WhatsApp Business enviará notificações para informar o status das mensagens enviadas para os usuários. Quando a mensagem for enviada com sucesso, você receberá uma notificação quando a mensagem for enviada, entregue e lida. A ordem dessas notificações em seu aplicativo pode não refletir o momento exato do status da mensagem. Verifique o timestamp para determinar o momento, se necessário. As notificações que você pode receber são:

  1. sent - A mensagem foi recebida pelo servidor.
  2. delivered - A mensagem foi entregue no dispositivo do usuário.
  3. read - A mensagem foi lida pelo usuário. Notificações de leitura estarão disponíveis apenas para usuários que tenham recibos de leitura habilitados. Para usuários que não têm isso habilitado, você receberá apenas a notificação de entrega.
  4. failed - A mensagem não foi enviada.
nota

Para que um status seja "read", ele deve ter sido "delivered". Em alguns cenários, como quando um usuário está na tela de chat e uma mensagem chega, a mensagem é entregue e lida quase simultaneamente. Nesses casos, a notificação de entrega será descartada, pois é implícito que uma mensagem foi entregue se foi lida. Isso ocorre devido a uma otimização interna.

Segurança

Veja um exemplo abaixo de como a assinatura pode ser calculada usando Python.

>>> import hmac
>>> import base64
>>> from hashlib import sha256
>>> h = hmac.new("secret", '{"foo":"bar"}', sha256)
>>> base64.b64encode(h.digest())
'PzqzmGtlarsXrz6xRD7WwI74//n+qDkVkJ0bQhrsib4='

A assinatura é enviada como um header HTTP para os endpoints de webhook configurados.

X-Turn-Hook-Subscription: whatsapp
X-Turn-Hook-Signature: PzqzmGtlarsXrz6xRD7WwI74//n+qDkVkJ0bQhrsib4=

Cada webhook possui um hmac_digest e um hmac_secret configurados. Esses valores são usados para calcular uma assinatura do payload do webhook. Com essa assinatura, você pode verificar se o webhook foi realmente recebido da Turn.io.

nota

Atualmente, apenas o algoritmo SHA256 é suportado como digest hmac.

A assinatura é enviada como um header HTTP no webhook postado para os endpoints configurados.

Erros de Notificação

Quando houver um erro no envio ou recebimento de uma notificação, o array errors fornecerá uma descrição do erro. Esse tipo de erro pode ser causado por problemas transitórios de conectividade de rede, credenciais inválidas, controladores de gerenciamento em status indisponível, entre outros.

{
"errors": [{
"code": <código-do-erro>,
"title": "<título-do-erro>",
"details": "<descrição-do-erro>",
"href": "localização para detalhes do erro"
},
{
...
}
]
}

Desempenho de Webhook e Novas Tentativas

Desempenho de Webhook

atenção

A Turn impõe um tempo limite rigoroso de 5 segundos nos webhooks. Se o serviço não responder dentro de 5 segundos, a Turn tentará novamente até 5 vezes, com um atraso incremental. Veja a documentação abaixo sobre novas tentativas.

Antes de um evento ser enviado ao seu webhook configurado, ele é colocado em fila na Turn.io. Em condições normais, isso ocorre em questão de milissegundos.

A Turn.io opera 3 níveis de prioridade de fila: low, default e high. A fila de prioridade low é processada com menor urgência, enquanto a de prioridade high recebe o máximo de recursos para garantir entrega rápida.

A fila à qual seus eventos são enviados depende da rapidez com que seu endpoint responde. O tempo de resposta de seus endpoints é analisado a cada 20 entregas de eventos de webhook. O tempo que você leva para aceitar uma mensagem para entrega determina em qual fila o próximo evento será enviado.

FilaLimite de milissegundos
low1 segundo ou mais
defaultMais de 200ms, mas menos de 1 segundo
high200ms ou menos

O compromisso da Turn.io é que, se seu endpoint de webhook processa mensagens rapidamente, nos comprometemos a processar suas mensagens o mais rápido possível. Se seu endpoint for lento, trataremos os eventos com baixa prioridade.

A análise do tempo de resposta do webhook ocorre continuamente e, à medida que você altera sua velocidade de processamento, será movido automaticamente para uma prioridade de fila superior ou inferior.

nota

Podemos optar por expor mais funcionalidades de configurações de aplicativos no futuro. Entre em contato conosco se você sentir que algo crítico está faltando.

Estratégia de Retentativa de Webhook

A Turn.io tentará reenviar um evento de webhook dependendo do código de status HTTP:

Tipo de ErroComportamentoExemplo de Resposta HTTP
Códigos HTTP 4XX (Erros do Cliente)Cancela novas tentativasHTTP 404 Not Found
Erros de Domínio Irresolvível (Permanente)Cancela novas tentativasHTTP 502 Bad Gateway (Unresolvable Domain)
Erros de Rede (Temporários)Tenta novamenteHTTP 504 Gateway Timeout
Outros ErrosTenta novamenteHTTP 500 Internal Server Error

Isso garante que erros recuperáveis sejam tratados de forma eficiente, enquanto erros irrecuperáveis sejam identificados e cancelados rapidamente, otimizando a resposta do sistema a diferentes cenários de falha.

A Turn.io continuará tentando no máximo 5 vezes, com um atraso incremental a cada tentativa.

A primeira tentativa ocorre cerca de 17 segundos após a falha inicial. As tentativas seguintes ocorrem cerca de 19, 24, 31 e 47 segundos depois. Mensagens serão descartadas se o endpoint estiver offline por mais de 140 segundos.

Algum grau de variação é introduzido nos intervalos de tempo das tentativas, então o intervalo exato pode variar.