Como podemos ajudar?

Conte brevemente do que se trata; responderemos por e-mail.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
Para a página inicial

Webhooks: eventos para seu servidor

Webhooks assinados e REST hooks do reactive.chat: eventos, cabeçalhos, corpo, verificação de assinatura com HMAC-SHA256, novas tentativas, tempos limite, desativação e exemplos de verificação em PHP, Node e Python.

Os webhooks informam ao seu servidor o que acontece no chat: uma nova conversa, uma nova mensagem, uma transferência para a equipe, uma avaliação. Há duas formas:

Eventos

As conversas da pesquisa no site (Smart Answer) só disparam eventos quando se tornam visíveis como chat.

Configurar o webhook assinado

Na conta, em Configurações → Integrações → Webhooks (permissão: gerenciar integrações):

Nenhuma chamada de teste é enviada ao salvar. Depois de ativar, pode levar cerca de 15 segundos para os eventos começarem a chegar; eventos anteriores à ativação não são entregues retroativamente.

A entrega

POST /rc-webhook HTTP/1.1
Host: hooks.your-company.com
Content-Type: application/json; charset=utf-8
User-Agent: reactive.chat-webhook/1.0
X-RC-Event: csat.submitted
X-RC-Delivery: 01JAB3C4D5E6F7G8H9JKMNPQRS
X-RC-Timestamp: 1792503600
X-RC-Signature: sha256=3f0a1c...

{"id":"01JAB3C4D5E6F7G8H9JKMNPQRS","event":"csat.submitted","ts":1792503600,"site_key":"ABCDEFGHJKLMNPQRSTUVWX12","conversation_id":"01JAB2...","session_id":"s_...","visitor_id":"v_...","data":{"score":5,"comment":"Very helpful"}}

Cabeçalhos:

Corpo:

Verificar a assinatura

Verifique antes de qualquer processamento: timestamp com no máximo 300 segundos de idade, assinatura sobre o corpo bruto, comparação em tempo constante.

PHP:

<?php
$geheim = getenv('RC_WEBHOOK_SECRET');
$body   = file_get_contents('php://input');
$ts     = $_SERVER['HTTP_X_RC_TIMESTAMP'] ?? '';
$sig    = $_SERVER['HTTP_X_RC_SIGNATURE'] ?? '';

if (!ctype_digit($ts) || abs(time() - (int) $ts) > 300) { http_response_code(401); exit; }
$soll = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, $geheim);
if (!hash_equals($soll, $sig)) { http_response_code(401); exit; }

$ereignis = json_decode($body, true);
// detect duplicates: remember $ereignis['id']
http_response_code(204);

Node.js (Express):

const crypto = require('crypto');
app.post('/rc-webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const ts = req.get('X-RC-Timestamp') || '';
  const sig = req.get('X-RC-Signature') || '';
  if (!/^\d+$/.test(ts) || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(401);
  const soll = 'sha256=' + crypto.createHmac('sha256', process.env.RC_WEBHOOK_SECRET)
    .update(ts + '.' + req.body.toString('utf8')).digest('hex');
  if (sig.length !== soll.length || !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(soll))) {
    return res.sendStatus(401);
  }
  const ereignis = JSON.parse(req.body.toString('utf8'));
  res.sendStatus(204);
  verarbeiteSpaeter(ereignis);   // respond quickly, work afterwards
});

Python (Flask):

import hmac, hashlib, os, time
from flask import request, abort

@app.post("/rc-webhook")
def rc_webhook():
    ts = request.headers.get("X-RC-Timestamp", "")
    sig = request.headers.get("X-RC-Signature", "")
    body = request.get_data()                      # raw bytes
    if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
        abort(401)
    soll = "sha256=" + hmac.new(os.environ["RC_WEBHOOK_SECRET"].encode(),
                                ts.encode() + b"." + body, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(soll, sig):
        abort(401)
    return "", 204

Respostas, novas tentativas e desativação

Responda rapidamente com um código 2xx e processe depois. Tempos limite: 4 segundos para estabelecer a conexão, 10 segundos no total. Redirecionamentos não são seguidos.

Eventos com mais de uma hora não são mais entregues. Se os erros se acumularem (5 em 60 segundos), a entrega ao seu destino será pausada por 30 segundos; as tarefas serão tentadas novamente depois. Um chat nunca espera pelo seu webhook.

A ordem das entregas não é garantida. Se necessário, ordene por ts ou pelo seq das mensagens da API.

REST hooks (Zapier, Make, n8n)

As ferramentas de automação cadastram seus próprios destinos pela API do servidor. Você também pode usar isso diretamente:

curl -X POST https://reactive.chat/v1/hooks \
  -H "Authorization: Bearer rc_live_..." \
  -H "Content-Type: application/json" \
  -d '{"event":"message.created","target_url":"https://hooks.your-company.com/rc","source":"n8n"}'

Entrega de um REST hook:

POST https://hooks.your-company.com/rc
Content-Type: application/json
User-Agent: reactive.chat-n8n/1.0
X-RC-Event: message.created
X-RC-Delivery: 01JAB3...

{"event":"message.created","delivery_id":"01JAB3...","data":{"name":"message.created","ts":1792503600123,"site_key":"...","conversation_id":"...","session_id":"...","visitor_id":"...","message":{"id":"...","seq":7,"kind":"text","direction":"in","author_type":"bot","author_name":"Assistant","via":null,"body":"…","redacted":false,"ts":1792503600120}}}

O que não existe

A seguir: API do servidor

Última atualização: