Súgóközpont
Chat API

Webhooks

Utoljára frissítve:

Webhookok áttekintése

A webhookok lehetővé teszik, hogy a ChatLab értesítse az Ön rendszereit abban a pillanatban, amint valami történik a chatbotjaiban. Ahelyett, hogy folyamatosan lekérdezné a Management API felületét vagy manuálisan exportálna adatokat, Ön regisztrál egy HTTPS-végpontot, és a ChatLab valós időben egy aláírt HTTP POST kérést küld rá - amikor egy látogató leadet hagy hátra, beküld egy űrlapot, értékeli a beszélgetést, emberi segítséget kér, vagy amikor lefut egy AI action.

Jellemző felhasználási módok:

  • az új leadek azonnali továbbítása a CRM-be, amint rögzítésre kerülnek
  • a csapat értesítése a Slackben, amikor egy látogató élő chatet kér
  • a beszélgetések értékeléseinek és összegzéseinek betáplálása a saját analitikai rendszerébe
  • az AI action (AI művelet) végrehajtások monitorozása és hibariasztások küldése

Elérhetőség: a webhookok a Standard csomagtól felfelé érhetők el (funkció: Webhooks).

Hol konfigurálható: az adminisztrációs felületen nyissa meg az Account settings -> Webhooks (Fiókbeállítások -> Webhookok) menüpontot (közvetlenül a Management API szekció mellett). A webhookok fiókszintűek - egy végpont fogadhatja az összes bot eseményeit, vagy azok egy szűrt részhalmazát is.

Végpont beállítása

  1. Nyissa meg az Account settings -> Webhooks (Fiókbeállítások -> Webhookok) menüpontot, majd kattintson a Create endpoint (Végpont létrehozása) gombra.
  2. Töltse ki a végpont űrlapját:
    • Name - egy elnevezés saját használatra, például "CRM sync" vagy "Slack alerts".
    • URL - az a HTTPS-cím, amelyre a ChatLab a POST kéréseket küldi az eseményekkel.
    • Events - válassza ki, mely eseménytípusokat fogadja ez a végpont (lásd az alábbi katalógust). Csak azt válassza ki, amire szüksége van; a nagy forgalmú események, mint például az ai_action.executed, jelentős adatforgalmat generálhatnak.
    • Bot filter (opcionális) - a végpont korlátozása konkrét botokra. Hagyja üresen, ha a fiókjában lévő összes bot eseményeit fogadni szeretné.
    • Custom form filter (opcionális) - egy adott egyéni űrlap beküldéseit irányítja erre a végpontra. Ez kizárólag a custom_form.submitted eseményt szűkíti; minden más esemény, amelyre feliratkozott (leadek, kapcsolatfelvételi kérések, beszélgetések, élő chat, AI actionök), ettől a beállítástól függetlenül kézbesítésre kerül.
  3. Mentse el. A végpont secret (titkos kulcs) pontosan egyszer jelenik meg a sikeres létrehozást jelző ablakban - másolja ki azonnal, és tárolja biztonságosan. Erre szüksége lesz az aláírások ellenőrzéséhez (lásd a Biztonság részt lentebb). A titkos kulcs sima szövegként később már nem kérhető le.

Minden végpont rendelkezik a következőkkel is:

  • Enable/disable toggle - a kézbesítések szüneteltetése a végpont törlése nélkül. A letiltott végpontok némán elvetik az eseményeket (nem kerülnek sorba későbbi kézbesítéshez).
  • Send sample event - egy aláírt tesztkérést küld az URL-címére, így a fogadó oldalt teljes egészében ellenőrizheti. Kiválaszthatja az esemény típusát, és a küldés előtt módosíthatja a mintaértékeket, hogy a feldolgozó kód valósághű adatokat lásson. A teszt normál kézbesítésként érkezik a kiválasztásának megfelelő eventType értékkel (vagy webhook.test típussal egy egyszerű kapcsolódási teszt esetén).
  • Roll secret - új titkos kulcsot hoz létre, és érvényteleníti a régit. Akkor használja, ha a titkos kulcs esetleg kiszivárgott. Az új kulcs szintén csak egyszer jelenik meg. A frissítés előtt frissítse a fogadó rendszert, különben a kézbesítések aláírás-ellenőrzése sikertelen lesz az Ön oldalán.
  • Delivery log - végpontonkénti lista a legutóbbi kézbesítésekről időbélyeggel, eseménytípussal, a szervere által visszaadott HTTP-státusszal és a válaszidővel. A sikertelen kézbesítések és a túláramvédelmi (circuit breaker) szüneteltetések itt láthatók. A naplót 14 napig őrizzük meg.

