Помощен център
Chat API

Уебхукове (Webhooks)

Последна актуализация:

Общ преглед на Webhooks

Чрез уебхукове (webhooks) ChatLab известява Вашите системи в момента, в който нещо се случи във Вашите чатботове. Вместо да правите периодични заявки към Management API или да експортирате данни ръчно, Вие регистрирате HTTPS крайна точка (endpoint), а ChatLab изпраща подписана HTTP POST заявка към нея в реално време - когато посетител остави lead, изпрати контактна форма, оцени разговор, поиска връзка с оператор или когато се изпълни AI действие.

Типични приложения:

  • прехвърляне на нови лийдове директно във Вашата CRM система още в момента на тяхното събиране
  • уведомяване на екипа Ви в Slack, когато посетител заяви чат на живо (live chat)
  • подаване на оценки и обобщения на разговорите към Вашите собствени аналитични инструменти
  • наблюдение на изпълнението на AI действия (AI actions) и предупреждения при грешки

Наличност: акаунтът Ви трябва да включва функцията Webhooks.

Къде се конфигурира: в административния панел отворете Account settings -> Webhooks (Настройки на акаунта -> Webhooks, точно до секцията за Management API). Уебхуковете са на ниво акаунт - една крайна точка може да получава събития от всички Ваши ботове или само от един избран бот.

Настройване на крайна точка

  1. Отворете Account settings -> Webhooks (Настройки на акаунта -> Уебхукове) и кликнете върху Add endpoint (Добавяне на крайна точка).
  2. Попълнете формуляра за крайната точка:
    • Name (Име) - етикет за Ваша собствена справка, напр. "CRM sync" или "Slack alerts".
    • URL - HTTPS адресът, към който ChatLab ще изпраща събитията чрез POST заявка.
    • Events (Събития) - изберете кои типове събития да получава тази крайна точка (вижте каталога по-долу). Изберете само това, от което се нуждаете; събития с голям обем като ai_action.executed могат да генерират значителен трафик.
    • Bot filter (Филтър по бот) (по избор) - изберете един бот или All bots (Всички ботове) за всички ботове във Вашия акаунт.
    • Custom form filter (Филтър за персонализирани формуляри) (по избор) - пренасочва изпратените данни от определен персонализиран формуляр към тази крайна точка. Това филтрира само събитието custom_form.submitted; всяко друго събитие, за което сте се абонирали (лийдове, запитвания за контакт, разговори, чат на живо, AI действия), се доставя независимо от тази настройка.
  3. Изпратете формуляра. Тайната на крайната точка (secret) се показва точно веднъж в диалоговия прозорец за успех - копирайте я веднага и я съхранявайте на сигурно място. Тя ще Ви е необходима за проверка на подписите (вижте раздела Сигурност по-долу). Текстът в явен вид не може да бъде възстановен по-късно.

Всяка крайна точка разполага и с:

  • Превключвател за активиране/деактивиране (Enable/disable) - спира временно доставките, без да изтрива крайната точка. Деактивираните крайни точки отхвърлят събитията тихомълком (те не се нареждат на опашка за по-късно).
  • Send sample event (Изпращане на тестово събитие) - доставя подписана тестова заявка към Вашия URL адрес, за да можете да тествате приемника си от край до край. Можете да изберете типа събитие и да редактирате примерните стойности преди изпращане, така че обработващият Ви модул да вижда реалистични данни. Тестът пристига като стандартна доставка с eventType, съответстващ на Вашия избор (или като webhook.test за обикновена проверка на свързаността).
  • Roll secret (Генериране на нов таен ключ) - генерира нова тайна и анулира старата. Използвайте това, ако тайната може да е била компрометирана. Новата тайна отново се показва само веднъж. За контролирана ротация поставете на пауза крайната точка, генерирайте и копирайте новата тайна, актуализирайте приемника, след което я активирайте отново и изпратете тестово събитие. Събитията по време на паузата не се нареждат на опашка. Планирайте това прекъсване преди ротацията.
  • Delivery log (Дневник на доставките) - списък с последните доставки за конкретната крайна точка с времево клеймо, тип събитие, HTTP статус, върнат от Вашия сървър, и време за отговор. Неуспешните доставки и паузите от предпазния прекъсвач (circuit breaker) се виждат тук. Дневникът се съхранява 14 дни.

