Pular para o conteúdo

Webhooks

O RolChat entrega eventos aos seus sistemas como requisições HTTP POST assinadas. Esta página descreve os webhooks de plugin; os webhooks enviados por uma regra de Automação diferem em tentativas, tempo de espera e rotação do segredo, veja Webhooks de automação. As mesmas regras valem no sentido inverso, quando o seu sistema, um plugin ou um provedor envia dados para o RolChat. Verifique cada entrega na ordem abaixo antes de agir com base nela.

POST /your/endpoint HTTP/1.1
Content-Type: application/json
User-Agent: RolChat-Webhook/1.0
X-RolChat-Timestamp: 1713615825
X-RolChat-Signature: sha256=a1b2c3…
X-RolChat-Nonce: nonce_01HKQN9…
X-RolChat-Event-Id: evt_01HKQN9…
{ "id": "evt_01HKQN9…", "type": "conversation.created", "occurred_at": "…", "data": { … } }
Cabeçalho Significado
X-RolChat-Timestamp Segundos Unix no momento do envio. Faz parte da mensagem assinada.
X-RolChat-Signature sha256=<hex>. O prefixo indica o algoritmo, para que ele possa mudar no futuro.
X-RolChat-Nonce Um ULID exclusivo desta requisição HTTP. Uma nova tentativa recebe um novo nonce.
X-RolChat-Event-Id O ID do próprio evento. Permanece o mesmo entre as novas tentativas; use-o para eliminar duplicados.

As entregas de saída vão apenas para endpoints HTTPS. Uma URL HTTP é rejeitada quando a assinatura do webhook é criada.

A mensagem assinada é o timestamp, um ponto literal e o corpo bruto da requisição, byte a byte:

canonical = "<timestamp>.<body>"
signature = hex( HMAC-SHA256( secret, canonical ) )

Assine os bytes que você recebeu, não uma cópia reserializada do JSON já interpretado. Mudanças de espaços em branco ou na ordem das chaves quebram a assinatura. SHA-256 é o único algoritmo aceito.

Faça estas cinco verificações em ordem. Exemplos em Python, Node.js, Go, Ruby e PHP estão na página exemplos de verificação.

  1. Validade. Rejeite se |now − X-RolChat-Timestamp| > 300 segundos (400). Cinco minutos toleram diferenças de relógio e tornam uma requisição capturada inútil depois disso. Mantenha o seu servidor sincronizado por NTP.
  2. Assinatura. Calcule o valor esperado e compare usando uma comparação de tempo constante (hmac.compare_digest, crypto.timingSafeEqual, hash_equals). Rejeite com 401 se não corresponder. Uma comparação simples de strings vaza informações de tempo e não é aceitável.
  3. Nonce. Armazene X-RolChat-Nonce com um TTL de 10 minutos usando uma gravação atômica condicional (SET NX EX 600). Se ele já existir, rejeite com 409: a requisição é um replay. Se o seu armazenamento de nonces estiver fora do ar, falhe de forma fechada com 503 para que o RolChat tente de novo; nunca caia no “aceitar”.
  4. Interprete o corpo somente agora.
  5. Elimine duplicados pelo ID do evento. As novas tentativas trazem um novo nonce, mas o mesmo X-RolChat-Event-Id. Se você já processou esse ID nos últimos sete dias, responda 200 sem processar de novo.

Responda 2xx assim que a entrega for aceita com segurança; faça o trabalho de forma assíncrona. O RolChat espera 15 segundos por uma resposta.

  • Um segredo de webhook tem 64 bytes aleatórios, codificados em base64url (cerca de 86 caracteres). Ele é gerado quando a assinatura do webhook ou o plugin é criado e exibido uma única vez.
  • Guarde-o no seu próprio cofre ou em variáveis de ambiente; o RolChat mantém apenas uma cópia criptografada.
  • Recomenda-se fazer a rotação após 90 dias; o produto mostra um lembrete, mas nunca desativa uma assinatura por falta de rotação.
  • A rotação usa uma janela de sobreposição: após POST /api/v1/plugins/{id}/webhook-secret/rotate, o segredo antigo e o novo são aceitos por sete dias, as novas entregas são assinadas com o novo, e o antigo é excluído após a janela. Nada quebra no momento da rotação.
  • Se um segredo vazar, POST /api/v1/plugins/{id}/webhook-secret/revoke o invalida imediatamente, emite um novo, envia um e-mail aos administradores da conta e grava uma entrada de auditoria.