Eseményburok (envelope)

Minden kézbesítés egy HTTP POST kérés Content-Type: application/json fejléccel. A törzs mindig ugyanolyan burokszerkezettel rendelkezik; a data objektum az esemény típusától függ:

{
  "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 - egyedi azonosító eseményenként. Használja duplikációk szűrésére, ha a feldolgozásnak idempotensnek kell lennie.
  • eventType - az alább dokumentált típusok egyike; az X-ChatLab-Event fejlécben is elküldésre kerül.
  • timestamp - az esemény bekövetkeztének ISO 8601 formátumú UTC ideje.
  • botId / botName - a bot, amelyhez az esemény tartozik.
  • conversationId / sessionId - a beszélgetés kontextusa, amennyiben releváns.

Eseménykatalógus

lead.created

Akkor aktiválódik, amikor egy látogató beküldi az elérhetőségeit - a leadgyűjtő űrlapon, a live chat előűrlapon vagy egy leadgyűjtésre használt egyéni űrlapon keresztül.

{
  "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 - az elérhetőségi adatok megszerzésének módja: LEAD_COLLECTION_FORM (leadgyűjtő űrlap), LIVE_CHAT_FORM (live chat előűrlap), CONVERSATION (az AI rögzítette a beszélgetés során), ADMIN_DATA_UPDATE vagy UPDATE_CLIENT_CONTEXT (a ChatLab oldalán szerkesztve). Az emberi ügyfélszolgálati űrlap kitöltései soha nem ezt az eseményt váltják ki - helyette a contact_form.submitted eseményt aktiválják.
  • email, name, phone - a lead rekordhoz rendelt elérhetőségi adatok.
  • Ha egyéni űrlapot használ leadgyűjtésre, az azon definiált összes mező bekerül a fields tömbbe, az űrlap szerinti sorrendben, a formCodeName / formName pedig azonosítja az űrlapot. A klasszikus lead űrlap esetén mindkettő értéke null, a fields pedig egy üres tömb.
  • A fields minden eleme {name, value, type} felépítésű. A name a mező technikai neve, amely a feliratok módosítása esetén is változatlan marad - használja ezt a CRM-be történő leképezéshez.
  • A multichoice típusú mezőknél a value a kiválasztott opciók tömbje. A jelölőnégyzet mezők külön bejegyzésként szerepelnek "true" / "false" értékkel.
  • A file típusú mezőknél a value a feltöltött fájlra mutató letöltési hivatkozás; a webhook soha nem tartalmazza a tényleges fájltartalmat.
  • pageUrl - az az oldal, amelyen a látogató a beküldés pillanatában tartózkodott.

contact_form.submitted

Akkor aktiválódik, amikor egy látogató beküldi az emberi ügyfélszolgálati kapcsolatfelvételi űrlapot vagy egy emberi kapcsolatfelvételre használt egyéni űrlapot.

{
  "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 - a látogató által megadott e-mail-cím, amelyre az ügyfélszolgálati csapatnak válaszolnia kell.
  • source - CUSTOM_FORM, ha a kapcsolatfelvételi űrlap hátterében egyéni űrlap áll, és CONTACT_FORM a beépített űrlap esetén.
  • formCodeName / formName - a kérés mögött álló egyéni űrlapot azonosítja; a beépített űrlapnál mindkettő null.
  • Egyéni űrlap használata esetén az azon definiált összes mező szerepel a fields listában (ugyanolyan {name, value, type} formátumban, mint a lead.created eseménynél). A beépített kapcsolatfelvételi űrlapnál csak az email és a message mező kerül kitöltésre, a fields üres tömb, az űrlapazonosítók pedig null értékűek.
  • message - a megfeleltetett üzenetmező, vagy az összes kitöltött érték összefűzve, amennyiben az űrlapon nincs külön üzenetmező definiálva.

custom_form.submitted

Minden egyes egyéni űrlap beküldésekor aktiválódik, függetlenül az űrlap céljától. Vegye figyelembe, hogy azok az űrlapok, amelyek célja a leadgyűjtés vagy az emberi kapcsolatfelvétel, a saját dedikált lead.created / contact_form.submitted eseményüket is aktiválják - attól függően iratkozzon fel az egyikre vagy a másikra, hogy az általános vagy a specializált nézetre van szüksége, és szűrje a duplikációkat a conversationId + timestamp alapján, ha mindkettőre feliratkozik.

{
  "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 - az űrlap állandó gépi neve, amely az űrlap átnevezésekor sem változik; használja ezt a beküldések saját rendszerében történő irányítására. A formName a látogatóknak megjelenített felirat.
  • A fields ugyanazokat a {name, value, type} elemeket használja, mint a lead.created: a multichoice értékek tömbök, a fájlértékek letöltési hivatkozások.
  • purpose - STANDALONE, LEAD_COLLECTION vagy HUMAN_CONTACT, attól függően, hogyan van az űrlap bekötve a chatbotba.

conversation.started

Akkor aktiválódik, amikor egy látogató elküldi egy új beszélgetés első üzenetét.

{
  "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 - a látogató nyitó üzenetének pontos szövege. Értéke null, ha a beszélgetést üzenettartalom nélkül nyitották meg.
  • chatSource - a csatorna, amelyen a beszélgetés érkezett: WIDGET, WHATSAPP, MESSENGER, VOICE, VOICE_PHONE, API, BOOKING, AIRBNB vagy IDOBOOKING.
  • byAdmin - értéke true, ha a beszélgetés a ChatLab adminisztrációs felületén belüli chatbot-előnézetből származik, nem pedig valódi látogatótól. Ezzel kiszűrheti a saját tesztbeszélgetéseit a CRM-ből.
  • countryCode - a látogató IP-címéből feloldott ISO országkód; null, ha nem sikerült meghatározni.
  • ipAddress - a látogató ChatLab által látott IP-címe; null, ha nem érhető el. Kezelje személyes adatként a GDPR szerint, és csak akkor tárolja, ha rendelkezik hozzá jogalappal.

conversation.rated

Akkor aktiválódik, amikor egy látogató felfelé vagy lefelé mutató hüvelykujjal értékeli a bot válaszát (lásd: Beszélgetés értékelése).

{
  "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 vagy NEGATIVE. Az értékelés visszavonása nem aktiválja az eseményt, így soha nem kap semleges értéket.

conversation.summarized

Akkor aktiválódik, amikor a ChatLab összefoglalót generál egy befejezett beszélgetésről.

{
  "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"
  }
}
  • summary - a generált összefoglaló szöveg. Az összefoglalók néhány perccel azután készülnek el, hogy a beszélgetés inaktívvá válik, így ez az esemény később érkezik meg, mint a többi beszélgetési esemény.
  • language - annak a nyelvnek az ISO-kódja, amelyen az összefoglaló készült, követve a beszélgetés nyelvét.

client.summarized

Akkor aktiválódik, amikor a ChatLab frissíti egy ügyfél AI profilját. A profil az előző profilból és a most véget ért beszélgetés összefoglalójából épül újra, így ez az esemény ugyanarra a beszélgetésre vonatkozóan a conversation.summarized után következik. Az ügyfeleket az e-mail-címük azonosítja, ezért az e-mail-cím a data legfelső szintjén is megismétlődik.

{
  "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 - az ügyfél saját CRM-mel történő párosítására szolgáló azonosító. Értéke null olyan névtelen látogatóknál, akik soha nem adtak meg e-mail-címet - az esemény számukra is lefut, ezért ugorja át ezeket a kézbesítéseket, ha az integrációja az e-mail-címen alapul.
  • client - a személy ChatLab által nyilvántartott kapcsolati adatai: email, name, phone, countryCode és ipAddress. Minden kulcs mindig jelen van; az ismeretlen értékek null értékűek.
  • clientSummary - a teljes profilszöveg sima szövegként, nem diffként. Felülírja a korábbi összefoglalót, ezért hozzáfűzés helyett felülírással tárolja el.
  • A profil csak azoknál a botoknál épül újra, amelyeknél engedélyezve van a chat memory (chatmemória), és csak olyan beszélgetéseknél, amelyek elég ideig voltak inaktívak az összegzéshez - erre az eseményre percekkel a beszélgetés vége után számítson, nem pedig azonnal.

live_chat.requested

Akkor aktiválódik, amikor az AI átadja a beszélgetést az élő chatnek, akár azért, mert a látogató emberi segítséget kért, akár azért, mert a bot úgy döntött, hogy emberre van szükség.

{
  "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 - jelenleg mindig AI, mivel az átadást mindig a bot élő chat művelete kezdeményezi, még akkor is, ha a látogató egyszerű szöveges üzenetben kéri azt. Kezelje nyílt értékkészletként (open enum): kezelje az ismeretlen értékeket is ahelyett, hogy kizárólag az AI érték meglétére támaszkodna.
  • Az esemény azt jelzi, hogy az átadás kérése megtörtént, nem pedig azt, hogy egy operátor átvette a beszélgetést. Ehhez várja meg a live_chat.started eseményt.

live_chat.started

Akkor aktiválódik, amikor egy operátor csatlakozik, és az élő chat munkamenet ténylegesen elkezdődik.

{
  "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": {}
}
  • A data szándékosan üres. Minden szükséges információ megtalálható a burokban: a botId azonosítja a chatbotot, a conversationId / sessionId pedig ahhoz a beszélgetéshez köti az eseményt, amelyhez korábban már megkapta a live_chat.requested eseményt.

live_chat.ended

Akkor aktiválódik, amikor az élő chat munkamenet véget ér.

{
  "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 - az az időtartam másodpercben, ameddig az operátor a beszélgetésben tartózkodott, a munkamenet kezdetétől számítva. A mező kimarad abban a ritka esetben, ha a munkamenet úgy ér véget, hogy el sem kezdődött.

ai_action.executed

Minden alkalommal lefut, amikor a bot végrehajt egy AI action hívást - egy menedzselt integrációs hívást vagy egy egyéni API-funkciót. Ez egy nagy forgalmú esemény: egy aktív e-kereskedelmi bot naponta több száz műveletet is végrehajthat, és a látogató egyetlen üzenetváltása is többet aktiválhat. Érdemes dedikált végponton feliratkozni rá, vagy meggyőződni arról, hogy a fogadó rendszer képes kezelni ezt a volument.

{
  "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 - a végrehajtott művelet neve az AI által látott formában, például search_products egy menedzselt integrációnál, vagy az az elnevezés, amelyet egy egyéni API actionnek adott.
  • status - SUCCESS vagy ERROR.
  • durationMs - a művelet lefutási ideje ezredmásodpercben (ms). Hasznos a lassú integrációk észlelésére, még mielőtt a látogatók panaszkodnának rá.
  • errorMessage - a hiba oka, amely csak akkor kerül kitöltésre, ha a status értéke ERROR; egyébként null.

webhook.test

A Send sample event (Mintaesemény küldése) gomb küldi ki, amikor egy egyszerű kapcsolódási tesztet hajt végre. Pontosan úgy van aláírva, mint egy valós esemény.

{
  "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 - fix szöveg, mindig ugyanaz. A burok mezői mintaértékeket tartalmaznak, ezért soha ne kezelje a webhook.test kézbesítést valós adatként.
  • Ez az egyetlen eseménytípus, amelyre nem lehet feliratkozni egy végponton: igény szerint küldhető az adminisztrációs felületről, és mindig megérkezik arra a végpontra, amelyre rákattintott, függetlenül attól, hogy az milyen eseményeket figyel.

Biztonság: kézbesítések ellenőrzése

Minden kézbesítés négy fejlécet tartalmaz:

Fejléc Érték
X-ChatLab-Signature sha256=<hex hmac> - A payload HMAC-SHA256 aláírása
X-ChatLab-Timestamp Unix időbélyeg másodpercben, amikor a kézbesítést aláírták
X-ChatLab-Event Az esemény típusa, pl. lead.created
X-ChatLab-Delivery Egyedi kézbesítési azonosító, megegyezik a törzs eventId értékével

Az aláírás a {timestamp}.{rawBody} karakterláncon végrehajtott HMAC-SHA256 számításként jön létre a végpont titkos kulcsának (secret) használatával, ahol a {timestamp} a X-ChatLab-Timestamp értéke, a {rawBody} pedig a kérés nyers, feldolgozatlan törzse. Mindig a nyers bájtokkal szemben végezze el az ellenőrzést - az értelmezett JSON újra-szerializálása megváltoztatja a bájtsorrendet, és érvényteleníti az aláírást.

A visszajátszásos támadások (replay attacks) elleni védelem érdekében utasítsa el azokat a kézbesítéseket, amelyek X-ChatLab-Timestamp értéke 5 percnél régebbi.

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 (!signature || !timestamp) 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 + '.' + 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 === '') {
        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);
}

Ha az ellenőrzés sikertelen, válaszoljon 401 kóddal, és vesse el a payloadot. Soha ne dolgozzon fel ellenőrizetlen kézbesítéseket - bárki, aki rátalál az Ön URL-jére, tetszőleges JSON-t küldhet rá POST kéréssel.

Kézbesítési működés

Mielőtt webhookokra építene, ismerje meg ezeket a garanciákat:

  • Válaszoljon gyorsan. Végpontjának 3 másodpercen belül válaszolnia kell, különben a kézbesítés sikertelennek minősül. Küldjön azonnal 2xx választ, és a payloadot aszinkron módon dolgozza fel (tegye sorba, majd igazolja vissza) - ne végezzen CRM-hívásokat vagy adatbázisba írást a válaszadás előtt.
  • Fire-and-forget, legfeljebb egyszeri kézbesítés (at-most-once). Minden esemény pontosan egy kézbesítési kísérletet kap - nincsenek újrapróbálkozások. Ha a végpont nem elérhető, túllépi az időkorlátot, vagy nem 2xx státuszkódot ad vissza, az az esemény elvész, és nem kerül újra kiküldésre. A webhookok értesítések, nem pedig replikált adattárak: ha garantált teljességre van szüksége, végezzen egyeztetést a Management API vagy a leadexportok segítségével.
  • Áramköri megszakító (circuit breaker). Ha egy bot esetében egymás után 5 sikertelen kézbesítés történik, a kézbesítések az adott botnál 5 percre szünetelnek. A szünet alatt bekövetkező események elvesznek, a kézbesítési naplóban pedig CIRCUIT_OPEN bejegyzések jelennek meg, így pontosan láthatja, mikor és miért állt le a forgalom. A nyitott áramkör miatt kihagyott kézbesítések nem számítanak bele az automatikus letiltásba.
  • Automatikus letiltás. Az ellenőrzés mindig egy kézbesítés meghiúsulásának pillanatában fut le, soha nem időzítő alapján. Ha egy kézbesítés meghiúsul, és 7 napja nem történt sikeres kézbesítés - az utolsó sikertől számítva, vagy a végpont létrehozásának dátumától, ha még sosem volt sikeres -, a rendszer kikapcsolja a végpontot, és Ön e-mail értesítést kap. Bármely pillanatban érkező egyetlen 2xx válasz visszaállítja ezt az órát. Az a végpont, amely nem kap forgalmat, soha nem kerül letiltásra, mert semmi sem hibásodik meg. Miután a fogadó oldalt kijavította, engedélyezze újra az Account settings (Fiókbeállítások) menüpontban; a hibaszámláló és az automatikus letiltási jelzés a visszakapcsoláskor törlődik, a kikapcsolt állapot alatt kimaradt események utólagos pótlására pedig nem kerül sor.
  • 410 Gone. Ha a végpontja HTTP 410 Gone kóddal válaszol, a ChatLab azonnal letiltja azt. Ezzel a módszerrel programozottan, a fogadó oldalról vonhat ki egy végpontot a forgalomból.
  • Idempotencia. Normál működés mellett nem várhatóak duplikált kézbesítések, de ha a feldolgozásnak szigorúan idempotensnek kell lennie, szűrje ki a duplikációkat az eventId alapján (ez az X-ChatLab-Delivery fejlécben is elérhető).

Korlátok

  • Fiókonként legfeljebb 10 webhook-végpont.
  • Kézbesítési napló megőrzési ideje: 14 nap. A régebbi bejegyzések automatikusan törlődnek.

Kapcsolódó cikkek