Centro de Ajuda
Chat API

Webhooks

Última atualização:

Descrição geral dos webhooks

Os webhooks permitem que o ChatLab notifique os seus sistemas no momento em que algo acontece nos seus chatbots. Em vez de consultar repetidamente a Management API ou exportar dados manualmente, regista um endpoint HTTPS e o ChatLab envia um HTTP POST assinado para o mesmo em tempo real - quando um visitante deixa um lead, envia um formulário de contacto, classifica uma conversa, solicita um operador humano ou quando uma ação de IA é executada.

Utilizações comuns:

  • enviar novos leads diretamente para o seu CRM no segundo em que são recolhidos
  • notificar a sua equipa no Slack quando um visitante solicita chat em tempo real
  • alimentar as suas próprias ferramentas de análise com classificações e resumos de conversas
  • monitorizar execuções de ações de IA e alertar sobre erros

Disponibilidade: a sua conta tem de incluir a funcionalidade Webhooks.

Onde configurar: na aplicação de administração, abra Account settings -> Webhooks (Definições da conta -> Webhooks, logo ao lado da secção da Management API). Os webhooks estão ao nível da conta - um endpoint pode receber eventos de todos os seus bots ou de um bot selecionado.

Configurar um endpoint

  1. Abra Account settings -> Webhooks e clique em Add endpoint (Adicionar endpoint).
  2. Preencha o formulário do endpoint:
    • Name (Nome) - uma etiqueta para sua referência interna, por exemplo "Sincronização de CRM" ou "Alertas do Slack".
    • URL - o endereço HTTPS para o qual o ChatLab enviará os eventos através de POST.
    • Events (Eventos) - selecione os tipos de eventos que este endpoint recebe (consulte o catálogo abaixo). Selecione apenas o que necessita; eventos de volume elevado como ai_action.executed podem gerar muito tráfego.
    • Bot filter (Filtro de bot) (opcional) - selecione um bot, ou All bots (Todos os bots) para todos os bots da sua conta.
    • Custom form filter (Filtro de formulário personalizado) (opcional) - encaminha os envios de um formulário personalizado para este endpoint. Restringe apenas o evento custom_form.submitted; todos os outros eventos que subscrever (leads, pedidos de contacto, conversas, chat em tempo real, ações de IA) são entregues independentemente desta definição.
  3. Submeta. O secret (segredo) do endpoint é mostrado exatamente uma vez na caixa de diálogo de sucesso - copie-o agora e guarde-o em segurança. Irá necessitar dele para verificar assinaturas (consulte a secção Segurança abaixo). O texto simples não pode ser recuperado mais tarde.

Cada endpoint também possui:

  • Controlo para ativar/desativar - pause os envios sem eliminar o endpoint. Os endpoints desativados descartam eventos silenciosamente (não ficam em fila de espera para mais tarde).
  • Send sample event (Enviar evento de exemplo) - envia um pedido de teste assinado para o seu URL, permitindo validar o seu recetor de ponta a ponta. Pode selecionar o tipo de evento e editar os valores de exemplo antes de enviar, para que o seu processador receba dados realistas. O teste chega como um envio normal com eventType correspondente à sua seleção (ou como webhook.test para uma simples verificação de conectividade).
  • Roll secret (Renovar segredo) - gera um novo segredo e invalida o antigo. Utilize esta opção se o segredo puder ter sido divulgado. O novo segredo é novamente apresentado apenas uma vez. Para uma rotação controlada, pause o endpoint, renove e copie o novo segredo, atualize o recetor e, em seguida, volte a ativar e envie um evento de exemplo. Os eventos que ocorram durante a pausa não ficam em fila de espera. Planeie esta interrupção antes de efetuar a rotação.
  • Delivery log (Registo de envios) - uma lista por endpoint com os envios recentes, incluindo o carimbo de data/hora, tipo de evento, estado HTTP devolvido pelo seu servidor e tempo de resposta. Os envios com falha e as pausas por circuit breaker são visíveis aqui. O registo é conservado durante 14 dias.

Envelope do evento

Cada envio é um HTTP POST com Content-Type: application/json. O corpo tem sempre o mesmo envelope; o objeto data é específico de cada tipo de evento:

