Centrum nápovědy
Chat API

Webhooks

Poslední aktualizace:

Přehled webhooků

Webhooky umožňují službě ChatLab informovat vaše systémy v okamžiku, kdy se v chatbotech něco stane. Místo dotazování Management API nebo ručního exportu dat zaregistrujete HTTPS endpoint a ChatLab na něj v reálném čase odešle podepsaný HTTP POST - když návštěvník zanechá lead, odešle kontaktní formulář, ohodnotí konverzaci, požádá o lidského operátora nebo když se spustí AI akce.

Typická využití:

  • odesílání nových leadů přímo do vašeho CRM ihned po jejich získání
  • upozornění týmu ve Slacku, když návštěvník požádá o live chat
  • předávání hodnocení a shrnutí konverzací do vašich vlastních analytických nástrojů
  • sledování spouštění AI akcí a upozorňování na chyby

Dostupnost: váš účet musí obsahovat funkci Webhooks.

Kde nastavit: v administraci otevřete Account settings -> Webhooks (Nastavení účtu -> Webhooks, hned vedle sekce Management API). Webhooky jsou na úrovni účtu - jeden endpoint může přijímat události ze všech vašich botů nebo z jednoho vybraného bota.

Nastavení endpointu

  1. Otevřete Account settings -> Webhooks (Nastavení účtu -> Webhooky) a klikněte na Add endpoint (Přidat endpoint).
  2. Vyplňte formulář endpointu:
    • Name (Název) - označení pro vaši vlastní potřebu, např. "CRM sync" nebo "Slack alerts".
    • URL - adresa HTTPS, na kterou bude ChatLab odesílat události metodou POST.
    • Events (Události) - vyberte, které typy událostí má tento endpoint přijímat (viz katalog níže). Vybírejte pouze to, co potřebujete; vysoce frekventované události jako ai_action.executed mohou generovat velký provoz.
    • Bot filter (Filtr botů) (volitelné) - vyberte jednoho bota, nebo All bots (Všichni boti) pro všechny boty na vašem účtu.
    • Custom form filter (Filtr vlastního formuláře) (volitelné) - směruje odeslání jednoho vlastního formuláře na tento endpoint. Zužuje pouze událost custom_form.submitted; všechny ostatní odebírané události (leady, žádosti o kontakt, konverzace, live chat, akce AI) se doručují bez ohledu na toto nastavení.
  3. Formulář odešlete. Secret (tajný klíč) endpointu se zobrazí přesně jednou v potvrzovacím dialogu - ihned jej zkopírujte a bezpečně uložte. Budete jej potřebovat k ověřování podpisů (viz Zabezpečení níže). V čitelné podobě jej později nelze znovu získat.

Každý endpoint obsahuje také:

  • Přepínač pro aktivaci/deaktivaci (Enable/disable) - pozastaví doručování bez nutnosti endpoint smazat. Deaktivované endpointy události bez upozornění zahazují (nezařazují se do fronty na později).
  • Send sample event (Odeslat ukázkovou událost) - doručí na vaši URL podepsaný testovací požadavek, abyste si mohli ověřit svůj přijímač end-to-end. Před odesláním můžete vybrat typ události a upravit vzorové hodnoty, aby váš handler zpracovával realistická data. Test dorazí jako běžné doručení s eventType odpovídajícím vašemu výběru (nebo jako webhook.test pro jednoduchou kontrolu spojení).
  • Roll secret (Vygenerovat nový tajný klíč) - vygeneruje nový tajný klíč a zneplatní ten starý. Použijte tuto možnost, pokud mohlo dojít k úniku klíče. Nový tajný klíč se opět zobrazí pouze jednou. Pro řízenou rotaci endpoint pozastavte, vygenerujte a zkopírujte nový tajný klíč, aktualizujte svůj přijímač, poté endpoint znovu aktivujte a odešlete ukázkovou událost. Události vzniklé během pozastavení se nezařazují do fronty. Před rotací s tímto přerušením počítejte.
  • Delivery log (Záznam doručování) - seznam nedávných doručení pro daný endpoint s časovým razítkem, typem události, HTTP kódem vráceným vaším serverem a dobou odezvy. Neúspěšná doručení a pozastavení způsobená jističem (circuit breaker) jsou viditelná zde. Záznam se uchovává po dobu 14 dnů.

