Webhooks de chat ao vivo

Os webhooks permitem que o onWebChat envie eventos para seu servidor em tempo real. Sempre que algo acontece (uma nova conversa começa, uma mensagem é enviada, um chat é encerrado ou avaliado, um visitante deixa uma mensagem offline), enviamos um HTTP POST com um corpo JSON para uma URL de sua escolha.

Esta é a forma mais fácil de sincronizar transcrições de chat com seu CRM ou CMS, disparar e-mails de acompanhamento, criar relatórios personalizados ou notificar outro sistema, sem polling.

Os webhooks estão disponíveis em todos os planos pagos e durante o teste grátis de 14 dias. Cada entrega é assinada para que você possa verificar que ela realmente veio do onWebChat.



POST https://your-server.com/onwebchat-webhook
Content-Type: application/json
User-Agent: onWebChat-Webhooks/1.0
X-OWC-Event: chat.closed
X-OWC-Delivery: 9381
X-OWC-Signature: sha256=4f1c...c2a9

{ "event": "chat.closed", "siteid": 1234, ... }

Configurar webhooks

Faça login no seu painel como administrador e vá em Configurações → Webhooks. Clique em “Adicionar endpoint”, cole a URL que deve receber os eventos, escolha os eventos desejados (ou selecione “Todos os eventos”, que inclui também os eventos que adicionarmos depois) e salve.

Quando você cria um endpoint, geramos um segredo de assinatura para ele (começa com whsec_). Você usará esse segredo para verificar as requisições recebidas (veja Verificar assinaturas, abaixo). Você pode gerar um novo segredo a qualquer momento; o antigo deixa de funcionar imediatamente.

Você pode adicionar vários endpoints por site e conferir as entregas recentes, incluindo o status HTTP, o número de tentativas e eventuais erros, diretamente no painel.



/* Dashboard → Settings → Webhooks */

URL      : https://your-server.com/onwebchat-webhook
Events   : chat.closed, message.created
Secret   : whsec_3f9a...   (used to verify requests)
Status   : Enabled

Tipos de evento

Assine qualquer combinação dos eventos abaixo. Cada mensagem tem um “author”: visitor, agent ou ai (e também trigger, para as mensagens de triggers na transcrição de chat.closed), então o mesmo evento message.created cobre as conversas gerenciadas pela sua equipe e pelo chatbot de IA.

Evento Enviado quando
chat.createdUm novo chat (diálogo) começa. O campo source indica como: visitor, trigger ou agent.
chat.assignedUm agente assume um chat: atende, assume de outro agente ou do chatbot de IA, ou aceita uma transferência. O campo source é pickup, reassign, ai_takeover ou transfer.
message.createdUma nova mensagem é enviada em um chat. Inclui mensagens do visitante, de um agente e do chatbot de IA.
chat.closedUm chat termina. O payload inclui a transcrição completa, os detalhes do visitante e as tags.
chat.ratedUm visitante avalia um chat (de 1 a 5 estrelas).
offline_message.createdUm visitante envia o formulário offline / de contato quando não há agentes disponíveis.
visitor.updatedUm agente atualiza o nome, o e-mail, o telefone ou as notas do visitante a partir do painel de chat.
visitor.bannedUm agente bloqueia um visitante a partir do painel de chat.
visitor.unbannedUm agente desbloqueia um visitante bloqueado anteriormente a partir do painel de chat.

Formato do payload

Cada webhook é um objeto JSON com o mesmo envelope: o nome do evento, seu siteid, um timestamp ISO-8601 e um objeto de dados cujo formato depende do evento.

O exemplo mostra um payload chat.closed, que contém a conversa completa. Eventos menores como message.created ou chat.rated incluem apenas os campos relevantes.