{
  "eventId": "9f1c1c8e-6a2b-4b9e-9d2f-3f8a1e2b4c5d",
  "eventType": "lead.created",
  "timestamp": "2026-08-13T14:22:31Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": { }
}
  • eventId - único por evento. Utilize-o para deduplicação se o seu processamento tiver de ser idempotente.
  • eventType - um dos tipos documentados abaixo; também enviado no cabeçalho X-ChatLab-Event.
  • timestamp - hora UTC em formato ISO 8601 em que o envelope de envio foi preparado.
  • botId / botName - o bot ao qual o evento pertence.
  • conversationId / sessionId - o contexto da conversa, quando aplicável.

Catálogo de eventos

lead.created

É acionado quando um visitante envia os seus detalhes de contacto - através do formulário de recolha de leads, do pré-formulário de live chat ou de um formulário personalizado utilizado para a recolha de leads.

{
  "eventId": "9f1c1c8e-6a2b-4b9e-9d2f-3f8a1e2b4c5d",
  "eventType": "lead.created",
  "timestamp": "2026-08-13T14:22:31Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "email": "jane.doe@example.com",
    "name": "Jane Doe",
    "phone": "+1 555 0123",
    "source": "LEAD_COLLECTION_FORM",
    "formCodeName": "lead_form",
    "formName": "Lead form",
    "fields": [
      {"name": "email", "value": "jane.doe@example.com", "type": "email"},
      {"name": "company", "value": "Acme Inc.", "type": "text"},
      {"name": "topics", "value": ["Billing", "Delivery"], "type": "multichoice"},
      {"name": "attachment", "value": "https://api.chatlab.com/aichat/customform/download?key=...&token=...", "type": "file"}
    ],
    "pageUrl": "https://acme.com/pricing"
  }
}
  • source - como os detalhes de contacto foram recolhidos: LEAD_COLLECTION_FORM (formulário de recolha de leads), LIVE_CHAT_FORM (pré-formulário de live chat), CONVERSATION (a IA recolheu os detalhes durante o chat), ADMIN_DATA_UPDATE ou UPDATE_CLIENT_CONTEXT (editado do lado do ChatLab). Os envios do formulário de suporte humano nunca acionam este evento - em vez disso, acionam contact_form.submitted.
  • email, name, phone - os detalhes de contacto mapeados no registo da lead.
  • Quando um formulário personalizado é utilizado para recolha de leads, todos os campos definidos nesse formulário são incluídos em fields, pela ordem do formulário, e formCodeName / formName identificam o formulário. Com o formulário de leads clássico, ambos são null e fields é um array vazio.
  • Cada entrada em fields é {name, value, type}. name é o nome técnico do campo, inalterado após edições do rótulo - utilize-o para fazer o mapeamento para o seu CRM.
  • Para campos multichoice, value é um array das opções selecionadas. Os campos de caixa de verificação são entradas individuais com valores "true" / "false".
  • Para campos file, value é uma ligação de transferência para o ficheiro enviado; o webhook nunca transporta o conteúdo dos ficheiros.
  • pageUrl - a página onde o visitante se encontrava quando submeteu o formulário.

contact_form.submitted

É acionado quando um visitante envia o formulário de contacto para suporte humano ou um formulário personalizado utilizado para contacto humano.

{
  "eventId": "3a7b9c2d-1e4f-4a6b-8c0d-5e2f7a9b1c3d",
  "eventType": "contact_form.submitted",
  "timestamp": "2026-08-13T14:25:02Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "email": "jane.doe@example.com",
    "message": "I need help with my last invoice.",
    "source": "CUSTOM_FORM",
    "formCodeName": "contact_form",
    "formName": "Contact form",
    "fields": [
      {"name": "email", "value": "jane.doe@example.com", "type": "email"},
      {"name": "order_number", "value": "A-10293", "type": "text"},
      {"name": "message", "value": "I need help with my last invoice.", "type": "textarea"}
    ]
  }
}
  • email - o endereço que o visitante indicou e para o qual a sua equipa de suporte deve responder.
  • source - CUSTOM_FORM quando um formulário personalizado suporta o formulário de contacto, CONTACT_FORM para o formulário integrado.
  • formCodeName / formName - identificam o formulário personalizado por trás do pedido; ambos são null para o formulário integrado.
  • Quando é utilizado um formulário personalizado, todos os campos definidos nesse formulário são incluídos em fields (mesmo formato {name, value, type} que em lead.created). Com o formulário de contacto integrado, apenas email e message são preenchidos, fields é um array vazio e os identificadores do formulário são null.
  • message - o campo de mensagem mapeado, ou todos os valores preenchidos agregados quando o formulário não define nenhum campo de mensagem.