Obálka události

Každé doručení probíhá přes HTTP POST s Content-Type: application/json. Tělo zprávy má vždy stejnou obálku; objekt data je specifický pro daný typ události:

{
  "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 - unikátní pro každou událost. Použijte jej pro deduplikaci, pokud vaše zpracování musí být idempotentní.
  • eventType - jeden z typů popsaných níže; odesílá se také v hlavičce X-ChatLab-Event.
  • timestamp - čas v UTC dle normy ISO 8601, kdy byla obálka pro doručení připravena.
  • botId / botName - bot, ke kterému událost patří.
  • conversationId / sessionId - kontext konverzace, pokud existuje.

Katalog událostí

lead.created

Spouští se, když návštěvník odešle své kontaktní údaje - prostřednictvím formuláře pro sběr leadů, předběžného formuláře pro live chat nebo vlastního formuláře použitého pro sběr leadů.

{
  "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 - způsob získání kontaktních údajů: LEAD_COLLECTION_FORM (formulář pro sběr leadů), LIVE_CHAT_FORM (předběžný formulář pro live chat), CONVERSATION (AI zachytila údaje během konverzace), ADMIN_DATA_UPDATE nebo UPDATE_CLIENT_CONTEXT (upraveno na straně ChatLabu). Odeslání formuláře zákaznické podpory tuto událost nikdy nespouští - místo toho vyvolá contact_form.submitted.
  • email, name, phone - kontaktní údaje namapované na záznam leadu.
  • Při použití vlastního formuláře pro sběr leadů je každé pole definované v tomto formuláři zahrnuto v fields, a to v pořadí z formuláře; formCodeName / formName identifikují daný formulář. U klasického formuláře pro leady jsou obě hodnoty null a fields je prázdné pole.
  • Každá položka v fields má formát {name, value, type}. name představuje technický název pole, který se nemění ani při úpravě popisku - použijte jej pro mapování do vašeho CRM.
  • U polí typu multichoice je value polem (array) vybraných možností. Zaškrtávací pole představují samostatné položky s hodnotami "true" / "false".
  • U polí typu file je value odkazem ke stažení nahraného souboru; webhook nikdy nepřenáší samotný obsah souboru.
  • pageUrl - stránka, na které se návštěvník při odeslání nacházel.

contact_form.submitted

Spouští se, když návštěvník odešle kontaktní formulář podpory nebo vlastní formulář určený ke kontaktování podpory.

{
  "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 - adresa, kterou návštěvník zanechal a na kterou má váš tým podpory odpovědět.
  • source - CUSTOM_FORM, pokud kontaktní formulář vychází z vlastního formuláře, a CONTACT_FORM pro výchozí vestavěný formulář.
  • formCodeName / formName - identifikují vlastní formulář stojící za požadavkem; pro vestavěný formulář mají obě hodnotu null.
  • Při použití vlastního formuláře je každé pole v něm definované zahrnuto v fields (ve stejném formátu {name, value, type} jako u lead.created). U vestavěného kontaktního formuláře jsou vyplněny pouze email a message, fields je prázdné pole a identifikátory formuláře mají hodnotu null.
  • message - namapované pole se zprávou, případně všechny vyplněné hodnoty spojené dohromady, pokud formulář pole se zprávou nedefinuje.

custom_form.submitted

Spouští se při každém odeslání vlastního formuláře bez ohledu na jeho účel. Formuláře určené pro sběr leadů nebo kontaktování podpory navíc vyvolávají i svou vyhrazenou událost lead.created / contact_form.submitted - přihlaste se k odběru jedné nebo druhé podle toho, zda potřebujete obecný, nebo specializovaný pohled, abyste nevytvářeli duplicitní akce. Tyto dvě rodiny událostí mají odlišná ID; kombinace conversationId a timestamp nepředstavuje spolehlivý identifikátor odeslání.

{
  "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 - stabilní strojový název formuláře, který se nemění ani při přejmenování; použijte jej pro směrování odeslaných dat ve vlastním systému. formName je popisek zobrazovaný návštěvníkům.
  • fields používá stejné položky {name, value, type} jako lead.created: hodnoty výběru z více možností jsou pole, hodnoty souborů jsou odkazy ke stažení.
  • purpose - STANDALONE, LEAD_COLLECTION nebo HUMAN_CONTACT, podle toho, jak je formulář v chatbotu zapojen.

conversation.started

Spouští se, když návštěvník odešle první zprávu nové konverzace.

{
  "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 - přesný text úvodní zprávy návštěvníka. null, pokud byla konverzace zahájena bez textového obsahu.
  • chatSource - kanál, přes který konverzace přišla: WIDGET, WHATSAPP, MESSENGER, VOICE, VOICE_PHONE, API, BOOKING, AIRBNB nebo IDOBOOKING.
  • byAdmin - true, pokud konverzace pochází z náhledu chatbota v administraci ChatLabu a nikoli od skutečného návštěvníka. Pomůže vám odfiltrovat vlastní testovací chaty z vašeho CRM.
  • countryCode - ISO kód země zjištěný z IP adresy návštěvníka; null, pokud jej nebylo možné určit.
  • ipAddress - IP adresa návštěvníka, jak ji vidí ChatLab; null, pokud není dostupná. Považujte ji za osobní údaj podle GDPR a ukládejte ji pouze s platným právním základem.

conversation.rated

Spouští se, když návštěvník odešle kladné nebo záporné hodnocení konverzace (viz Hodnocení konverzace).

{
  "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 nebo NEGATIVE. Zrušení hodnocení událost nespouští, neutrální hodnotu tedy nikdy neobdržíte.

conversation.summarized

Spouští se, když ChatLab vygeneruje shrnutí ukončené konverzace.

{
  "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 - vygenerovaný text shrnutí. Generování shrnutí probíhá asynchronně a závisí na nastavení shrnutí a plánu zpracování bota; nepočítejte s pevnou prodlevou doručení.
  • language - interní národní prostředí (locale) bota předaný ke shrnutí, například en_US; tato hodnota nemusí odpovídat jazyku konverzace návštěvníka.

client.summarized

Spouští se, když ChatLab aktualizuje AI profil klienta. Profil se sestavuje z předchozího profilu a shrnutí právě ukončené konverzace; může se vygenerovat až po události conversation.summarized. Pořadí doručení není zaručeno. Tělo zprávy (payload) obsahuje e-mail, pokud je znám, ChatLab však může evidovat i klienty bez e-mailu.

{
  "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 - identifikátor pro spárování klienta s vaším CRM. U anonymních návštěvníků, kteří nikdy nezanechali adresu, má hodnotu null, přičemž událost se spouští i pro ně - pokud je vaše integrace vázána na e-mail, tato doručení přeskočte.
  • client - kontaktní záznam, který ChatLab o dané osobě vede: email, name, phone, countryCode a ipAddress. Všechny klíče jsou přítomny vždy; neznámé hodnoty mají hodnotu null.
  • clientSummary - kompletní text profilu jako prostý text, nikoli rozdíl (diff). Nahrazuje veškerá předchozí shrnutí, ukládejte jej proto přepsáním původního záznamu, nikoli připojením na konec.
  • Profil se sestavuje pouze pro boty s povolenou funkcí paměť chatu a pouze pro konverzace, které byly neaktivní dostatečně dlouho na to, aby proběhlo jejich shrnutí - tuto událost očekávejte spíše několik minut po skončení konverzace než okamžitě.

live_chat.requested

Spouští se, když AI předá konverzaci do Live Chat (živého chatu) - ať už proto, že návštěvník požádal o operátora, nebo proto, že bot vyhodnotil přítomnost člověka jako nezbytnou.

{
  "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 - v současnosti vždy AI, protože předání vždy vyvolává akce živého chatu v botu, a to i když o něj návštěvník požádá vlastními slovy. Považujte jej za otevřený výčet: zpracovávejte i neznámé hodnoty namísto striktního ověřování na AI.
  • Tato událost pokrývá akci AI požadující předání, nikoli všechny způsoby, jakými může návštěvník live chat otevřít. Nepředstavuje důkaz, že se operátor skutečně připojil.

live_chat.started

Spouští se, když se po odeslání formuláře pro předání ze strany návštěvníka vytvoří relace live chatu. K tomu dochází dříve, než se operátor nutně připojí nebo odpoví; nepovažujte to za potvrzení zapojení člověka.

{
  "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 je záměrně prázdné. Vše potřebné naleznete v obálce zprávy: botId identifikuje chatbota a conversationId / sessionId propojují událost s danou konverzací. Událost můžete obdržet i bez předchozí live_chat.requested, například když návštěvník použil ovládací prvek pro live chat ve widgetu.

live_chat.ended

Spouští se po ukončení relace live chatu.

{
  "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 - uplynulá doba trvání relace live chatu počítaná od jejího vytvoření, včetně doby čekání na operátora. Pole se vynechává ve vzácných případech, kdy relace skončí, aniž by byla vůbec zahájena.

ai_action.executed

Spouští se při každém provedení akce AI botem - ať už jde o spravované volání integrace, nebo vlastní funkci API. Jedná se o událost s vysokým objemem zpráv: aktivní e-commerce bot dokáže provést stovky akcí denně a jediný dotaz návštěvníka jich může spustit hned několik. Přihlaste se k jejímu odběru na vyhrazeném koncovém bodu nebo zajistěte, aby váš přijímač tento objem zvládl.

{
  "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 - název provedené akce z pohledu AI, například search_products pro spravovanou integraci nebo název, který jste přiřadili vlastní akci API.
  • status - SUCCESS nebo ERROR.
  • durationMs - doba trvání akce v milisekundách. Hodí se pro odhalení pomalé integrace dříve, než si na ni začnou návštěvníci stěžovat.
  • errorMessage - důvod selhání, vyplněný pouze tehdy, když má status hodnotu ERROR; v ostatních případech je null.

webhook.test

Odesílá se tlačítkem Send sample event (Odeslat ukázkovou událost) při běžné kontrole konektivity. Je podepsána naprosto stejně jako skutečná událost.

{
  "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 - pevně daný text, který je vždy stejný. Pole obálky nesou ukázkové hodnoty, proto doručená data s typem webhook.test nikdy nepovažujte za skutečná.
  • Jde o jediný typ události, k jehož odběru se na koncovém bodu nelze přihlásit: odesílá se na vyžádání z administrace a vždy dorazí na koncový bod, na který jste klikli, bez ohledu na to, kterým událostem naslouchá.

Zabezpečení: ověřování doručení

Každé doručení obsahuje čtyři hlavičky:

Hlavička Hodnota
X-ChatLab-Signature sha256=<hex hmac> - podpis HMAC-SHA256 datové zprávy (payloadu)
X-ChatLab-Timestamp Čas Unixu v sekundách, kdy bylo doručení podepsáno
X-ChatLab-Event Typ události, např. lead.created
X-ChatLab-Delivery Jedinečné ID doručení, shodné s eventId v těle zprávy

Podpis se počítá jako HMAC-SHA256 z řetězce {timestamp}.{rawBody} pomocí tajného klíče vašeho koncového bodu (endpoint secret), kde {timestamp} je hodnota X-ChatLab-Timestamp a {rawBody} je nezpracované, neparsované tělo požadavku. Vždy ověřujte proti nezpracovaným (raw) bajtům - opětovná serializace parsovaného JSONu změní sekvenci bajtů a poruší podpis.

Pro ochranu před útoky typu replay odmítněte doručení, jejichž X-ChatLab-Timestamp je starší než 5 minut.

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);
}

Pokud ověření selže, odpovězte s 401 a datovou zprávu zahoďte. Nikdy nezpracovávejte neověřená doručení - kdokoli, kdo zjistí vaši URL, na ni může poslat (POST) libovolný JSON.

Chování při doručování

Před zahájením práce s webhooky se seznamte s těmito pravidly doručování:

  • Odpovídejte rychle. Váš koncový bod musí odpovědět do 3 sekund, jinak je doručení považováno za neúspěšné. Během tohoto časového limitu ověřte podpis, trvale uložte událost do fronty a potvrďte přijetí kódem 2xx. Pomalejší volání CRM a obchodní logiku zpracovávejte asynchronně.
  • Fire-and-forget, nanejvýš jednou (at-most-once). Odpovídající aktivní koncové body mají nanejvýš jeden pokus o doručení - žádná opakování se neprovádějí. Pozastavené koncové body a aktivované ochranné mechanismy (circuit breakers) mohou zamezit i tomuto pokusu. Pokud je váš koncový bod nedostupný, vyprší časový limit nebo vrátí jiný než 2xx stav, událost je ztracena a nebude znovu odeslána. Webhooks slouží jako notifikace, nikoli jako replikované datové úložiště: k porovnání a doplnění uchovávaných dat použijte v podporovaných případech koncové body konverzací v Bot Talk API nebo exporty leadů. Management API slouží pro nastavení bota a využití, nikoli jako kompletní archiv událostí. Některé události nelze přes tato rozhraní zpětně zkonstruovat.
  • Jistič (Circuit breaker). Po 5 po sobě jdoucích neúspěšných doručeních pro danou dvojici koncový bod / bot se doručování pro tuto dvojici pozastaví na 5 minut. Události vzniklé během této pauzy se zahazují a v protokolu doručení se zobrazí záznamy CIRCUIT_OPEN pro identifikaci potlačených pokusů. Doručení přeskočená z důvodu otevřeného jističe se nezapočítávají do automatické deaktivace.
  • Automatická deaktivace (Auto-disable). Kontrola probíhá výhradně v okamžiku selhání doručení, nikdy na základě časovače. Pokud doručení selže a za posledních 7 dní nedošlo k žádnému úspěšnému doručení - počítáno od posledního úspěchu, nebo od data vytvoření koncového bodu, pokud ještě nikdy neuspěl - koncový bod se vypne a vy obdržíte e-mailové oznámení. Jediný stav 2xx v libovolném okamžiku tento časovač resetuje. Koncový bod, který nepřijímá žádný provoz, se nikdy nedeaktivuje, protože u něj nic neselže. Jakmile přijímač opravíte, znovu jej povolte v nastavení účtu (Account settings); počítadlo selhání i časové razítko automatické deaktivace se při opětovném zapnutí vymažou. Události zmeškané během doby vypnutí se zpětně nedoplňují.
  • 410 Gone. Pokud váš koncový bod odpoví kódem HTTP 410 Gone, ChatLab jej okamžitě deaktivuje. Tento postup využijte k programovému vyřazení koncového bodu z provozu na straně příjemce.
  • Idempotence. Duplicitní doručení se při běžném provozu neočekávají, ale pokud vaše zpracování vyžaduje přísnou idempotenci, deduplikujte podle eventId (k dispozici také v záhlaví X-ChatLab-Delivery).

Pořadí doručení není zaručeno. Ukládejte ID události a nastavte obchodní zpracování jako idempotentní. Pro data z webhooků (payloads), která mohou obsahovat osobní údaje a odkazy ke stažení souborů, udržujte vlastní pravidla uchovávání a řízení přístupu.

V příkladech pro ověření podpisu se používá Node.js crypto a funkce hash_equals v PHP. Neupravené tělo požadavku (raw body) zachyťte ještě před jeho zpracováním (parsingem).

Limity

  • Až 10 koncových bodů pro webhooky na jeden účet.
  • Uchovávání protokolů doručení: 14 dní. Starší záznamy se automaticky mažou.

Související články