Webhooks
Os webhooks podem ser configurados através da interface da Turn.io.
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
e turn
.
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.
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.
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:
sent
- A mensagem foi recebida pelo servidor.delivered
- A mensagem foi entregue no dispositivo do usuário.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.failed
- A mensagem não foi enviada.
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.
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"
},
{
...
}
]
}