custom_form.submitted

É acionado para todos os envios de formulários personalizados, independentemente da finalidade do formulário. Tenha em atenção que os formulários cuja finalidade é a recolha de leads ou o contacto humano também acionam o seu evento dedicado lead.created / contact_form.submitted - subscreva um ou outro dependendo se pretende a vista genérica ou especializada, em vez de criar ações de negócio duplicadas. As duas famílias de eventos têm IDs de evento diferentes; conversationId em conjunto com timestamp não é um identificador de submissão fiável.

{
  "eventId": "6c1d8e3f-2a5b-4c7d-9e0f-1a4b6c8d0e2f",
  "eventType": "custom_form.submitted",
  "timestamp": "2026-08-13T14:27:45Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "formCodeName": "warranty_claim",
    "formName": "Warranty claim",
    "fields": [
      {"name": "order_number", "value": "A-10293", "type": "text"},
      {"name": "issue", "value": "Damaged on arrival", "type": "textarea"},
      {"name": "photo", "value": "https://api.chatlab.com/aichat/customform/download?key=...&token=...", "type": "file"}
    ],
    "purpose": "STANDALONE"
  }
}
  • formCodeName - o nome técnico estável do formulário, que não se altera ao mudar o nome do formulário; utilize-o para encaminhar submissões no seu próprio sistema. formName é o rótulo de apresentação apresentado aos visitantes.
  • fields utiliza as mesmas entradas {name, value, type} que lead.created: valores de escolha múltipla são arrays, valores de ficheiro são ligações de transferência.
  • purpose - STANDALONE, LEAD_COLLECTION ou HUMAN_CONTACT, dependendo de como o formulário está associado ao chatbot.

conversation.started

É acionado quando um visitante envia a primeira mensagem de uma nova conversa.

{
  "eventId": "8e2f0a4b-3c6d-4e8f-a1b2-2c5d7e9f1a3b",
  "eventType": "conversation.started",
  "timestamp": "2026-08-13T14:20:11Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "firstMessage": "Do you ship to Canada?",
    "chatSource": "WIDGET",
    "byAdmin": false,
    "countryCode": "PL",
    "ipAddress": "83.12.44.7"
  }
}
  • firstMessage - o texto exato da mensagem inicial do visitante. null se a conversa tiver sido iniciada sem conteúdo de mensagem.
  • chatSource - o canal através do qual a conversa chegou: WIDGET, WHATSAPP, MESSENGER, VOICE, VOICE_PHONE, API, BOOKING, AIRBNB ou IDOBOOKING.
  • byAdmin - true quando a conversa tem origem na pré-visualização do chatbot dentro do painel de administração do ChatLab e não de um visitante real. Utilize este campo para manter os seus próprios chats de teste fora do seu CRM.
  • countryCode - código de país ISO obtido a partir do endereço IP do visitante, null quando não for possível determinar.
  • ipAddress - o endereço IP do visitante identificado pelo ChatLab, null quando indisponível. Trate-o como dados pessoais ao abrigo do RGPD e guarde-o apenas se tiver uma base de licitude.

conversation.rated

É acionado quando um visitante envia uma avaliação positiva ou negativa da conversa (consulte Conversation rating (Avaliação de conversas)).

{
  "eventId": "1b4c6d8e-5f0a-4b2c-8d3e-4f7a9b1c3d5e",
  "eventType": "conversation.rated",
  "timestamp": "2026-08-13T14:31:09Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "rating": "POSITIVE"
  }
}
  • rating - POSITIVE ou NEGATIVE. A remoção de uma avaliação não aciona o evento, pelo que nunca receberá um valor neutro.

conversation.summarized

É acionado quando o ChatLab gera um resumo de uma conversa concluída.

