O webhook do SMS não chega ou é recusado: HTTPS, assinatura, resposta em 5 segundos e novas tentativas

WhatsApp e APIs·· 54 visualizações· 3 min de leitura

A resposta curta: quase sempre é uma de cinco coisas: o endereço não é HTTPS na porta 443, é um endereço privado, o seu servidor demora mais de 5 segundos a responder, a assinatura é conferida sobre o corpo errado, ou a mensagem foi criada antes de o webhook ser gravado. Comece sempre por POST /v1/sms/webhook/test: ele mostra o que o seu servidor respondeu.

A lista de verificação

Sintoma Causa provável O que fazer
O webhook não grava Endereço sem HTTPS, noutra porta, ou interno Use https:// na porta 443, num endereço público.
O teste devolve erro ou tempo esgotado O servidor não respondeu com um código 2xx em 5 segundos Responda logo com 200 e faça o trabalho depois, numa fila sua.
O seu código recusa todos os avisos A assinatura é calculada sobre o corpo já convertido, ou com o segredo antigo Use o corpo bruto, tal como chegou, e o segredo actual.
Recusa só alguns avisos Relógio do servidor atrasado, e a hora t parece antiga Acerte a hora do servidor e dê uma tolerância razoável.
Uma mensagem não deu aviso Foi criada antes de o webhook ser gravado Consulte-a com GET /v1/sms/messages/{id}.
O mesmo aviso chegou duas vezes O seu servidor não respondeu a tempo e tentámos de novo Trate o aviso pelo id da mensagem e pelo acontecimento; ignore o repetido.

Conferir a assinatura

O cabeçalho X-Webhook-Signature tem a forma t=<hora unix>,v1=<hex>. O v1 é o HMAC-SHA256 de t + "." + corpo com o seu segredo. Em PHP:

$corpo = file_get_contents('php://input'); // o corpo tal como chegou
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? ''), $a);
$esperado = hash_hmac('sha256', ($a['t'] ?? '') . '.' . $corpo, $segredo);
$recente = abs(time() - (int) ($a['t'] ?? 0)) < 300; // tolerância à sua escolha
if (!$recente || !hash_equals($esperado, $a['v1'] ?? '')) { http_response_code(401); exit; }
http_response_code(200); // responda já; trate o aviso depois

Mais pormenores, e o mesmo noutras linguagens, em receber um webhook em PHP e conferir a assinatura.

As novas tentativas

Se o seu servidor não responder com 2xx em 5 segundos, tentamos de novo 1 minuto, 5 minutos, 30 minutos, 2 horas e 6 horas depois. Por isso um servidor parado algumas horas não perde avisos, mas pode recebê-los atrasados e, se respondeu tarde, repetidos.

Não faça o trabalho pesado antes de responder. Enviar um e-mail, gerar um PDF ou chamar outro serviço dentro do pedido é a causa mais comum dos 5 segundos. Grave o aviso, responda 200 e trate-o a seguir.
Mudou o segredo? Pedir um novo com rotate_secret invalida o antigo para os avisos seguintes. Actualize o seu servidor no mesmo momento, senão passa a recusar tudo.

Ainda sem avisos no seu endereço? Veja a página da API ou fale connosco com o correlation_id do pedido.

Ver a página da API

VEJA TAMBÉM

O webhook do SMS: como o seu sistema fica a saber que cada aviso saiu ou falhou

Receber um webhook em PHP e verificar a assinatura

Webhook ou consulta periódica: como um sistema fica a saber que algo mudou noutro

Quando um aviso por SMS falha: novas tentativas, créditos devolvidos e passar para o e-mail

Erros e estados das mensagens na API de SMS: o que significa cada um e o que fazer

Uma chave de API ou um token ficou exposto: o que fazer, pela ordem certa

PRODUTO RECOMENDADO

Hospedagem de sites com cPanel

Domínio e SSL incluídos, cópias diárias e o painel que já conhece. desde $6.60/mês (plano de 3 anos, com cupão)

Ver planos
Esta resposta foi útil? A sua resposta ajuda-nos a melhorar este artigo.