Webhooks de chat ao vivo
Os webhooks permitem que a onWebChat envie eventos para o seu servidor em tempo real. Sempre que algo acontece (uma nova conversa começa, é enviada uma mensagem, um chat é encerrado ou avaliado, um visitante deixa uma mensagem offline), enviamos um HTTP POST com um corpo JSON para um URL à sua escolha.
Esta é a forma mais fácil de sincronizar transcrições de chat no seu CRM ou CMS, acionar 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 possa verificar que veio realmente da 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
Inicie sessão no seu painel como administrador e vá a Configurações → Webhooks. Clique em «Adicionar endpoint», cole o URL que deve receber os eventos, escolha os eventos pretendidos (ou selecione «Todos os eventos», que inclui também os eventos que adicionarmos mais tarde) e guarde.
Quando cria um endpoint, geramos um segredo de assinatura para ele (começa por whsec_). Vai usar este segredo para verificar os pedidos recebidos (ver Verificar assinaturas, abaixo). Pode gerar um novo segredo a qualquer momento; o antigo deixa de funcionar de imediato.
Pode adicionar vários endpoints por site e rever as entregas recentes, incluindo o estado 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
Subscreva qualquer combinação dos eventos abaixo. Cada mensagem tem um «author»: visitor, agent ou ai (e ainda trigger, para as mensagens de triggers na transcrição de chat.closed), pelo que o mesmo evento message.created cobre as conversas geridas pela sua equipa e pelo chatbot de IA.
| Evento | Enviado quando |
|---|---|
chat.created | Um novo chat (diálogo) começa. O campo source indica como: visitor, trigger ou agent. |
chat.assigned | Um agente assume um chat: atende-o, assume-o de outro agente ou do chatbot de IA, ou aceita uma transferência. O campo source é pickup, reassign, ai_takeover ou transfer. |
message.created | Uma nova mensagem é enviada num chat. Inclui mensagens do visitante, de um agente e do chatbot de IA. |
chat.closed | Um chat termina. O payload inclui a transcrição completa, detalhes do visitante e etiquetas. |
chat.rated | Um visitante avalia um chat (de 1 a 5 estrelas). |
offline_message.created | Um visitante submete o formulário offline / de contacto enquanto não há agentes disponíveis. |
visitor.updated | Um agente atualiza o nome, o e-mail, o telefone ou as notas do visitante a partir do painel de chat. |
visitor.banned | Um agente bloqueia um visitante a partir do painel de chat. |
visitor.unbanned | Um agente desbloqueia um visitante previamente bloqueado a partir do painel de chat. |
Formato do payload
Cada webhook é um objeto JSON com o mesmo envelope: o nome do evento, o seu siteid, um timestamp ISO-8601 e um objeto de dados cuja forma 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 pedido inclui um cabeçalho X-OWC-Signature com um hash HMAC-SHA256 do corpo bruto exato do pedido, calculado com o segredo de assinatura do seu endpoint.
Para verificar um pedido, calcule o HMAC-SHA256 do corpo bruto com o seu segredo e compare-o com o valor do cabeçalho (a parte após «sha256=»). Use uma comparação em tempo constante e faça sempre o hash do corpo bruto, não de uma versão serializada de novo.
Também recebe X-OWC-Event (o nome do evento) e X-OWC-Delivery (um ID de entrega único que se mantém igual nas novas tentativas, para que o possa usar para eliminar duplicados). Os pedidos são enviados 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 o 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
O seu endpoint deve responder com um estado 2xx o mais rapidamente possível e, no máximo, em 10 segundos. Qualquer resposta não-2xx, timeout ou erro de ligação é tratado como uma tentativa falhada.
As entregas falhadas 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 a falhar 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. Devolver HTTP 410 (Gone) desativa o endpoint de imediato.
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 (numa fila), para não exceder o tempo limite.
- Use X-OWC-Delivery para eliminar duplicados, porque a mesma entrega pode ser repetida após uma falha temporária.
- Disponibilize o seu endpoint através de HTTPS.
- Ignore os tipos de evento desconhecidos, para que os novos eventos que adicionarmos mais tarde não afetem a sua integração.
Pronto para começar? Ver planos ou abra Configurações → Webhooks no seu painel.