{
  "eventId": "4d7e9f1a-6b2c-4d4e-9f0a-5b8c0d2e4f6a",
  "eventType": "conversation.summarized",
  "timestamp": "2026-08-13T14:45:00Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "summary": "Visitor asked about shipping to Canada and delivery times. The bot confirmed availability and quoted 5-7 business days. Visitor left satisfied.",
    "language": "en_US"
  }
}
  • summary - o texto do resumo gerado. A geração do resumo é assíncrona e depende da configuração de resumos do bot e do calendário de processamento; não assuma um atraso de entrega fixo.
  • language - o locale interno do bot transmitido à sumarização, por exemplo en_US; não assuma que este valor corresponde ao idioma da conversa do visitante.

client.summarized

É acionado quando o ChatLab atualiza o perfil de IA de um cliente. O perfil é reconstruído a partir do perfil anterior mais o resumo da conversa que acabou de terminar, podendo ser gerado após conversation.summarized. A ordem de entrega não é garantida. O payload inclui um e-mail quando este é conhecido, mas o ChatLab também pode manter clientes sem e-mail.

{
  "eventId": "b5d8f1a3-7c2e-4d9b-a6f0-1e3c5a7b9d2f",
  "eventType": "client.summarized",
  "timestamp": "2026-08-18T09:12:04Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "clientEmail": "jane.doe@example.com",
    "client": {
      "email": "jane.doe@example.com",
      "name": "Jane Doe",
      "phone": "+1 555 0123",
      "countryCode": "PL",
      "ipAddress": "83.12.44.7"
    },
    "clientSummary": "Returning customer interested in international shipping. Asked about delivery times to Canada twice and about return costs once."
  }
}
  • clientEmail - o identificador para associar o cliente ao seu próprio CRM. É null para visitantes anónimos que nunca tenham deixado um endereço, e o evento continuará a ser acionado para eles - ignore estas entregas se a sua integração depender do e-mail como chave.
  • client - o registo de contacto que o ChatLab mantém para esta pessoa: email, name, phone, countryCode e ipAddress. Todas as chaves estão sempre presentes; valores desconhecidos são null.
  • clientSummary - o texto completo do perfil em texto simples, não uma diferença (diff). Substitui o resumo anterior na totalidade, pelo que deve guardá-lo substituindo o valor existente em vez de anexar.
  • O perfil é reconstruído apenas para bots com a funcionalidade de memória de chat ativada e apenas para conversas que estiveram inativas durante tempo suficiente para serem resumidas - conte receber este evento minutos após o fim da conversa, não imediatamente.

live_chat.requested

É acionado quando a IA transfere a conversa para o live chat, seja porque o visitante pediu um operador humano ou porque o bot decidiu que era necessária assistência humana.

{
  "eventId": "7a0b2c4d-8e3f-4a5b-b0c1-6d9e1f3a5b7c",
  "eventType": "live_chat.requested",
  "timestamp": "2026-08-13T14:33:20Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "requestedBy": "AI"
  }
}
  • requestedBy - atualmente sempre AI, porque a transferência é sempre acionada pela ação de live chat do bot, mesmo quando o visitante a solicita em linguagem natural. Trate este campo como um enum aberto: processe valores desconhecidos em vez de validar estritamente por AI.
  • Este evento cobre a ação da IA que solicita a transferência, não todas as formas pelas quais um visitante pode abrir o live chat. Não serve de prova de que um operador tenha entrado na conversa.

live_chat.started

É acionado quando a sessão de live chat é criada após o envio do formulário de transferência do visitante. Isto acontece antes de um operador necessariamente entrar ou responder; não trate isto como prova de envolvimento humano.

{
  "eventId": "0c3d5e7f-9a4b-4c6d-a1b2-7e0f2a4b6c8d",
  "eventType": "live_chat.started",
  "timestamp": "2026-08-13T14:33:55Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {}
}
  • data está intencionalmente vazio. Tudo o que necessita encontra-se no envelope: botId identifica o chatbot e conversationId / sessionId associam o evento à conversa. Pode recebê-lo sem um live_chat.requested anterior, por exemplo quando o visitante utilizou o controlo de live chat do widget.

live_chat.ended

É acionado quando a sessão de live chat termina.

{
  "eventId": "2e5f7a9b-0c5d-4e7f-b2c3-8f1a3b5c7d9e",
  "eventType": "live_chat.ended",
  "timestamp": "2026-08-13T14:52:41Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "durationSeconds": 1126
  }
}
  • durationSeconds - duração decorrida da sessão de live chat, contabilizada a partir da criação da sessão, incluindo o tempo de espera por um operador. O campo é omitido no caso raro de uma sessão terminar sem nunca ter sido iniciada.