Обвивка на събитието (Event envelope)

Всяко доставяне представлява HTTP POST със Content-Type: application/json. Тялото винаги има една и съща обвивка; обектът data е специфичен за съответния тип събитие:

{
  "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 - уникален за всяко събитие. Използвайте го за дедупликация, ако обработката Ви трябва да бъде идемпотентна.
  • eventType - един от типовете, описани по-долу; изпраща се и в хедъра X-ChatLab-Event.
  • timestamp - ISO 8601 UTC време на подготовка на обвивката за доставка.
  • botId / botName - ботът, към когото принадлежи събитието.
  • conversationId / sessionId - контекстът на разговора, когато е приложимо.

Каталог със събития

lead.created

Задейства се, когато посетител изпрати своите данни за контакт - чрез формуляра за събиране на лийдове, предварителния формуляр за чат на живо или персонализиран формуляр, използван за събиране на лийдове.

{
  "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 - как са били събрани данните за контакт: LEAD_COLLECTION_FORM (формуляр за събиране на лийдове), LIVE_CHAT_FORM (предварителен формуляр за чат на живо), CONVERSATION (изкуственият интелект е прихванал данните по време на чата), ADMIN_DATA_UPDATE или UPDATE_CLIENT_CONTEXT (редактирано от страна на ChatLab). Изпращанията през формуляра за връзка с оператор никога не задействат това събитие - вместо него те задействат contact_form.submitted.
  • email, name, phone - данните за контакт, съпоставени със записа на лийда.
  • Когато за събиране на лийдове се използва персонализиран формуляр, всяко поле, дефинирано в него, се включва в fields, по реда на формуляра, а formCodeName / formName идентифицират формуляра. При класическия формуляр за лийдове и двете са null, а fields е празен масив.
  • Всеки запис в fields е {name, value, type}. name е техническото име на полето, което остава постоянно дори при промяна на етикета - използвайте го за съпоставяне във Вашата CRM система.
  • За полета от тип multichoice стойността value е масив от избраните опции. Полетата за отметка (checkbox) са отделни записи със стойности "true" / "false".
  • За полета от тип file стойността value е връзка за изтегляне на качения файл; webhook никога не пренася съдържанието на файла директно.
  • pageUrl - страницата, на която се е намирал посетителят в момента на изпращане.

contact_form.submitted

Задейства се, когато посетител изпрати формуляра за връзка с оператор или персонализиран формуляр, предназначен за контакт с човек.

{
  "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 - адресът, оставен от посетителя, на който Вашият екип за поддръжка трябва да отговори.
  • source - CUSTOM_FORM, когато зад формата за контакт стои персонализиран формуляр, или CONTACT_FORM за вградения формуляр.
  • formCodeName / formName - идентифицират персонализирания формуляр зад заявката; и двете са null за вградения формуляр.
  • Когато се използва персонализиран формуляр, всяко дефинирано в него поле се включва в fields (в същия формат {name, value, type} като при lead.created). При вградения формуляр за контакт се попълват само email и message, fields е празен масив, а идентификаторите на формуляра са null.
  • message - съпоставеното поле за съобщение или всички попълнени стойности, обединени заедно, ако във формуляра няма изрично дефинирано поле за съобщение.

custom_form.submitted

Задейства се при всяко изпращане на персонализиран формуляр, независимо от целта му. Имайте предвид, че формулярите, чиято цел е събиране на лийдове или връзка с човек, също така задействат своето специализирано събитие lead.created / contact_form.submitted - абонирайте се за едното или за другото в зависимост от това дали искате общ или специализиран изглед, за да не създавате дублирани бизнес действия. Двете семейства събития имат различни идентификатори на събитието; комбинацията от conversationId и timestamp не е надежден идентификатор на изпращането.

{
  "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 - постоянното служебно име на формуляра, което не се променя при преименуването му; използвайте го за насочване на данните във Вашата собствена система. formName е видимият етикет, показван на посетителите.
  • fields използва същите записи {name, value, type} като lead.created: стойностите с множествен избор са масиви, а стойностите за файлове са връзки за изтегляне.
  • purpose - STANDALONE, LEAD_COLLECTION или HUMAN_CONTACT, в зависимост от начина, по който формулярът е свързан с чатбота.

conversation.started

Задейства се, когато посетител изпрати първото съобщение в нов разговор.

{
  "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 - точният текст на първото съобщение на посетителя. null, ако разговорът е отворен без съдържание на съобщението.
  • chatSource - каналът, през който е постъпил разговорът: WIDGET, WHATSAPP, MESSENGER, VOICE, VOICE_PHONE, API, BOOKING, AIRBNB или IDOBOOKING.
  • byAdmin - true, когато разговорът идва от предварителния преглед на чатбота в административния панел на ChatLab, а не от реален посетител. Използвайте го, за да филтрирате собствените си тестови чатове от Вашата CRM система.
  • countryCode - код на държавата по ISO, определен от IP адреса на посетителя; null, когато не може да бъде установен.
  • ipAddress - IP адресът на посетителя, отчетен от ChatLab; null, когато липсва. Третирайте го като лични данни според GDPR и го съхранявайте само при наличие на законово основание.

conversation.rated

Задейства се, когато посетител изпрати положителна или отрицателна оценка за разговора (вижте Оценка на разговор).

{
  "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 или NEGATIVE. Изчистването на оценка не задейства събитието, така че никога не получавате неутрална стойност.

conversation.summarized

Задейства се, когато ChatLab генерира резюме на приключил разговор.

{
  "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 - генерираният текст на резюмето. Генерирането на резюме е асинхронно и зависи от конфигурацията за обобщаване и графика на обработка на бота; не очаквайте фиксирано време за доставка.
  • language - вътрешната езикова променлива (locale) на бота, подадена за обобщаването, например en_US; не приемайте, че тя задължително съвпада с езика на разговора на посетителя.

client.summarized

Задейства се, когато ChatLab актуализира AI профила на клиент. Профилът се пресъздава въз основа на предишния профил и резюмето на току-що приключилия разговор, като може да бъде генериран след conversation.summarized. Редът на доставка не е гарантиран. Данните съдържат имейл адрес, когато такъв е известен, но ChatLab може да съхранява и клиенти без посочен имейл.

{
  "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 - идентификаторът за напасване на клиента с Вашата CRM система. Стойността е null за анонимни посетители, които никога не са оставяли адрес, като събитието все пак се задейства и за тях - пренебрегвайте тези доставки, ако интеграцията Ви разчита на имейл.
  • client - записът за контакт, с който ChatLab разполага за това лице: email, name, phone, countryCode и ipAddress. Всеки ключ присъства винаги; неизвестните стойности са null.
  • clientSummary - пълният текст на профила като обикновен текст, а не като разлика (diff). Той замества предишното резюме, така че го записвайте с презаписване, а не с добавяне.
  • Профилът се пресъздава само за ботове с включена памет за чат и само за разговори, които са били неактивни достатъчно дълго, за да бъдат обобщени - очаквайте това събитие няколко минути след края на разговора, а не веднага.

live_chat.requested

Задейства се, когато изкуственият интелект прехвърли разговора към чат на живо (Live Chat) - независимо дали посетителят е поискал връзка с оператор, или ботът е преценил, че е необходима човешка намеса.

{
  "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 - в момента винаги е със стойност AI, тъй като прехвърлянето винаги се задейства от действието за чат на живо на бота, включително когато посетителят го заяви в свободен текст. Третирайте го като отворено изброяване (enum): предвидете обработка на неизвестни стойности, вместо да разчитате твърдо на AI.
  • Това събитие отразява действието на AI, заявяващо прехвърляне, а не всеки възможен начин, по който посетител може да отвори чат на живо. То не е доказателство, че оператор се е включил.

live_chat.started

Задейства се, когато сесията за чат на живо бъде създадена след изпращане на формуляра за прехвърляне от страна на посетителя. В този момент операторът може още да не се е присъединил или да не е отговорил; не го третирайте като доказателство за реално човешко взаимодействие.

{
  "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 умишлено е празно. Всичко необходимо се съдържа в общата структура (envelope): botId идентифицира чатбота, а conversationId / sessionId свързват събитието със самия разговор. Възможно е да го получите без предхождащо live_chat.requested, например когато посетителят е използвал директния бутон за чат на живо в уиджета.

live_chat.ended

Задейства се, когато сесията в чата на живо приключи.

{
  "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 - изтеклата продължителност на сесията в чата на живо, изчислена от момента на създаването ѝ, включително времето за изчакване на оператор. Полето се пропуска в редките случаи, когато дадена сесия приключи, без изобщо да е била започната.

ai_action.executed

Задейства се всеки път, когато ботът изпълни AI действие (AI action) - управлявано извикване на интеграция или персонализирана API функция. Това събитие генерира голям обем трафик: активен бот в електронната търговия може да изпълнява стотици действия дневно, а единична реплика на посетител може да задейства няколко. Абонирайте се за него на отделен краен адрес (endpoint) или се уверете, че Вашият приемник може да поеме обема.

{
  "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 - името на изпълненото действие според изкуствения интелект, например search_products за управлявана интеграция или името, което сте задали на персонализирано API действие.
  • status - SUCCESS или ERROR.
  • durationMs - времетраенето на действието в милисекунди. Полезно за откриване на бавна интеграция, преди посетителите да започнат да се оплакват.
  • errorMessage - причината за неуспеха, попълнена само когато status е ERROR; в противен случай е null.

webhook.test

Изпраща се от бутона Send sample event (Изпращане на тестово събитие), когато извършвате обикновена проверка на свързаността. Подписва се точно както реално събитие.

{
  "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 - фиксиран текст, винаги един и същ. Полетата в структурата съдържат примерни стойности, така че никога не третирайте получено събитие webhook.test като реални данни.
  • Това е единственият тип събитие, за което не можете да се абонирате на краен адрес: то се изпраща при поискване от административния панел и винаги достига до адреса, за който сте кликнали, независимо кои събития слуша той.

Сигурност: проверка на доставките

Всяка доставка съдържа четири заглавни части (headers):

Заглавна част Стойност
X-ChatLab-Signature sha256=<hex hmac> - HMAC-SHA256 подпис на полезния товар
X-ChatLab-Timestamp Unix време в секунди, когато доставката е била подписана
X-ChatLab-Event Видът на събитието, напр. lead.created
X-ChatLab-Delivery Уникален идентификатор на доставката, равен на eventId от тялото

Подписът се изчислява като HMAC-SHA256 върху низа {timestamp}.{rawBody} чрез тайния ключ на Вашата крайна точка (endpoint secret), където {timestamp} е стойността на X-ChatLab-Timestamp, а {rawBody} е суровото, непарснато тяло на заявката. Винаги проверявайте спрямо суровите байтове - повторното сериализиране на парснат JSON ще промени последователността от байтове и ще наруши подписа.

За да се предпазите от атаки чрез повторение (replay attacks), отхвърляйте доставки, чийто X-ChatLab-Timestamp е по-стар от 5 минути.

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

Ако проверката е неуспешна, отговорете с 401 и отхвърлете полезния товар. Никога не обработвайте непотвърдени доставки - всеки, който открие Вашия URL адрес, може да изпрати произволен JSON чрез POST към него.

Поведение при доставяне

Запознайте се с тези правила за доставяне, преди да изграждате интеграции с уебхукове:

  • Отговаряйте бързо. Вашата крайна точка (endpoint) трябва да отговори в рамките на 3 секунди, в противен случай доставянето се счита за неуспешно. Проверете подписа, добавете събитието надеждно в опашка и потвърдете с 2xx в този времеви прозорец. Изпълнявайте по-бавните CRM заявки и бизнес обработка асинхронно.
  • Fire-and-forget, най-много веднъж (at-most-once). Съответстващите активирани крайни точки получават най-много един опит за доставяне - няма повторни опити. Паузираните крайни точки и отворените предпазни вериги (circuit breakers) могат да предотвратят дори този опит. Ако крайната Ви точка е недостъпна, просрочи времето за отговор или върне статус, различен от 2xx, това събитие се губи и няма да бъде доставено повторно. Уебхуковете са известия, а не репликирано хранилище на данни: използвайте Крайни точки на Bot Talk API за разговори или експорт на лийдове, за да сверявате запазените данни, където това се поддържа. Management API покрива настройките и използването на бота, а не пълен архив на събитията. Някои събития не могат да бъдат възстановени чрез тези интерфейси.
  • Предпазна верига (Circuit breaker). След 5 последователни неуспешни доставяния за двойка крайна точка/бот, доставянията за тази двойка се паузират за 5 минути. Събитията, възникнали по време на паузата, се отхвърлят, а журналът за доставяния показва записи CIRCUIT_OPEN за идентифициране на потиснатите опити. Доставянията, пропуснати поради отворена предпазна верига, не се броят за автоматично деактивиране.
  • Автоматично деактивиране. Проверката се извършва в момента на неуспешно доставяне, никога по график с таймер. Ако доставянето е неуспешно и няма успешно доставяне в продължение на 7 дни - броено от последния успех или от датата на създаване на крайната точка, ако никога не е имала успех - крайната точка се изключва и Вие получавате известие по имейл. Един-единствен 2xx във всеки един момент нулира този брояч. Крайна точка, която не получава трафик, никога не се деактивира, тъй като нищо не се проваля. Активирайте я отново от настройките на акаунта (Account settings), след като оправите Вашия приемник; броячът на грешките и отметката за автоматично деактивиране се изчистват при повторно включване, а пропуснатите събития, докато е била изключена, не се наваксват.
  • 410 Gone. Ако Вашата крайна точка отговори с HTTP 410 Gone, ChatLab я деактивира незабавно. Използвайте това, за да изведете крайна точка от експлоатация програмно от страната на получателя.
  • Идемпотентност. Повтарящи се доставяния не се очакват при нормална работа, но ако Вашата обработка трябва да бъде строго идемпотентна, премахвайте дубликатите по eventId (наличен и в заглавката X-ChatLab-Delivery).

Редът на доставяне не е гарантиран. Запазвайте ID на събитието и направете бизнес обработката идемпотентна. Поддържайте собствени политики за съхранение и контрол на достъпа за полезния товар (payload) на уебхуковете, който може да съдържа лични данни и връзки за изтегляне на файлове.

Примерите за подпис използват Node.js crypto и hash_equals на PHP. Прихващайте суровото тяло на заявката (raw request body), преди да го обработите (parse).

Ограничения

  • До 10 крайни точки за уебхукове на акаунт.
  • Съхранение на дневника за доставки: 14 дни. По-старите записи се изтриват автоматично.

Свързани статии

  • Lead collection (Събиране на лийдове) - формулярът зад lead.created
  • Human Support Contact form (Формуляр за връзка с човешка поддръжка) - формулярът зад contact_form.submitted
  • Live Chat - работният процес зад събитията live_chat.*
  • Conversation rating (Оценка на разговор) - оценяването с палец нагоре/надолу зад conversation.rated
  • AI Actions (Действия на AI) - интеграциите зад ai_action.executed
  • Chat API - извиквания за обратна връзка (callbacks) от уиджета в браузъра (клиентски еквивалент на уебхуковете)
  • Management API - REST API за управление на ботове и данни за потреблението