{
  "event": "chat.closed",
  "siteid": 1234,
  "created_at": "2026-06-22T07:40:52.322Z",
  "data": {
    "chat_id": 1206836,
    "started_at": "22-06-2026 10:40",
    "closed_at": "2026-06-22T07:40:52.322Z",
    "visitor": {
      "name": "Sarah Chen",
      "email": "sarah@example.com",
      "phone": "",
      "notes": "",
      "country_code": "us",
      "country": "United States",
      "os": "Windows 10",
      "browser": "Chrome 149.0"
    },
    "agents": ["Alex"],
    "labels": [{ "name": "sales", "color": "#4caf50" }],
    "messages": [
      { "author": "visitor", "agent_name": "", "text": "pricing info please", "time": "10:40", "date": "22-06-2026" },
      { "author": "ai", "agent_name": "", "text": "Here is a quick overview...", "time": "10:40", "date": "22-06-2026" },
      { "author": "agent", "agent_name": "Alex", "text": "Hi Sarah, I can help with a quote.", "time": "10:41", "date": "22-06-2026" }
    ]
  }
}

Verificar assinaturas

Cada requisição inclui um cabeçalho X-OWC-Signature com um hash HMAC-SHA256 do corpo bruto exato da requisição, calculado com o segredo de assinatura do seu endpoint.

Para verificar uma requisição, calcule o HMAC-SHA256 do corpo bruto com seu segredo e compare com o valor do cabeçalho (a parte após “sha256=”). Use uma comparação em tempo constante e sempre calcule o hash do corpo bruto, não de uma versão serializada novamente.

Você também recebe X-OWC-Event (o nome do evento) e X-OWC-Delivery (um ID de entrega único que permanece o mesmo nas novas tentativas, para que você possa usá-lo para eliminar duplicatas). As requisições são enviadas com o User-Agent onWebChat-Webhooks/1.0.


// Node.js / Express
const crypto = require('crypto');

app.post('/onwebchat-webhook',
  express.raw({ type: '*/*' }), (req, res) => {

  const secret = 'whsec_your_secret';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(req.body)              // raw Buffer
    .digest('hex');

  const got = req.headers['x-owc-signature'] || '';

  // constant-time compare; guard length first (timingSafeEqual throws on mismatch)
  const a = Buffer.from(got), b = Buffer.from(expected);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.status(401).end();

  const payload = JSON.parse(req.body.toString());
  // ... handle payload.event ...
  res.sendStatus(200);
});

Verificar em PHP

A mesma verificação em PHP: leia o corpo bruto, recalcule o HMAC com seu segredo e compare com hash_equals().


<?php
$secret  = 'whsec_your_secret';
$payload = file_get_contents('php://input');
$got     = $_SERVER['HTTP_X_OWC_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);

if (!hash_equals($expected, $got)) {
    http_response_code(401);
    exit;
}

$event = json_decode($payload, true);
// ... handle $event['event'] ...
http_response_code(200);

Novas tentativas e desativação automática

Seu endpoint deve responder com status 2xx o mais rápido possível e, no máximo, em 10 segundos. Qualquer resposta não 2xx, timeout ou erro de conexão é tratado como uma tentativa com falha.

As entregas com falha são repetidas com um intervalo crescente: após 1 minuto, 5 minutos, 20 minutos, 1 hora e 2 horas (6 tentativas no total).

Se 5 entregas seguidas continuarem falhando depois de todas as novas tentativas, o endpoint é desativado automaticamente e o titular da conta recebe um e-mail. Reative-o no painel depois de resolver o problema. Retornar HTTP 410 (Gone) desativa o endpoint imediatamente.



    Attempt 1  → immediately
    Attempt 2  → after  1 minute
    Attempt 3  → after  5 minutes
    Attempt 4  → after 20 minutes
    Attempt 5  → after  1 hour
    Attempt 6  → after  2 hours

    5 failed deliveries in a row → endpoint disabled

Boas práticas

  • Verifique sempre o X-OWC-Signature antes de confiar num payload.
  • Responda 2xx rapidamente e faça o trabalho pesado de forma assíncrona (em uma fila), para não exceder o tempo limite.
  • Use X-OWC-Delivery para eliminar duplicatas, porque a mesma entrega pode ser repetida após uma falha temporária.
  • Disponibilize seu endpoint por HTTPS.
  • Ignore os tipos de evento desconhecidos, para que os novos eventos que adicionarmos depois não afetem sua integração.

Pronto para começar? Ver planos ou abra Configurações → Webhooks no seu painel.

Usamos cookies para melhorar nosso site. Não coletamos dados pessoais nem o que você digita nos formulários.