ai_action.executed

É acionado sempre que o bot executa uma ação de IA - uma chamada a uma integração gerida ou uma função personalizada da API. Este é um evento de volume elevado: um bot de e-commerce ativo pode executar centenas de ações por dia, e uma única intervenção do visitante pode desencadear várias. Subscreva este evento num endpoint dedicado ou certifique-se de que o seu recetor consegue absorver o volume.

{
  "eventId": "5f8a0b2c-1d6e-4f8a-c3d4-9a2b4c6d8e0f",
  "eventType": "ai_action.executed",
  "timestamp": "2026-08-13T14:21:03Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "actionName": "search_products",
    "status": "SUCCESS",
    "durationMs": 842,
    "errorMessage": null
  }
}
  • actionName - o nome da ação executada tal como a IA o vê, por exemplo search_products para uma integração gerida ou o nome atribuído a uma ação personalizada da API.
  • status - SUCCESS ou ERROR.
  • durationMs - quanto tempo a ação demorou, em milissegundos. Útil para identificar uma integração lenta antes de os visitantes se queixarem dela.
  • errorMessage - o motivo da falha, preenchido apenas quando status for ERROR; caso contrário, é null.

webhook.test

Enviado pelo botão Send sample event (Enviar evento de exemplo) quando efetua uma simples verificação de conectividade. É assinado exatamente como um evento real.

{
  "eventId": "9b2c4d6e-3f8a-4b0c-d5e6-0b3c5d7e9f1a",
  "eventType": "webhook.test",
  "timestamp": "2026-08-13T14:10:00Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "message": "Test delivery from ChatLab"
  }
}
  • message - texto fixo, sempre o mesmo. Os campos do envelope contêm valores de exemplo, pelo que nunca deve tratar uma entrega de webhook.test como dados reais.
  • Este é o único tipo de evento que não pode subscrever num endpoint: é enviado a pedido a partir do painel de administração e chega sempre ao endpoint no qual clicou, independentemente dos eventos que este escuta.

Segurança: verificar entregas

Cada entrega transporta quatro cabeçalhos:

Cabeçalho Valor
X-ChatLab-Signature sha256=<hex hmac> - assinatura HMAC-SHA256 do payload
X-ChatLab-Timestamp Horário Unix em segundos de quando a entrega foi assinada
X-ChatLab-Event O tipo de evento, ex.: lead.created
X-ChatLab-Delivery ID único de entrega, igual ao eventId do corpo

A assinatura é calculada como HMAC-SHA256 sobre a cadeia {timestamp}.{rawBody} utilizando o segredo do seu endpoint, onde {timestamp} é o valor de X-ChatLab-Timestamp e {rawBody} é o corpo em bruto e não analisado do pedido. Verifique sempre em relação aos bytes em bruto - voltar a serializar JSON já processado alterará a sequência de bytes e invalidará a assinatura.

Para se proteger contra ataques de repetição, rejeite entregas cujo X-ChatLab-Timestamp tenha mais de 5 minutos.

Node.js

const crypto = require('crypto');

function verifyChatLabSignature(req, secret) {
    const signature = req.headers['x-chatlab-signature'];
    const timestamp = req.headers['x-chatlab-timestamp'];
    if (typeof signature !== 'string' || typeof timestamp !== 'string') return false;
    if (!/^\d+$/.test(timestamp) || !Number.isSafeInteger(Number(timestamp))) return false;
    if (!Buffer.isBuffer(req.rawBody)) return false;

    // Reject stale deliveries (older than 5 minutes)
    const ageSeconds = Math.abs(Date.now() / 1000 - Number(timestamp));
    if (ageSeconds > 300) return false;

    // rawBody must be the raw request body bytes, not re-serialized JSON.
    // With Express: app.use(express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }))
    const expected = 'sha256=' + crypto
        .createHmac('sha256', secret)
        .update(timestamp + '.')
        .update(req.rawBody)
        .digest('hex');

    const a = Buffer.from(signature);
    const b = Buffer.from(expected);
    return a.length === b.length && crypto.timingSafeEqual(a, b);
}

