Webhook apžvalga
Webhook leidžia ChatLab pranešti Jūsų sistemoms tą pačią akimirką, kai kas nors įvyksta Jūsų pokalbių robotuose. Užuot siuntus užklausas į Management API ar eksportavus duomenis rankiniu būdu, Jūs užregistruojate HTTPS galinį tašką (endpoint), o ChatLab siunčia į jį pasirašytą HTTP POST užklausą realiuoju laiku - kai lankytojas palieka kontaktus (lead), pateikia kontaktinę formą, įvertina pokalbį, paprašo žmogaus pagalbos arba kai įvykdomas AI veiksmas.
Tipiniai panaudojimo atvejai:
- persiųsti naujus kontaktus tiesiai į savo CRM tą pačią sekundę, kai jie užfiksuojami
- pranešti komandai Slack platformoje, kai lankytojas paprašo tiesioginio pokalbio (live chat)
- perduoti pokalbių įvertinimus ir santraukas į savo analitikos sistemas
- stebėti AI veiksmų (AI actions) vykdymą ir gauti įspėjimus apie klaidas
Prieinamumas: webhook funkcijos pasiekiamos nuo Standard plano (funkcija: Webhooks).
Kur konfigūruoti: administratoriaus programėlėje atidarykite Account settings -> Webhooks (Paskyros nustatymai -> Webhook; šalia Management API skilties). Webhook veikia paskyros lygiu - vienas galinis taškas gali gauti įvykius iš visų Jūsų robotų arba iš filtruoto jų poaibio.
Galinio taško nustatymas
- Atidarykite Account settings -> Webhooks ir spustelėkite Create endpoint (Sukurti galinį tašką).
- Užpildykite galinio taško formą:
- Name (Pavadinimas) - etiketė Jūsų pačių patogumui, pvz., „CRM sinchronizavimas“ arba „Slack pranešimai“.
- URL - HTTPS adresas, į kurį ChatLab siųs POST įvykius.
- Events (Įvykiai) - pasirinkite, kuriuos įvykių tipus šis galinis taškas turi gauti (žr. katalogą žemiau). Pasirinkite tik tai, ko reikia; didelio srauto įvykiai, tokie kaip
ai_action.executed, gali generuoti daug užklausų. - Bot filter (Roboto filtras) (neprivaloma) - apribokite galinį tašką konkrečiais robotais. Palikite tuščią, jei norite gauti įvykius iš visų Jūsų paskyros robotų.
- Custom form filter (Tinkintos formos filtras) (neprivaloma) - nukreipia vienos tinkintos formos pateikimus į šį galinį tašką. Tai apriboja tik
custom_form.submittedįvykį; visi kiti prenumeruojami įvykiai (kontaktai, susisiekimo užklausos, pokalbiai, tiesioginis pokalbis, AI veiksmai) bus pristatomi nepriklausomai nuo šio nustatymo.
- Pateikite formą. Galinio taško slaptasis raktas (secret) parodomas tik vieną kartą sėkmės lange - nukopijuokite jį dabar ir saugiai išsaugokite. Jo prireiks parašams tikrinti (žr. skiltį „Sauga“ žemiau). Vėliau grynojo teksto peržiūrėti nebebus įmanoma.
Kiekvienas galinis taškas taip pat turi:
- Enable/disable toggle (Įjungimo / išjungimo perjungiklis) - pristatymo pristabdymas neištrinant galinio taško. Išjungti galiniai taškai įvykius tiesiog ignoruoja (jie nėra kaupiami eilėje vėlesniam laikui).
- Send sample event (Siųsti pavyzdinį įvykį) - nusiunčia pasirašytą bandomąją užklausą į Jūsų URL, kad galėtumėte patikrinti visą priėmimo grandinę. Galite pasirinkti įvykio tipą ir prieš siųsdami redaguoti pavyzdines reikšmes, kad gaviklis matytų tikroviškus duomenis. Testas pristatomas kaip įprastas įvykis su Jūsų pasirinktu
eventType(arba kaipwebhook.test, jei atliekamas paprastas ryšio patikrinimas). - Roll secret (Pakeisti slaptąjį raktą) - sugeneruoja naują slaptąjį raktą ir panaikina senojo galiojimą. Naudokite tai, jei kilo įtarimas, kad raktas galėjo nutekėti. Naujas raktas vėl parodomas tik vieną kartą. Prieš keisdami atnaujinkite gaviklio nustatymus, kitaip užklausos neatlaikys parašo patikros Jūsų pusėje.
- Delivery log (Pristatymo žurnalas) - konkretaus galinio taško naujausių pristatymų sąrašas su laiko žyma, įvykio tipu, Jūsų serverio grąžintu HTTP statusu ir atsakymo laiku. Čia matomi nesėkmingi pristatymai ir grandinės pertraukiklio (circuit breaker) pauzės. Žurnalas saugomas 14 dienų.
Įvykio apvalkalas (envelope)
Kiekvienas pristatymas yra HTTP POST užklausa su Content-Type: application/json. Turinys visada turi tą patį apvalkalą; objektas data priklauso nuo konkretaus įvykio tipo:
{
"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- unikalus kiekvienam įvykiui. Naudokite jį dublikatams šalinti (deduplikacijai), jei Jūsų apdorojimas turi būti idempotentiškas.eventType- vienas iš žemiau aprašytų tipų; taip pat siunčiamasX-ChatLab-Eventantraštėje.timestamp- ISO 8601 UTC laikas, kada įvyko įvykis.botId/botName- robotas, kuriam priklauso įvykis.conversationId/sessionId- pokalbio kontekstas, kai taikoma.
Įvykių katalogas
lead.created
Suveikia, kai lankytojas pateikia savo kontaktinius duomenis - per kontaktų surinkimo formą, tiesioginio pokalbio pradinę formą arba tinkintą formą, naudojamą kontaktams rinkti.
{
"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- būdas, kaip buvo užfiksuoti kontaktai:LEAD_COLLECTION_FORM(kontaktų surinkimo forma),LIVE_CHAT_FORM(tiesioginio pokalbio pradinė forma),CONVERSATION(AI suprato ir išsaugojo duomenis pokalbio metu),ADMIN_DATA_UPDATEarbaUPDATE_CLIENT_CONTEXT(redaguota ChatLab pusėje). Pagalbos kreipimosi į žmogų formos pateikimai niekada nesuaktyvina šio įvykio - vietoj to jie aktyvinacontact_form.submitted.email,name,phone- kontaktiniai duomenys, priskirti šiam kontaktų įrašui.- Kai kontaktų rinkimui naudojama tinkinta forma, kiekvienas joje nurodytas laukas įtraukiamas į
fieldsformos nustatyta tvarka, oformCodeName/formNameidentifikuoja formą. Naudojant klasikinę formą, abu yranull, ofieldsyra tuščias masyvas. - Kiekvienas įrašas
fieldsmasyve yra{name, value, type}.nameyra techninis lauko pavadinimas, nekintantis redaguojant etiketę - naudokite jį susiejimui su savo CRM. - Laukuose su
multichoicereikšmėvalueyra pasirinktų parinkčių masyvas. Žymimųjų langelių (checkbox) laukai yra atskiri įrašai su reikšmėmis"true"/"false". - Laukuose su
filereikšmėvalueyra įkelto failo atsisiuntimo nuoroda; webhook pranešime failo turinys niekada nesiunčiamas. pageUrl- puslapis, kuriame lankytojas buvo pateikimo metu.
contact_form.submitted
Suveikia, kai lankytojas pateikia žmogaus pagalbos kontaktinę formą arba tinkintą formą, naudojamą susisiekti su žmogumi.
{
"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- lankytojo paliktas adresas, kuriuo Jūsų palaikymo komanda turėtų atsakyti.source-CUSTOM_FORM, kai kontaktinei formai naudojama tinkinta forma, arbaCONTACT_FORM, kai naudojama integruota forma.formCodeName/formName- nurodo užklausai naudotą tinkintą formą; integruotos formos atveju abu yranull.- Kai naudojama tinkinta forma, visi joje nurodyti laukai įtraukiami į
fields(tokiu pačiu{name, value, type}formatu kaip irlead.created). Su integruota kontaktine forma užpildomi tikemailbeimessage,fieldsyra tuščias masyvas, o formos identifikatoriai yranull. message- priskirtas pranešimo laukas arba visų užpildytų laukų reikšmės, sujungtos kartu, jei formoje nėra atskiro pranešimo lauko.
custom_form.submitted
Suveikia pateikus bet kurią tinkintą formą, nepriklausomai nuo jos paskirties. Atkreipkite dėmesį, kad formos, kurių paskirtis yra kontaktų rinkimas arba susisiekimas su žmogumi, taip pat sukelia joms skirtus įvykius lead.created / contact_form.submitted - pasirinkite vieną ar kitą priklausomai nuo to, ar norite bendro, ar specializuoto vaizdo, ir šalinkite dublikatus pagal conversationId + timestamp, jei prenumeruojate abu.
{
"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- nekintantis sistemos formos pavadinimas, kuris nesikeičia pervardijus formą; naudokite jį duomenų nukreipimui savo sistemoje.formNameyra lankytojams rodomas pavadinimas.fieldsnaudoja tuos pačius{name, value, type}įrašus kaiplead.created: kelių pasirinkimų reikšmės yra masyvai, failų reikšmės yra atsisiuntimo nuorodos.purpose-STANDALONE,LEAD_COLLECTIONarbaHUMAN_CONTACT, priklausomai nuo to, kaip forma susieta su pokalbių robotu.
conversation.started
Suveikia, kai lankytojas išsiunčia pirmąją naujo pokalbio žinutę.
{
"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- tikslus lankytojo pradinės žinutės tekstas.null, jei pokalbis buvo pradėtas be žinutės turinio.chatSource- kanalas, per kurį gautas pokalbis:WIDGET,WHATSAPP,MESSENGER,VOICE,VOICE_PHONE,API,BOOKING,AIRBNBarbaIDOBOOKING.byAdmin-true, kai pokalbis vyksta iš pokalbių roboto peržiūros ChatLab administratoriaus skydelyje, o ne su tikru lankytoju. Naudokite tai, kad bandomieji pokalbiai nepatektų į Jūsų CRM.countryCode- ISO šalies kodas, nustatytas pagal lankytojo IP adresą;null, jei nustatyti nepavyko.ipAddress- lankytojo IP adresas, kurį mato ChatLab;null, jei neprieinamas. Pagal BDAR traktuokite jį kaip asmens duomenis ir saugokite tik turėdami teisinį pagrindą.
conversation.rated
Suveikia, kai lankytojas įvertina roboto atsakymą teigiamai arba neigiamai (žr. Pokalbių vertinimas).
{
"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-POSITIVEarbaNEGATIVE. Įvertinimo atšaukimas šio įvykio nesuaktyvina, todėl neutralios reikšmės niekada negausite.
conversation.summarized
Suveikia, kai ChatLab sugeneruoja baigto pokalbio santrauką.
{
"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- sugeneruotas santraukos tekstas. Santraukos sukuriamos praėjus kelioms minutėms po to, kai pokalbis tampa neaktyvus, todėl šis įvykis atkeliauja vėliau nei kiti pokalbio įvykiai.language- ISO kalbos kodas, kuria parašyta santrauka (atitinka pokalbio kalbą).
client.summarized
Suveikia, kai ChatLab atnaujina kliento AI profilį. Profilis atkuriamas iš ankstesnio profilio ir ką tik pasibaigusio pokalbio santraukos, todėl šis įvykis eina po conversation.summarized tam pačiam pokalbiui. Klientai identifikuojami pagal el. paštą, todėl šis adresas pakartojamas viršutiniame data lygyje.
{
"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- identifikatorius, skirtas susieti klientą su Jūsų CRM. Jis yranullanoniminiams lankytojams, kurie niekada nepaliko adreso; šiems lankytojams įvykis vis tiek suveikia - praleiskite šiuos pristatymus, jei Jūsų integracija paremta el. paštu.client- kontaktinė informacija, kurią ChatLab turi apie šį asmenį:email,name,phone,countryCodeiripAddress. Visi raktai pateikiami visada; nežinomos reikšmės yranull.clientSummary- visas profilio tekstas kaip paprastas tekstas, o ne skirtumai (diff). Jis pakeičia bet kokią buvusią santrauką, todėl išsaugokite jį perrašydami, o ne pridėdami gale.- Profilis atkuriamas tik tiems robotams, kuriuose įjungta pokalbių atmintis (chat memory), ir tik tiems pokalbiams, kurie buvo neaktyvūs pakankamai ilgai, kad būtų apibendrinti - šio įvykio tikėkitės praėjus kelioms minutėms po pokalbio pabaigos, o ne iš karto.
live_chat.requested
Suveikia, kai AI perduoda pokalbį į tiesioginį pokalbį, nes lankytojas paprašė žmogaus pagalbos arba robotas nusprendė, kad žmogus yra būtinas.
{
"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- šiuo metu visadaAI, nes perdavimą visada inicijuoja roboto tiesioginio pokalbio veiksmas, įskaitant atvejus, kai lankytojas to paprašo žodžiais. Traktuokite tai kaip atvirą reikšmių sąrašą (open enum): apdorokite nežinomas reikšmes užuot griežtai reikalavę tikAI.- Įvykis reiškia, kad buvo paprašyta perdavimo, o ne tai, kad operatorius jau prisijungė. Norėdami tai sužinoti, laukite
live_chat.started.
live_chat.started
Suveikia, kai operatorius prisijungia ir realiai prasideda tiesioginio pokalbio sesija.
{
"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": {}
}
datasąmoningai yra tuščias. Viskas, ko reikia, yra apvalkale:botIdidentifikuoja pokalbių robotą, oconversationId/sessionIdsusieja įvykį su pokalbiu, apie kurį jau gavotelive_chat.requested.
live_chat.ended
Suveikia, kai tiesioginio pokalbio sesija baigiasi.
{
"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- kiek laiko operatorius dalyvavo pokalbyje, skaičiuojant nuo sesijos pradžios. Šis laukas praleidžiamas retais atvejais, kai sesija baigiasi taip ir neprasidėjusi.
ai_action.executed
Suveikia kiekvieną kartą, kai robotas įvykdo AI veiksmą - valdomą integracijos iškvietimą arba pasirinktinę API funkciją. Tai didelio srauto įvykis: aktyvus e. prekybos robotas gali atlikti šimtus veiksmų per dieną, o viena lankytojo užklausa gali sukelti kelis veiksmus iš eilės. Užsiprenumeruokite jį atskirame galiniame taške arba įsitikinkite, kad Jūsų gaviklis pajėgus apdoroti tokį srautą.
{
"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- atlikto veiksmo pavadinimas, kaip jį mato AI, pavyzdžiui,search_productsvaldomai integracijai arba Jūsų suteiktas pavadinimas pasirinktiniam API veiksmui.status-SUCCESSarbaERROR.durationMs- veiksmo vykdymo trukmė milisekundėmis. Naudinga norint pastebėti lėtą integraciją dar prieš lankytojams pradedant skųstis.errorMessage- klaidos priežastis; pateikiama tik tada, kaistatusyraERROR; priešingu atveju reikšmė yranull.
webhook.test
Siunčiamas mygtuku Send sample event (Siųsti pavyzdinį įvykį), kai atliekate paprastą ryšio patikrinimą. Pasirašomas lygiai taip pat, kaip ir tikras įvykis.
{
"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- fiksuotas tekstas, visada toks pat. Apvalkalo laukuose pateikiamos pavyzdinės reikšmės, todėl niekada nelaikykitewebhook.testsiuntimo tikrais duomenimis.- Tai vienintelis įvykio tipas, kurio negalite užsiprenumeruoti galiniame taške: jis siunčiamas pagal pareikalavimą iš administratoriaus skydelio ir visada pasiekia tą galinį tašką, kurį spustelėjote, nepriklausomai nuo to, kokių įvykių jis klausosi.
Sauga: pristatymų patvirtinimas
Kiekvienas pristatymas turi keturias antraštes:
| Header | Reikšmė |
|---|---|
X-ChatLab-Signature |
sha256=<hex hmac> - naudingosios apkrovos (payload) HMAC-SHA256 parašas |
X-ChatLab-Timestamp |
„Unix“ laikas sekundėmis, kada pristatymas buvo pasirašytas |
X-ChatLab-Event |
Įvykio tipas, pvz., lead.created |
X-ChatLab-Delivery |
Unikalus pristatymo ID, sutampantis su turinio eventId |
Parašas apskaičiuojamas kaip HMAC-SHA256 eilutei {timestamp}.{rawBody}, naudojant jūsų galutinio taško slaptąjį raktą (secret), kur {timestamp} yra X-ChatLab-Timestamp reikšmė, o {rawBody} yra neapdorotas, neanalizuotas užklausos turinys. Visada tikrinkite pagal neapdorotus (raw) baitus - išanalizuoto JSON pakartotinis serializavimas pakeis baitų seką ir pažeis parašą.
Norėdami apsisaugoti nuo pakartotinio siuntimo atakų (replay attacks), atmeskite pristatymus, kurių X-ChatLab-Timestamp yra senesnis nei 5 minutės.
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);
}
Jei patvirtinimas nepavyksta, atsakykite su 401 ir atmeskite naudingąją apkrovą. Niekada neapdorokite nepatvirtintų pristatymų - bet kas, sužinojęs jūsų URL, gali išsiųsti į jį bet kokį JSON.
Pristatymo elgsena
Prieš kurdami sprendimus su „webhook“, susipažinkite su šiomis garantijomis:
- Atsakykite greitai. Jūsų galutinis taškas turi atsakyti per 3 sekundes, kitaip pristatymas bus laikomas nesėkmingu. Nedelsdami atsakykite
2xxkodu ir apdorokite naudingąją apkrovą asinchroniškai (įdėkite į eilę ir tik tada patvirtinkite) - prieš atsakydami nevykdykite CRM užklausų ar įrašymo į duomenų bazę operacijų. - Išsiųskite ir pamirškite, daugiausiai vieną kartą (at-most-once). Kiekvienas įvykis gauna tiksliai vieną pristatymo bandymą - pakartotinių bandymų nėra. Jei jūsų galutinis taškas neveikia, baigiasi laukimo laikas arba grąžinamas ne
2xxbūsenos kodas, tas įvykis prarandamas ir nebebus pristatytas iš naujo. „Webhook“ yra pranešimai, o ne replikuojama duomenų saugykla: kai reikia garantuoto išsamumo, sutikrinkite duomenis naudodami Management API arba savo kontaktų (leads) eksportus. - Grandinės pertraukiklis (circuit breaker). Po 5 iš eilės nesėkmingų pristatymų vienam botui, to boto pristatymai pristabdomi 5 minutėms. Per šią pauzę įvykę įvykiai atmetami, o pristatymo žurnale rodomi
CIRCUIT_OPENįrašai, kad matytumėte, kada tiksliai ir kodėl srautas buvo sustabdytas. Pristatymai, praleisti dėl atidarytos grandinės, nėra įskaičiuojami į automatinį išjungimą. - Automatinis išjungimas. Tikrinimas vykdomas pristatymo nesėkmės momentu, niekada ne pagal laikmatį. Jei pristatymas nepavyksta ir 7 dienas nebuvo jokio sėkmingo pristatymo - skaičiuojant nuo paskutinio sėkmingo atvejo arba nuo galutinio taško sukūrimo datos, jei sėkmingų pristatymų dar nebuvo, - galutinis taškas išjungiamas, o Jūs gaunate pranešimą el. paštu. Bet kuriuo metu gautas bent vienas
2xxatsakymas iš naujo nustato šį laiką. Galutinis taškas, kuris negauna jokio srauto, niekada neišjungiamas, nes nėra jokių klaidų. Sutvarkę savo gavėją, iš naujo įjunkite jį paskyros nustatymuose (Account settings); iš naujo įjungus, klaidų skaitiklis ir automatinio išjungimo žyma išvalomi, o įvykiai, praleisti kol taškas buvo išjungtas, neatkuriami. - 410 Gone. Jei jūsų galutinis taškas atsako HTTP kodu
410 Gone, „ChatLab“ jį iškart išjungia. Naudokite tai, norėdami programiškai nutraukti galutinio taško veikimą iš gavėjo pusės. - Idempotentiškumas. Įprastai veikiant sistemai pasikartojančių pristatymų nebūna, tačiau jei jūsų apdorojimas turi būti griežtai idempotentinis, pašalinkite dublikatus pagal
eventId(taip pat prieinamąX-ChatLab-Deliveryantraštėje).
Apribojimai
- Iki 10 „webhook“ galutinių taškų vienai paskyrai.
- Pristatymo žurnalo saugojimas: 14 dienų. Senesni įrašai pašalinami automatiškai.
Susiję straipsniai
- Kontaktų rinkimas (Lead collection) - forma, susieta su
lead.created - Pagalbos kreipimosi forma (Human Support Contact form) - forma, susieta su
contact_form.submitted - Live Chat - procesas, susietas su
live_chat.*įvykiais - Pokalbio įvertinimas (Conversation rating) - mygtukai „patinka“ / „nepatinka“, susieti su
conversation.rated - AI veiksmai (AI Actions) - integracijos, susietos su
ai_action.executed - Pokalbių API (Chat API) - naršyklės valdiklio atgalinio iškvietimo funkcijos (kliento pusės alternatyva „webhook“)
- Management API - REST API boto valdymui ir naudojimo duomenims gauti