Uma resposta diferente de 2xx ou uma falha de rede agenda uma nova tentativa:

Tentativa Intervalo após a anterior
1 imediatamente
2 15 segundos
3 1 minuto
4 5 minutos
5 30 minutos
6 2 horas
7 8 horas
8 24 horas

408, 429, 5xx e erros de rede são repetidos. 400, 401, 403, 404 e 410 não são: a entrega vai direto para a fila de dead letters, porque repetir uma assinatura rejeitada ou um endpoint inexistente não adianta. Após oito tentativas malsucedidas, a entrega também vai para as dead letters.

As dead letters são mantidas por 30 dias e ficam visíveis em Configurações → Plugins → {plugin} → Log de webhooks → DLQ, onde um administrador pode reenviar uma delas (POST /api/v1/plugins/{id}/webhook-dlq/{entry_id}/replay).

  • Corpo de saída: 1 MB por padrão (configurável por plugin). Corpo de entrada no RolChat: 5 MB. Acima disso, 413.
  • Um plugin pode declarar allowed_source_ips; o RolChat aplica essa lista de permissões antes da verificação.
  • Você pode checar o user agent RolChat-Webhook/1.0 como verificação extra de sanidade. Isso não é um controle de segurança.

Os provedores enviam dados ao RolChat em /api/v1/webhooks/{category}/{adapter} usando os próprios esquemas de assinatura (Twilio, Telnyx, Bandwidth, Meta para o WhatsApp, Stripe). Cada adaptador verifica a assinatura do seu provedor, normaliza o payload e o republica no barramento de eventos interno com uma assinatura do RolChat. O seu próprio sistema pode enviar dados ao RolChat com os mesmos cabeçalhos X-RolChat-* descritos acima, assinados com o segredo do plugin dono do endpoint.

A ação Enviar requisição HTTP do módulo Automação tem regras de entrega próprias:

  • Um segredo por conta. Exiba-o ou gire-o na tela de Automação (Proprietário e Administrador). A rotação vale na hora: não há janela de sobreposição, o segredo antigo deixa de ser verificado imediatamente, então atualize primeiro o seu receptor ou aceite uma breve interrupção.
  • Tempo de espera: o RolChat espera 10 segundos por uma resposta.
  • Novas tentativas: até 6 tentativas no total. A pausa antes da tentativa 2 é de 30 segundos, depois cerca de 2 minutos, 8 minutos, 32 minutos e 2 horas 8 minutos, cada uma com variação de até 20 %. Uma única pausa nunca passa de 6 horas.
  • O que é repetido: erros de rede, tempos esgotados, 5xx, 408, 425 e 429. Outras respostas 4xx, um endereço bloqueado ou um corpo grande demais não são repetidos: a entrega vai direto para a fila de falhas, como depois da última tentativa com falha.
  • Cabeçalhos: X-RolChat-Signature, X-RolChat-Signature-V2, X-RolChat-Timestamp, X-RolChat-Delivery-Id, X-RolChat-Attempt.

POST /api/v1/webhooks/test-signature envia um evento sintético assinado para o endpoint do plugin que faz a chamada, para que você verifique a sua implementação de ponta a ponta antes da chegada do tráfego real.

  • Verificar com o JSON interpretado e recodificado em vez dos bytes brutos.
  • Usar == para comparar assinaturas.
  • Eliminar duplicados pelo nonce (cada nova tentativa tem um novo) em vez de pelo ID do evento.
  • Um relógio adiantado ou atrasado em mais de cinco minutos.
  • Fazer um trabalho lento antes de responder, estourar o tempo de 15 segundos e receber o mesmo evento de novo.