PHP

<?php
function verifyChatLabSignature(string $secret): bool
{
    $signature = $_SERVER['HTTP_X_CHATLAB_SIGNATURE'] ?? '';
    $timestamp = $_SERVER['HTTP_X_CHATLAB_TIMESTAMP'] ?? '';
    if ($signature === '' || $timestamp === '' || !ctype_digit($timestamp)) {
        return false;
    }

    // Reject stale deliveries (older than 5 minutes)
    if (abs(time() - (int) $timestamp) > 300) {
        return false;
    }

    $rawBody = file_get_contents('php://input');
    $expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);

    return hash_equals($expected, $signature);
}

Se a verificação falhar, responda com 401 e descarte o payload. Nunca processe entregas não verificadas - qualquer pessoa que descubra o seu URL pode enviar pedidos POST com JSON arbitrário para o mesmo.

Comportamento de entrega

Compreenda estas regras de entrega antes de efetuar integrações com webhooks:

  • Responda rapidamente. O seu endpoint tem de responder no prazo de 3 segundos, caso contrário a entrega é considerada falhada. Valide a assinatura, coloque o evento em fila de espera de forma duradoura e confirme com 2xx dentro dessa janela temporal. Execute chamadas mais lentas ao CRM e processamentos de negócio de forma assíncrona.
  • Fire-and-forget, no máximo uma vez. Os endpoints ativos correspondentes recebem no máximo uma tentativa de entrega - não existem novas tentativas. Endpoints pausados e circuitos abertos podem suprimir até essa mesma tentativa. Se o seu endpoint estiver inacessível, exceder o tempo limite ou devolver um estado diferente de 2xx, esse evento perde-se e não será reenviado. Os webhooks são notificações e não um armazenamento de dados replicado: utilize os endpoints de conversa da Bot Talk API ou exportações de leads para reconciliar os dados mantidos, onde tal for suportado. A Management API abrange as definições e a utilização do bot, não um arquivo completo de eventos. Alguns eventos não podem ser reconstruídos através destas interfaces.
  • Disjuntor (circuit breaker). Após 5 falhas consecutivas de entrega para um par de endpoint/bot, as entregas para esse par são pausadas durante 5 minutos. Os eventos que ocorram durante a pausa são descartados, e o registo de entregas apresenta entradas CIRCUIT_OPEN para identificar as tentativas suprimidas. As entregas ignoradas por um circuito aberto não contam para a desativação automática.
  • Desativação automática. A verificação é executada no momento em que uma entrega falha, nunca com base num temporizador. Se uma entrega falhar e não tiver ocorrido qualquer entrega bem-sucedida durante 7 dias - contados a partir do último sucesso ou da data de criação do endpoint, caso nunca tenha tido sucesso - o endpoint é desativado e recebe uma notificação por e-mail. Uma única resposta 2xx em qualquer momento reinicia essa contagem. Um endpoint que não receba tráfego nunca é desativado, porque nada falha. Volte a ativá-lo nas Account settings (Definições de conta) assim que o seu recetor estiver corrigido; o contador de falhas e a marcação de desativação automática são repostos ao voltar a ligá-lo, e os eventos perdidos enquanto esteve desligado não são repostos retroativamente.
  • 410 Gone. Se o seu endpoint responder com o código HTTP 410 Gone, o ChatLab desativa-o imediatamente. Utilize isto para desativar programaticamente um endpoint a partir do sistema recetor.
  • Idempotência. Não se esperam entregas duplicadas em funcionamento normal, mas se o seu processamento tiver de ser estritamente idempotente, proceda à desduplicação através do eventId (também disponível no cabeçalho X-ChatLab-Delivery).

A ordem de entrega não é garantida. Guarde o ID do evento e garanta que o processamento de negócio é idempotente. Mantenha os seus próprios controlos de retenção e de acesso para os payloads dos webhooks, que podem conter dados pessoais e ligações para transferência de ficheiros.

Os exemplos de assinatura utilizam o Node.js crypto e a função hash_equals do PHP. Capture o corpo do pedido em formato não processado (raw) antes de o analisar.

Limites

  • Até 10 endpoints de webhook por conta.
  • Retenção do registo de entregas: 14 dias. As entradas mais antigas são removidas automaticamente.

Artigos relacionados