Webhooks
Webhooks são notificações automatizadas para URLs definidas, que informam em tempo real sobre eventos. Eles são úteis porque permitem uma resposta imediata a eventos específicos, sem a necessidade de consultas contínuas. Webhooks ajudam a manter os sistemas eficientes e responsivos.
Seus Webhooks são chamados imediatamente quando um evento ocorre. Se não conseguirmos alcançar sua URL ou se ela responder com um status de erro, repetimos o envio segundo um plano fixo e, além disso, verificamos automaticamente ao longo de vários dias se o destinatário está falhando de forma permanente. Os detalhes estão descritos abaixo em Entrega e retries.
Entrega e retries
Quando reenviamos um Webhook
Um Webhook só é reentregue quando a resposta do seu servidor indica um erro temporário:
- Name
HTTP 429- Type
- rate-limit
- Description
Seu endpoint sinaliza que está recebendo muitas solicitações no momento.
- Name
HTTP 5xx- Type
- erro de servidor
- Description
Concretamente
500,502,503e504.
- Name
Erros de conexão- Type
- rede
- Description
Tempos esgotados, falhas de resolução DNS, erros de TLS/handshake ou uma conexão interrompida durante a solicitação.
Todas as demais respostas são consideradas finais e não desencadeiam outra tentativa de entrega. Isso inclui códigos 4xx como 400, 401, 403 e 404, pois geralmente indicam um erro de configuração no lado do destinatário que não pode ser resolvido apenas tentando novamente. Respostas na faixa 2xx e 3xx são consideradas bem-sucedidas.
Timeout de requisição
Cada tentativa de entrega tem um timeout de 5 segundos. Se o seu servidor não responder dentro dessa janela, tratamos a tentativa como falha e agendamos um retry conforme o plano abaixo.
Plano de retry
Se uma tentativa falhar, a próxima é agendada após um intervalo fixo e crescente. Realizamos um total de até 14 tentativas; depois disso, o job é descartado. A janela total de entrega abrange, portanto, cerca de 3,5 dias.
| Tentativa | Espera desde a tentativa anterior |
|---|---|
| 1 (inicial) | imediatamente |
| 2 | 1 minuto |
| 3 | 5 minutos |
| 4 | 30 minutos |
| 5 | 60 minutos |
| 6 | 2 horas |
| 7 a 14 | 10 horas cada |
Desativação automática em caso de falhas persistentes
Além dos retries individuais, monitoramos continuamente a taxa de erro diária por Webhook. Um Webhook é marcado como "problemático" assim que, em um dado dia,
- a taxa de erro diária estiver acima de 80 % e
- ocorrerem pelo menos 10 falhas naquele dia.
A partir desse momento, o Webhook é observado por vários dias. Se a situação não melhorar, o sistema escala em etapas:
| Dia | Limite (taxa de erro rolling) | Ação |
|---|---|---|
| 1 | acima de 80 % | E-mail de aviso nível 1 |
| 3 | acima de 85 % | E-mail de aviso nível 2 |
| 5 | acima de 90 % | E-mail de aviso nível 3 |
| 7 | acima de 95 % | O Webhook é desativado automaticamente, entrada no audit-log e e-mail de desativação |
Os contadores diários são contados a partir do dia em que o problema é detectado.
Após uma desativação automática
Um Webhook desativado automaticamente permanece inativo até que você o reative manualmente no Dashboard. Após a reativação, as estatísticas começam do zero.
O que conta como "bem-sucedido"?
Para a avaliação da taxa de erro, toda resposta que não seja um disparador de retry conta como "ok". Concretamente, respostas 2xx, 3xx e até mesmo 4xx (com exceção de 429) são tratadas como bem-sucedidas, pois, do ponto de vista do sistema de envio, representam uma resposta final e inequívoca.
Isso significa: um endpoint que responde de forma persistente com 404 não será desativado automaticamente, e deverá ser removido ou corrigido manualmente por você.
Segurança
Verificar IP de origem
Todos os Webhooks vêm do nosso IPv4 195.201.160.143 ou do IPv6 2a01:4f8:13a:8e7::2. Se isso mudar, você encontrará todos os detalhes no nosso Changelog.
Verificar assinatura
Todos os Webhooks para o seu servidor são assinados com a chave de assinatura da sua conta. Com base nesses dados, você pode validar a autenticidade das solicitações recebidas de nós e evitar duplicações ou solicitações fraudulentas. Verifique a assinatura conforme descrito na página Assinatura.
Enviamos os seguintes cabeçalhos em cada Webhook:
- Name
X-Signature- Type
- string
- Description
A assinatura gerada por nós
- Name
X-Timestamp- Type
- integer
- Description
Timestamp no qual a assinatura foi criada por nós
- Name
X-Nonce- Type
- string
- Description
String gerada aleatoriamente com 32 caracteres
Exemplos como JSON Payload
SMS
SMS recebida (sms_mo)
{
"data": {
"id": "681590",
"sender": "SMS",
"system": "491771783130",
"text": "Hello World",
"time": "1605878104",
"message_type": "SMS"
},
"webhook_event": "sms_mo",
"webhook_timestamp": "2020-12-02 11:55:44"
}
Mudança de status do SMS (dlr)
{
"data": {
"msg_id": "77149843739",
"status": "TRANSMITTED",
"timestamp": "2021-08-24 08:08:00.000000"
},
"webhook_event": "dlr",
"webhook_timestamp": "2021-08-24T08:08:00+02:00"
}
Rastreamento de Desempenho (tracking)
{
"webhook_event": "tracking",
"webhook_timestamp": "2022-07-27T07:38:18+02:00",
"data": {
"sms_id": "77182424125",
"sms_label": null,
"tracking_url": "https://svn.me/7oz",
"final_url": "https://www.google.com",
"type": "click",
"total_clicks": 5,
"total_views": 3
}
}
Voz
Alteração de Status da Mensagem de Voz (voice_status)
{
"data": {
"callerId": "49176123456789",
"duration": "4",
"id": "284195",
"pricePerMinute": 0.075,
"recipient": "4943160049851",
"status": "completed",
"timestamp": 1629786769
},
"webhook_event": "voice_status",
"webhook_timestamp": "2021-08-24T08:32:50+02:00"
}
Chamada Recebida (voice_call)
{
"webhook_event": "voice_call",
"webhook_timestamp": "2024-08-02T07:28:59+02:00",
"data": {
"id": 0,
"caller": "4943160049851",
"time": 1722576539,
"system": "4915170517246"
}
}
Sinal DTMF (voice_dtmf)
{
"webhook_event": "voice_dtmf",
"webhook_timestamp": "2024-08-02T07:28:59+02:00",
"data": {
"id": 0,
"callerId": "4943160049851",
"recipient": "4943160049851",
"status": "completed",
"system": "4915170517246",
"timestamp": 1722576539,
"duration": 2.76,
"pricePerMinute": 0.045,
"dtmf_digit": 9,
"total_price": 0.045
}
}
RCS
Mensagem foi entregue
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T10:01:07+01:00",
"data":
{
"msg_id": "77233699836",
"status": "DELIVERED",
"timestamp": "1709888466.254410",
"foreign_id": null,
"agent_id": "myfancyagent"
}
}
Mensagem foi lida
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T10:01:09+01:00",
"data":
{
"msg_id": "77233699836",
"status": "READ",
"timestamp": "1709888468.065783",
"foreign_id": null,
"agent_id": "myfancyagent"
}
}
Relatório de status de uma mensagem enviada
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T10:00:18+01:00",
"data":
{
"sender": "4915153952979",
"status": "IS_TYPING",
"agent_id": "myfancyagent"
}
}
Uma mensagem de texto foi enviada
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T09:47:12+01:00",
"data": {
"id": 1871353,
"sender": "4915153952979",
"time": 1709870553,
"message_type": "RCS",
"content_type": "text",
"text": "Hallo",
"agent_id": "myfancyagent"
}
}
Uma resposta sugerida foi selecionada
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T05:59:33+01:00",
"data": {
"id": 1870983,
"sender": "4915153952979",
"time": 1709870129,
"message_type": "RCS",
"content_type": "suggestion_response",
"suggestion_response": {
"postbackData": "suggestion_2",
"text": "Suggestion #2",
"type": "REPLY"
},
"agent_id": "myfancyagent"
}
}
Uma imagem foi enviada
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T08:58:20+01:00",
"data": {
"id": 1871195,
"sender": "4915153952979",
"time": 1709870556,
"message_type": "RCS",
"content_type": "user_file",
"user_file": {
"thumbnail": {
"mimeType": "image/jpeg",
"fileSizeBytes": 10166,
"fileUri": "https://static.seven.io/uploads/rbm/61513d3d/6176746a5177553d/4f36357145416a773452537737696e495a366a68454a42344639574937716e62704156765358664d486e42776730337334675a76522b6d4f574b6e32626632546842493d.jpeg"
},
"payload": {
"mimeType": "image/jpeg",
"fileSizeBytes": 611314,
"fileName": "IMG_20240308_050231_01.jpg",
"fileUri": "https://static.seven.io/uploads/rbm/61513d3d/6176746a5177553d/4f76746e45515768746866717653444e6166336a513852375249614d753637656f414a6f4758624d5358417269306e767331493645372b47446654325a66764b3168453d.jpeg"
}
},
"agent_id": "myfancyagent"
}
}
Um arquivo foi enviado
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T11:07:51+01:00",
"data": {
"id": 1871485,
"sender": "4915153952979",
"time": 1709892233,
"message_type": "RCS",
"content_type": "user_file",
"user_file": {
"payload": {
"mimeType": "application/pdf",
"fileSizeBytes": 18810,
"fileName": "sample (1).pdf",
"fileUri": "https://static.seven.io/uploads/rbm/61513d3d/617678715267303d/4f616c675256696b73524c6c75337a4b5a66336a51705570464e665a752f6d4e70464d37546e504b5458423730556a7337314e70514c3241436650304d616e4b3078493d.pdf"
}
},
"agent_id": "myfancyagent"
}
}
Uma localização foi compartilhada
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T11:07:51+01:00",
"data": {
"id": 1871485,
"sender": "4915153952979",
"time": 1709892233,
"message_type": "RCS",
"content_type": "location",
"location": {
"latitude": 54.3216562,
"longitude": 10.1350767
},
"agent_id": "myfancyagent"
}
}