Webhooki
Webhooki pozwalają Your AI Connector automatycznie powiadamiać inne narzędzia biznesowe, gdy wydarzy się coś ważnego — utworzenie nowego kontaktu, umówienie spotkania czy otrzymanie wiadomości. Zamiast ręcznie sprawdzać aktualizacje, połączone systemy otrzymują natychmiastowe powiadomienie w momencie, gdy coś się wydarzy.
Czym są webhooki?
Pomyśl o webhooku jak o automatycznej wiadomości tekstowej między dwiema aplikacjami. Gdy coś wydarzy się w Your AI Connector (np. zarejestruje się nowy kontakt), platforma natychmiast wysyła powiadomienie do wybranego przez Ciebie systemu. Podajesz adres internetowy (zwany „adresem URL webhooka”), na który mają być wysyłane te powiadomienia — zazwyczaj jest on dostarczany przez Twój system CRM, platformę do automatyzacji lub programistę.
Webhooki wysyłają dane WYŁĄCZNIE z Your AI Connector. Webhook to droga jednokierunkowa z Your AI Connector do Twoich innych narzędzi. Nie istnieje adres URL webhooka, który przesyłałby leady, kontakty lub wiadomości DO platformy. Aby wprowadzić nowy lead — z formularza na stronie internetowej, systemu CRM lub GoHighLevel — Twój system wykonuje zamiast tego wywołanie API. Zobacz Dostęp do API (operacja Utwórz kontakt) oraz Lejki. Jedyną rzeczą potrzebną do komunikacji przychodzącej jest Twój klucz API, który znajduje się w osobnej sekcji — zobacz Dostęp do API. Opisana tutaj strona Webhooki służy wyłącznie do komunikacji wychodzącej.
Uwaga: Konfiguracja webhooków wymaga pewnej wiedzy technicznej. Jeśli nie czujesz się z tym pewnie, udostępnij tę stronę swojemu programiście lub skorzystaj z platformy automatyzacji, takiej jak Zapier, Make lub Pabbly, które zapewniają adresy URL webhooków bez konieczności programowania.
Typowe zastosowania obejmują:
- Synchronizację nowych kontaktów z Twoim systemem CRM.
- Uruchamianie przepływu pracy w Zapier, Make lub Pabbly po przypisaniu tagu.
- Powiadamianie zespołu na Slacku, gdy użytkownik zostanie zaalarmowany.
- Aktualizację systemu kalendarza po umówieniu spotkania.
- Zapisywanie podsumowań rozmów w Twojej bazie danych.
Konfigurowanie webhooków
- Na lewym pasku bocznym kliknij Ustawienia (ikona koła zębatego).
- Na pasku bocznym Ustawień, w grupie Integracje, kliknij Webhooki.
Na koncie, na którym nie skonfigurowano jeszcze żadnych webhooków, strona wygląda następująco:
- Kliknij Nowy webhook w prawym górnym rogu. Na stronie otworzy się formularz:
- Wypełnij:
- Adres URL punktu końcowego (Endpoint URL) — adres internetowy, na który Your AI Connector będzie wysyłać powiadomienia o zdarzeniach. Otrzymasz go od swojego systemu zewnętrznego (CRM, platformy do automatyzacji lub własnego serwera).
- Nazwa — etykieta, którą rozpoznasz później (np. „Powiadomienia Slack” lub „Synchronizacja CRM”). Tylko do Twojego wglądu.
Twój adres URL webhooka musi być publicznie dostępnym adresem
https://. Zwykłe adresyhttp://, adresylocalhostlub adresy sieci prywatnych oraz adresy wewnętrzne platformy są odrzucane podczas zapisu. Aby przetestować webhooka z własnego komputera, użyj publicznego tunelu (webhook.site lub ngrok) zamiast localhost.
- W sekcji Zdarzenia (Events) kliknij zdarzenia, które ma odbierać ten webhook — wszystkie 22 wymieniono w 22 zdarzenia webhooka.
- (Opcjonalnie) Włącz Ponów nieudane dostarczenia (Retry failed deliveries), jeśli chcesz, aby Your AI Connector ponawiał próby w przypadku tymczasowej awarii — zobacz Ponawianie nieudanych dostarczeń.
- Kliknij Utwórz webhook (Create webhook). Pojawi się on na liście poniżej formularza i w dowolnym momencie możesz kliknąć Test w jego wierszu, aby wysłać przykładowy ładunek (payload) do swojego punktu końcowego.
Wymagane uprawnienia. Dodawanie, edytowanie lub testowanie webhooków wymaga uprawnienia „edit” dla integracji (członkowie zespołu z uprawnieniami tylko do odczytu zobaczą powiadomienie o braku dostępu zamiast formularza).
Podpisywanie webhooka wymaga jego wcześniejszego zapisania — otwórz wiersz istniejącego webhooka, aby go edytować, a panel Signing secret pojawi się na dole formularza edycji. Nowy, niezapisany szkic nie ma jeszcze opcji podpisywania — zobacz Podpisane ładunki poniżej.
Jeden webhook dla wszystkich kont Twoich klientów (agencje)
Jeśli prowadzisz agencję, nie musisz tworzyć tego samego webhooka na każdym koncie klienta z osobna. Na koncie agencji formularz webhooka posiada dodatkowy przełącznik: Wywołuj również dla wszystkich kont klientów. Włącz go, a ten webhook będzie otrzymywał również zdarzenia, które mają miejsce na każdym koncie klienta w ramach Twojej agencji — jeden punkt końcowy dla całej agencji.
Jak to działa:
- Blok
userinformuje, do którego klienta należy zdarzenie. Każde powiadomienie zawiera już blokuseridentyfikujący konto, na którym wystąpiło zdarzenie, dzięki czemu Twoja automatyzacja może kierować ruch dla każdego klienta z osobna. - Ustawienia Twojego webhooka mają zastosowanie wszędzie. Wybrane zdarzenia, klucz podpisywania oraz ustawienie ponawiania są używane również w przypadku dostaw na konta klientów.
- Brak podwójnych dostaw. Jeśli konto klienta posiada własny webhook wskazujący na ten sam adres URL, to on zostanie użyty do obsługi zdarzeń tego konta — to samo zdarzenie nigdy nie trafi dwukrotnie do jednego punktu końcowego.
- Klienci go nie widzą. Webhook nie pojawia się na stronie Webhooków konta klienta, a klienci nie mogą go wyłączyć — zarządzanie nim należy wyłącznie do Ciebie.
- Niezawodność jest śledzona dla każdego konta klienta z osobna. Jeśli Twój punkt końcowy stale zawodzi, zostanie automatycznie wyłączony dla konta, którego dostawy nie powiodły się (zobacz Niezawodność webhooków), a nie dla całej agencji jednocześnie.
Przełącznik pojawia się tylko na kontach agencji. Obsługiwane jest również ustawianie go przez API — zobacz pole apply_to_sub_accounts w API Webhooków.
Dostępne zdarzenia wyzwalające
Możesz niezależnie włączać lub wyłączać każde z 22 zdarzeń webhooka. Gdy zdarzenie zostanie wywołane, Your AI Connector wysyła powiadomienie na Twój adres URL webhooka wraz z odpowiednimi danymi. Każde zdarzenie, jego znaczenie oraz kod event, który umieszcza w ładunku, zostały zestawione w sekcji 22 zdarzenia webhooka poniżej na tej stronie.
Warto wiedzieć: Zadanie utworzone (Task Created), Zadanie zaktualizowane (Task Updated) oraz Zadanie ukończone (Task Completed) są w pełni wybieralne i zapisują się poprawnie. Utworzono podsumowanie dzienne (Daily Summary Created) to również niedawny dodatek. Zobacz Webhook ukończenia zadania poniżej, aby sprawdzić strukturę tego ładunku.
Wyzwalacze webhooków oparte na tagach
subscribed_to_tags nie ogranicza zdarzeń webhooka do konkretnego tagu. Ogranicza jedynie to, które tagi generują powiadomienie o podsumowaniu konwersacji. Aby otrzymać żądanie po zastosowaniu określonego tagu, ustaw adres URL webhooka dla tego tagu w zakładce Tagi agenta (lub kampanii).
Sam formularz webhooka nie posiada selektora tagów, ani podczas tworzenia nowego webhooka, ani podczas edycji istniejącego, więc subscribed_to_tags można odczytać lub zmienić tylko za pośrednictwem API Webhooków lub kontaktując się z pomocą techniczną.
Warto wiedzieć: edycja istniejącego webhooka, który posiada listę
subscribed_to_tags(zmiana nazwy, zmiana zdarzeń, przełączanie ponownych prób), nie czyści już tej listy — ponieważ formularz nie posiada selektora tagów do odesłania, zapisanie zmian z tej strony pozostawia istniejącą listę nienaruszoną. (Był to rzeczywisty błąd przed 21 lipca 2026 r.: zapisywanie z poziomu formularza webhooka usuwało listę, ponieważ zawsze wysyłało pustą listę tagów. Jeśli webhook utracił swoją listęsubscribed_to_tagsprzed tą datą, będzie wymagał ponownej konfiguracji przez API.)
Generowanie podsumowania dla otagowanych kontaktów
Jeśli webhook posiada listę subscribed_to_tags, możesz włączyć Generuj podsumowanie (Generate Summary). Po włączeniu Your AI Connector automatycznie generuje podsumowanie konwersacji dla kontaktu, gdy jeden z tych tagów zostanie zastosowany, i dołącza je do danych webhooka — pełny kontekst bez konieczności wysyłania osobnego żądania.
Testowanie webhooka
- Otwórz Ustawienia → Integracje → Webhooki.
- W wierszu swojego webhooka kliknij Testuj.
- Sprawdź swój system zewnętrzny, aby potwierdzić, że otrzymał dane testowe.
- Przejrzyj format danych, aby upewnić się, że Twój system może je poprawnie przetworzyć.
Aby przeprowadzić pełny test typu end-to-end, wyślij wiadomość, która wywołałaby jedno z Twoich skonfigurowanych zdarzeń (transmisję lub wiadomość przychodzącą na połączony kanał) i zweryfikuj, czy webhook uruchamia się z rzeczywistymi danymi.
Wskazówka: Podczas programowania używaj narzędzi takich jak webhook.site lub RequestBin, aby sprawdzić surowe dane webhooka przed podłączeniem systemu produkcyjnego.
Co uznaje się za udane dostarczenie
Niezależnie od tego, czy klikniesz Testuj, czy zdarzenie wystąpi naprawdę, wysyłamy to samo:
- Żądanie POST (nigdy GET), z treścią (body) w formacie JSON i
Content-Type: application/json. - Nagłówki wymienione w sekcji Podpisane ładunki. Nagłówki podpisu są dołączane tylko wtedy, gdy ustawisz klucz podpisywania (signing secret).
Dostarczenie uznajemy za udane, gdy:
- Twój punkt końcowy odpowiada dowolnym statusem 2xx (200, 201, 204 — wszystkie są poprawne).
- Odpowiada w ciągu 30 sekund.
Kilka rzeczy, które zaskakują użytkowników:
- Treść odpowiedzi jest ignorowana. Nie musisz zwracać żadnego konkretnego pliku JSON. Wystarczy pusta odpowiedź 200.
- Przekierowania są traktowane jako błąd. Nie podążamy za nimi, więc kod 301 lub 302 (w tym przekierowanie z ukośnikiem na końcu lub z http na https) jest rejestrowany jako nieudane dostarczenie. Zapisz ostateczny adres URL, a nie ten, który przekierowuje.
- Ciągi zapytań (query strings) są w pełni obsługiwane.
https://your-app.com/hook?token=abc123jest wysyłany dokładnie tak, jak go zapisałeś, więc umieszczenie tokena w ciągu zapytania działa tak samo dobrze, jak umieszczenie go w ścieżce. - Twój adres URL musi być
https://i publicznie dostępny. Adresy należące do własnej infrastruktury Your AI Connector są odrzucane, ale Twoje własne punkty końcowe w Google Cloud Functions, Cloud Run, App Engine, Firebase Hosting lub gdziekolwiek indziej są w porządku. - Zapora sieciowa lub warstwa ochrony przed botami przed Twoim punktem końcowym może nas blokować. Najczęstszym przypadkiem jest Cloudflare: jeśli Twoja strefa ma włączony tryb Bot Fight Mode lub zarządzane wyzwanie, nasze żądanie otrzymuje stronę z wyzwaniem „Just a moment…” z kodem 403 zamiast dotrzeć do Twojego serwera — a żądanie serwer-serwer nigdy nie przejdzie wyzwania przeglądarkowego, więc zarówno przycisk Test, jak i rzeczywiste zdarzenia kończą się niepowodzeniem w ten sam sposób. Przycisk Test poinformuje Cię, kiedy tak się dzieje („Cloudflare wyświetla wyzwanie bota dla naszego żądania”). Napraw to w Cloudflare za pomocą reguły Security / WAF, która pomija wyzwania dla Twojej ścieżki webhooka (lub dla agenta użytkownika
Webhook-Delivery/1.0), a następnie kliknij ponownie Test. - Jeśli Twoja zapora sieciowa wymaga listy dozwolonych adresów IP (na przykład w darmowym planie Cloudflare, gdzie zwykłego trybu Bot Fight Mode nie można pominąć regułą WAF, ale reguła dostępu IP ustawiona na Zezwalaj działa przed nim), możemy pomóc: każde dostarczenie, czy to z przycisku Test, czy z wydarzenia na żywo, jest wysyłane z jednego stałego adresu IPv4 (bez zakresów, bez IPv6, bez rotacji). Skontaktuj się z pomocą techniczną, a podamy Ci adres do umieszczenia na liście dozwolonych. Zachowaj weryfikację podpisu jako właściwą kontrolę zaufania, ponieważ sprawdza ona każdy ładunek niezależnie od tego, skąd pochodzi.
- Wynik testu dokładnie pokazuje, co odpowiedział Twój punkt końcowy. Nieudany test pokazuje teraz rzeczywisty powód (kod stanu HTTP zwrócony przez Twój punkt końcowy, przekroczenie limitu czasu lub brak możliwości dotarcia do adresu) zamiast ogólnego błędu, a test zapisanego webhooka jest wysyłany z podpisem, gdy podpisywanie jest włączone, dokładnie tak jak w przypadku zdarzenia na żywo.
Korzystanie z n8n, Make lub Zapier („Testowy URL” vs „Produkcyjny URL”)
Platformy automatyzacji zazwyczaj udostępniają dwa różne adresy webhooków, co często wprowadza użytkowników w błąd:
- Testowy URL (w n8n zawiera
/webhook-test/). Otrzymuje dane tylko wtedy, gdy aktywnie obserwujesz obszar roboczy i właśnie kliknąłeś Listen for test event (lub Test workflow). Przechwytuje jedno zdarzenie, a następnie przestaje nasłuchiwać — więc wielokrotne klikanie Testuj w Your AI Connector z rzędu przechwyci tylko pierwsze z nich, i to tylko wtedy, gdy okno nasłuchiwania jest w tym momencie aktywne. Aby przetestować: najpierw kliknij Listen for test event w n8n, a następnie wróć do Your AI Connector i kliknij Testuj raz. - Produkcyjny URL (w n8n zawiera
/webhook/, bez-test). To ten adres należy wkleić do Your AI Connector dla zdarzeń na żywo. Działa tylko wtedy, gdy Twój przepływ pracy (workflow) jest ustawiony jako Active. Jeśli przepływ pracy nie jest aktywny, n8n odrzuci żądanie błędem „404 / webhook not registered”, mimo że Your AI Connector wysłał dane poprawnie.
Krótko mówiąc: testuj za pomocą Testowego URL-a podczas nasłuchiwania, ale aby webhook działał dla rzeczywistych kontaktów, zapisz Produkcyjny URL w Your AI Connector i upewnij się, że przepływ pracy jest Active.
Format danych webhooka
Gdy webhook zostaje wywołany, Your AI Connector wysyła ustrukturyzowane dane (JSON) na Twój adres URL webhooka. Jeśli korzystasz z platformy do automatyzacji, takiej jak Zapier lub Make, dane te są parsowane automatycznie. Jeśli tworzysz własną integrację:
{
"event": "contactCreated",
"contact": { "id": "<contact-id>", "first_name": "Jane", "...": "..." },
"campaign": { "id": "<campaign-id>", "name": "AI Receptionist", "status": "Live" },
"agent": { "id": "<agent-id>", "name": "Front Desk" },
"user": { "id": "<account-id>", "email": "owner@example.com" }
}
| Pole | Opis |
|---|---|
event |
Dokładny ciąg zdarzenia, który wywołał powiadomienie (na przykład contactCreated, booked). To nie jest etykieta wyświetlana na liście zdarzeń; każda etykieta i odpowiadający jej kod znajdują się w sekcji 22 zdarzenia webhooka. |
contact |
Kontakt, którego dotyczy zdarzenie, lub null w przypadku zdarzeń niezwiązanych z kontaktem (takich jak creditsRecharged). |
campaign |
Kampania, do której należy kontakt, lub null, jeśli taka nie istnieje. |
agent |
Agent obsługujący konwersację lub null, jeśli taki nie istnieje. |
user |
Podstawowe informacje identyfikacyjne konta, do którego należą dane. |
campaignlubagent— zazwyczaj jedno, nie oba. Jeśli Twoje konto korzysta z agentów, kontakty są przypisane do agenta, a nie do kampanii, więccampaignpojawia się jakonull, aagentinformuje, który z nich obsługiwał zdarzenie. Starsze konta oparte na kampaniach widzą to odwrotnie. Odczytaj to pole, które jest wypełnione; nie zakładaj, żecampaignzawsze tam jest.
Blok
agentpojawił się 15 sierpnia 2026 r. Znajduje się on obokcampaignw zdarzeniach powiązanych z konwersacją — zakończonym czatem, trybem nie przeszkadzać, wznowieniem, przywróceniem z archiwum, wstrzymaniem AI, nową wiadomością, podsumowaniem konwersacji oraz webhookiem, który można ustawić dla tagu — i zawieraidoraznameagenta obsługującego, lubnull, gdy żaden agent nie jest zaangażowany. Jest to zmiana czysto addytywna: każde pole, które już otrzymujesz, pozostaje bez zmian, więc odbiornik zbudowany przed tą datą będzie nadal działał bez konieczności wprowadzania aktualizacji.
Niektóre zdarzenia dodają własny, dodatkowy blok najwyższego poziomu. Na przykład Appointment Booked dodaje blok appointment (zobacz Webhook Appointment Booked), New Message dodaje pełny blok message z tekstem (zobacz Webhook New Message), a Deliveries i Reads dodają krótki blok message zawierający tylko identyfikator wiadomości i jej status (zobacz Webhook Deliveries and Reads).
Deliveries i Reads informują, której wiadomości dotyczą, ale nie podają jej treści. Zawierają blok
messagezidistatuswiadomości — a tenidjest tym samymmessageId, który zwraca punkt końcowy wysyłania wiadomości, dzięki czemu możesz dopasować potwierdzenie dostarczenia lub odczytania do konkretnej wysłanej wiadomości — ale bez treści samej wiadomości. Replies nie zawiera żadnego blokumessage. Jeśli potrzebujesz treści wysłanych lub odebranych wiadomości, zasubskrybuj również New Message.
Dwie rzeczy, które warto wiedzieć przed napisaniem odbiornika. Nie ma pola
timestampani otokidata. Każdy blok znajduje się na najwyższym poziomie obiektu JSON, jak pokazano powyżej.
22 zdarzenia webhooka
22 zdarzenia webhooka wraz z etykietą wyświetlaną w aplikacji, którą zaznaczasz, oraz kodem event wysyłanym w ładunku. Kod event to krótki ciąg znaków, który nie pasuje do etykiety wyświetlanej w aplikacji, dlatego dopasowuj odbiornik na podstawie kodu, a nie etykiety:
| Etykieta wyświetlania (w aplikacji) | Kod event w ładunku (payload) |
Co to oznacza |
|---|---|---|
| Contact Created | contactCreated |
Nowy kontakt został dodany do Twojego konta (ręcznie, przez import lub przez API). |
| Contact Paused | contact_paused |
Konwersacja z kontaktem została wstrzymana (bot przestaje odpowiadać). |
| Contact Resumed | contact_resumed |
Wstrzymana konwersacja z kontaktem została wznowiona. |
| Contact Do Not Disturb | contact_do_not_disturb_changed |
Ustawienie „Nie przeszkadzać” dla kontaktu zostało włączone. |
| Contact Unarchived | contact_unarchived |
Zarchiwizowany kontakt wysyła nową wiadomość, co przywraca go do aktywnej skrzynki odbiorczej. |
| New Message | new_message |
Dowolna wiadomość dodana do konwersacji na dowolnym kanale — zarówno wiadomości wysyłane przez kontakt do Ciebie, jak i wiadomości wysyłane przez Twojego bota AI lub zespół do kontaktu. Jest to jedyne zdarzenie, które zawiera faktyczny tekst wiadomości (zobacz Webhook New Message). |
| Replies | replied |
Kontakt odpowiada na wiadomość. |
| Reads | read |
Kontakt odczytuje wiadomość (na kanałach obsługujących potwierdzenia odczytu). Zawiera identyfikator odczytanej wiadomości — zobacz Webhook Deliveries and Reads. |
| Deliveries | delivered lub undelivered |
Wiadomość została pomyślnie dostarczona do kontaktu (undelivered w przypadku niepowodzenia dostarczenia). Zawiera identyfikator wiadomości — zobacz Webhook Deliveries and Reads. |
| Human Alerted | humanAlerted |
Bot AI stwierdza, że nie może obsłużyć konwersacji i oznacza ją jako wymagającą uwagi człowieka. |
| Chat Concluded | chat_concluded |
Bot AI uznaje, że konwersacja dobiegła końca (dokonano rezerwacji, lead zdyskwalifikowany itp.). |
| Appointment Booked | booked |
Kontakt rezerwuje spotkanie przez system rezerwacji. |
| Credits Spent | creditsSpent |
Kredyty zostały odjęte z Twojego konta. |
| Credits Recharged | creditsRecharged |
Kredyty zostały dodane do Twojego konta poprzez automatyczne doładowanie lub ręczny zakup. |
| Low Credit Balance | lowCreditBalance przy dostarczeniu Test, Low Credit Balance przy prawdziwym |
Wczesne ostrzeżenie, że saldo kredytów spadło poniżej progu alertu (100 kredytów, chyba że ustawisz własny). Skierowane do agencji, których subkonta korzystają z jednej puli. Zawiera balance, threshold i account_email zamiast bloku kontaktu, jest wysyłane maksymalnie raz na 24 godziny, gdy saldo pozostaje niskie, i aktywuje się ponownie, gdy saldo wzrośnie powyżej progu. |
| Task Created | taskCreated |
Zadanie zostało utworzone. |
| Task Updated | taskUpdated |
Zadanie uległo zmianie bez przejścia do etapu zakończenia. |
| Task Completed | taskCompleted |
Zadanie przeszło do etapu skonfigurowanego jako etap zakończenia. |
| Daily Summary Created | dailySummaryCreated |
Twój dzienny raport podsumowujący został wygenerowany. |
| Channel Connected | channelConnected |
Jeszcze nie wysyłane — możliwe do wybrania, ale obecnie nic go nie wyzwala. Nie buduj rozwiązań w oparciu o to. Przeznaczone dla momentu, gdy kanał komunikacji zakończy łączenie. |
| Broadcast Started | broadcastStarted |
Rozpoczyna się wysyłanie transmisji (status zmienia się na Sending). Wyzwalane raz na rozpoczęcie, w tym przy wznawianiu wstrzymanej transmisji. Zawiera blok broadcast zamiast bloku kontaktu: id, name, channel, status, previous status, lista docelowa (list_id, list_name, is_smart_list), scheduled_at, total_contacts. |
| Broadcast Completed | broadcastCompleted |
Transmisja kończy się (status zmienia się na Sent lub Failed). Ten sam blok broadcast oraz completed_at i, jeśli są dostępne, completion_summary (total_sent, permanently_failed, unique_replied, failure_rate, had_errors). Użyj tych dwóch, aby połączyć listę Smart Broadcast z zewnętrznymi narzędziami. |
Dwa kolejne kody nigdy nie pojawiają się na tej liście, ponieważ nie subskrybujesz ich: contact_tags_updated, wysyłany przez adres URL webhooka ustawiony na indywidualnym tagu, oraz summary_generated, wysyłany, gdy podsumowanie czatu jest zapisywane dla tagu na liście subscribed_to_tags webhooka.
Zdarzenie Kanał połączony nie jest jeszcze wysyłane. Pojawia się na liście zdarzeń, ale obecnie nic go nie wywołuje. Nie opieraj na nim żadnych funkcji.
Powiadomienia oparte na tagach i zadaniach używają własnych, oddzielnych struktur. Zobacz Contact Tags Updated oraz Task Completed.
Webhook Contact Created
Wysyłany, gdy wyzwalane jest zdarzenie Contact Created (nowy kontakt dodany ręcznie, poprzez import lub przez API).
Nazwa zdarzenia
contactCreated
Format ładunku (payload)
{
"event": "contactCreated",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"human_alert_reason": null,
"is_bot_active": true,
"ad_referral": null
},
"campaign": {
"id": "<campaign-id>",
"name": "AI Receptionist",
"status": "Live"
},
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
}
}
| Pole | Opis |
|---|---|
event |
Zawsze contactCreated dla tego zdarzenia. |
contact.id |
Unikalny identyfikator nowego kontaktu. |
contact.email / contact.phone_number |
Adres e-mail i numer telefonu kontaktu, jeśli są znane (w zależności od kanału oba mogą być puste). |
contact.first_name / contact.last_name |
Imię i nazwisko kontaktu, jeśli są znane. |
contact.human_alerted / contact.human_alert_reason |
Czy kontakt został oznaczony do uwagi człowieka i dlaczego. |
contact.is_bot_active |
Czy bot AI jest obecnie aktywny dla tego kontaktu. |
contact.ad_referral |
Atrybucja reklamy Meta Click-to-WhatsApp lub null — zobacz Atrybucja reklamy Click-to-WhatsApp. |
campaign |
Kampania, w ramach której utworzono kontakt, lub null. |
agent |
Agent przypisany do kontaktu lub null. |
user |
Podstawowe informacje identyfikacyjne konta, do którego należy kontakt. |
Próbka „Test” i rzeczywiste zdarzenie wyglądają nieco inaczej. Przycisk testowy wysyła dane zastępcze (John Doe, przykładowa kampania). Rzeczywiste zdarzenie Contact Created zawiera dane faktycznego kontaktu, a niektóre pola mogą być puste w zależności od kanału.
Webhook nowej wiadomości
Ten webhook uruchamia się za każdym razem, gdy wiadomość jest dodawana do konwersacji, w dowolnym kanale. Obejmuje oba kierunki: wiadomości, które wysyła Ci kontakt, oraz wiadomości wysyłane przez Twoją sztuczną inteligencję, Twój zespół lub kampanię. Jest to jedyny webhook, który zawiera treść wiadomości, więc należy go użyć, jeśli chcesz odzwierciedlić konwersacje w zewnętrznym systemie.
Nazwa zdarzenia
new_message
Format ładunku (payload)
{
"event": "new_message",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"human_alert_reason": null,
"is_bot_active": true,
"ad_referral": null
},
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
},
"message": {
"id": "<message-id>",
"body": "Hi, are you open on Saturday?",
"direction": "inbound",
"status": "received",
"created_at": "2026-07-30T17:27:06.000Z",
"channel": "whatsapp_web"
}
}
| Pole | Opis |
|---|---|
event |
Zawsze new_message dla tego zdarzenia. Pamiętaj, że jest to dokładny ciąg znaków wysyłany — nie jest to etykieta wyświetlania „New Message”. |
contact |
Kontakt, do którego należy konwersacja z wiadomością. Ten sam kształt co w Contact Created. |
agent |
Agent obsługujący konwersację (id i name) lub null, jeśli żaden agent nie jest zaangażowany. |
user |
Podstawowe informacje identyfikacyjne konta, do którego należy konwersacja. |
message.id |
Unikalny identyfikator wiadomości. |
message.body |
Tekst wiadomości. Puste dla wiadomości zawierającej tylko załącznik (obraz, notatka głosowa, dokument). |
message.direction |
inbound dla wiadomości od kontaktu, outbound dla wiadomości wysłanej przez Twoje AI lub zespół ze skrzynki odbiorczej oraz outbound-api dla wiadomości wysłanej przez kampanię, transmisję, szablon lub API. |
message.status |
Etap cyklu życia wiadomości: received dla przychodzących oraz queued / sent / delivered / read / failed / undelivered dla wychodzących. Jest to status w momencie utworzenia wiadomości, więc wiadomość wychodząca zazwyczaj dociera tutaj jako queued lub sent, a status delivered osiąga później — użyj zdarzeń Deliveries i Reads, jeśli potrzebujesz tych późniejszych przejść. Zawierają one ten sam message.id co ten blok, więc możesz dopasować przejście do tej wiadomości (zobacz Webhook Deliveries and Reads). |
message.created_at |
Czas utworzenia wiadomości w formacie UTC (ISO 8601). |
message.channel |
Kanał, przez który przeszła wiadomość, na przykład whatsapp, whatsapp_web, sms, instagram, messenger, telegram, email lub custom. |
W tym ładunku nadal nie ma bloku
campaign. Nowa wiadomość wysyłacontact,agent,userorazmessage. Blokagentzostał dodany 15 sierpnia 2026 r. i informuje, który agent obsługuje konwersację; jeśli potrzebujesz również kontekstu kampanii, wyszukaj kontakt przez API, używająccontact.id.
Wewnętrzne rekordy AI nie uruchamiają tego webhooka. Oprócz rzeczywistych wiadomości platforma przechowuje własne wiersze księgowe w konwersacji (wywołania narzędzi AI i wewnętrzne rekordy tur). Nigdy nie są one wysyłane — otrzymujesz tylko wiadomości, które zostały faktycznie wysłane lub odebrane.
Webhook Deliveries and Reads
Te dwa zdarzenia raportują, co stało się z wiadomością po tym, jak opuściła Your AI Connector: Deliveries wyzwala się, gdy wiadomość dotrze do kontaktu (lub nie uda się jej dostarczyć), a Reads wyzwala się, gdy kontakt ją otworzy, na kanałach obsługujących potwierdzenia odczytu.
Oba zawierają blok message z identyfikatorem wiadomości, której dotyczy zdarzenie, dzięki czemu możesz dopasować aktualizację do konkretnej wysłanej wiadomości.
Nazwy zdarzeń
delivered i undelivered dla Deliveries, read dla Reads.
Format ładunku (payload)
{
"event": "delivered",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"ad_referral": null
},
"campaign": {
"id": "<campaign-id>",
"name": "AI Receptionist",
"status": "Live"
},
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
},
"message": {
"id": "<message-id>",
"status": "delivered"
}
}
| Pole | Opis |
|---|---|
event |
delivered lub undelivered dla Deliveries, read dla Reads. |
contact |
Kontakt, do którego wysłano wiadomość. |
campaign |
Kampania, do której należy kontakt, lub null. |
agent |
Agent obsługujący konwersację lub null. |
user |
Podstawowe informacje identyfikacyjne konta, do którego należą dane. |
message.id |
Identyfikator wiadomości, której dotyczy ta aktualizacja. Jest to ta sama wartość, którą punkt końcowy wysyłania wiadomości zwraca jako messageId, oraz ten sam message.id, który zawiera powiadomienie New Message. |
message.status |
Nowy status, zawsze ten sam ciąg znaków co event (delivered, undelivered lub read). |
Jak dopasować aktualizację do wysłanej wiadomości. Przechowuj
messageId, który otrzymujesz po wysłaniu wiadomości przez API. Gdy nadejdzie powiadomienie Deliveries lub Reads, wyszukaj ten zapisany identyfikator w polumessage.idw ładunku — to jest Twoje potwierdzenie dostarczenia lub odczytania dla tej konkretnej wiadomości.
Tutaj nie ma tekstu wiadomości. Blok
messagezawiera tylko identyfikator i status. Zasubskrybuj New Message, jeśli potrzebujesz również treści wiadomości.
Blok
messagejest obecny tylko wtedy, gdy wiemy, o jaką wiadomość chodzi. W rzadkich przypadkach aktualizacji, których nie możemy powiązać z zapisaną wiadomością, blok jest całkowicie pomijany, zamiast być wysyłanym jako pusty — dlatego sprawdź, czymessageistnieje, zanim odczytaszmessage.id.
Jedno powiadomienie na zmianę statusu. Pojedyncza wiadomość wychodząca zazwyczaj generuje powiadomienie
delivered, a następnie, na kanałach z potwierdzeniami odczytu, powiadomienieread. Nieudana wysyłka generuje zamiast tegoundelivered.
Webhook rezerwacji spotkania
Uruchamia się, gdy kontakt zarezerwuje spotkanie. Uruchamia się w ten sam sposób, niezależnie od tego, czy sztuczna inteligencja zarezerwowała je podczas konwersacji, czy Ty zarezerwowałeś je ręcznie, czy też wpłynęło ono przez API.
Nazwa zdarzenia
booked
Format ładunku (payload)
{
"event": "booked",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith"
},
"campaign": {
"id": "<campaign-id>",
"name": "AI Receptionist",
"status": "Live"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com"
},
"appointment": {
"appointment_id": "<appointment-id>",
"start_time": "2026-07-20T15:00:00.000Z",
"end_time": "2026-07-20T15:30:00.000Z",
"status": "confirmed",
"room_name": "Room 1",
"description": "Discovery call",
"summary": "30 min intro",
"google_calendar_event_id": null,
"event": {
"id": "<service-id>",
"event_name": "Intro Call",
"slot_duration": 30,
"location": "Zoom",
"meeting_link": "https://...",
"event_type": "online"
}
}
}
| Pole | Opis |
|---|---|
event |
Zawsze booked dla tego zdarzenia. |
contact |
Osoba, która dokonała rezerwacji. email i phone_number mogą być puste w zależności od kanału. |
appointment.appointment_id |
Unikalny identyfikator rezerwacji. |
appointment.start_time / end_time |
Początek i koniec zarezerwowanego terminu, w UTC (ISO 8601). |
appointment.status |
Bieżący status rezerwacji. |
appointment.room_name |
Pokój, w którym dokonano rezerwacji, jeśli jest używany. |
appointment.description / summary |
Szczegóły w formie dowolnego tekstu zarejestrowane przy rezerwacji. |
appointment.google_calendar_event_id |
Identyfikator Google Calendar dla zsynchronizowanego zdarzenia. Często jest to null w webhooku „Wizyta zarezerwowana”, ponieważ zdarzenie w kalendarzu jest tworzone w tym samym momencie, w którym wysyłane jest powiadomienie — pobierz wizytę ponownie za pomocą jej appointment_id chwilę później, jeśli jej potrzebujesz, i spodziewaj się stałego null na kontach bez połączonego Kalendarza Google. |
appointment.event |
Usługa, która została zarezerwowana: nazwa, długość terminu, lokalizacja, link do spotkania, typ. |
google_calendar_event_idjest częstonullw tym webhooku i jest to normalne. Wydarzenie w Kalendarzu Google jest tworzone w tym samym momencie, w którym wysyłane jest powiadomienie, więc identyfikator zazwyczaj nie jest jeszcze gotowy. Jeśli go potrzebujesz, pobierz ponownie spotkanie za pomocą jegoappointment_idchwilę później. Pozostaje ononullna stałe, jeśli konto nie ma połączonego Kalendarza Google, więc nie czekaj na nie w nieskończoność.
Przycisk „Test” nie zawiera bloku
appointment. Użyj go, aby potwierdzić, że Twój punkt końcowy odpowiada, a następnie dokonaj jednej rzeczywistej rezerwacji, aby zobaczyć pełny ładunek (payload).
Dwa przypadki, w których ten webhook nie jest wyzwalany: spotkania zaimportowane z zewnętrznego kalendarza oraz rezerwacje pochodzące z integracji Formitable.
Webhook aktualizacji tagów kontaktu
Uruchamia się, gdy do kontaktu zostanie przypisana etykieta, a ta etykieta ma skonfigurowany adres URL webhooka w agencie lub kampanii, do której należy kontakt.
Nazwa zdarzenia
contact_tags_updated
Kiedy jest wyzwalane
- Do kontaktu przypisano etykietę, a kontakt ma przypisanego agenta, kampanię lub oba te elementy.
- Co najmniej jedna z przypisanych etykiet ma ustawiony adres URL webhooka w zakładce Etykiety (Tags) danego agenta lub kampanii.
Jeśli kontakt ma oba te elementy, a tagi kampanii zawierają adresy URL webhooków, to one mają pierwszeństwo; w przeciwnym razie używane są tagi agenta.
Jeśli w tej samej aktualizacji przypisanych zostanie wiele etykiet z różnymi adresami URL webhooków, wysyłane jest jedno żądanie na każdy adres URL, z których każde zawiera tylko etykiety przypisane do tego konkretnego adresu.
Usunięcie etykiety nigdy nie powoduje wysłania żądania. Większość użytkowników kieruje te adresy URL do określonych działań — pobrania zaliczki, zarezerwowania terminu, powiadomienia przedstawiciela — więc ponowne pojawienie się etykiety u kontaktu mogłoby spowodować ponowne uruchomienie tego działania. Teraz nie jest to już możliwe. Usunięcie nadal pojawia się w removed_tags, jeśli wystąpi w tej samej aktualizacji co przypisanie, które kieruje do tego samego adresu URL, dzięki czemu automatyzacja odczytująca obie tablice zachowuje pełny obraz sytuacji; nigdy jednak nie zobaczy żądania wywołanego wyłącznie usunięciem. (Zmieniono 12 sierpnia 2026 r. Przed tą datą usunięcia również wysyłały żądanie.)
Format ładunku (payload)
{
"event": "contact_tags_updated",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"is_bot_active": true,
"ad_referral": {
"ctwa_clid": "ARAbc123...",
"source_id": "120210000000000",
"source_type": "ad",
"source_url": "https://fb.me/xxxx",
"headline": "Get 20% off today",
"body": "Message us now to claim your discount",
"channel": "whatsapp"
}
},
"added_tags": ["qualified-lead"],
"removed_tags": ["new-lead"],
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
}
}
| Pole | Opis |
|---|---|
event |
Zawsze contact_tags_updated dla tego webhooka. |
contact.id |
Unikalny identyfikator kontaktu, którego tagi uległy zmianie. |
contact.email / contact.phone_number |
E-mail/telefon kontaktu, jeśli jest znany. |
contact.first_name / contact.last_name |
Imię i nazwisko kontaktu. |
contact.human_alerted |
Czy kontakt jest obecnie oznaczony jako wymagający uwagi człowieka. |
contact.is_bot_active |
Czy bot AI jest obecnie aktywny w konwersacji z tym kontaktem. |
contact.ad_referral |
Obecne tylko wtedy, gdy kontakt po raz pierwszy dotarł do Ciebie przez reklamę lub post Meta Click-to-WhatsApp (CTWA). W przeciwnym razie null. |
added_tags |
Tablica nazw tagów zastosowanych w tej aktualizacji. Nigdy nie jest pusta — zastosowanie tagu jest tym, co wyzwala żądanie. |
removed_tags |
Tablica nazw tagów usuniętych w tej samej aktualizacji, jeśli istnieją. Samo usunięcie tagu nie powoduje wysłania żadnych danych. |
agent |
Agent obsługujący konwersację z kontaktem (id i name) lub null, jeśli żaden agent nie jest zaangażowany. Dodano 15 sierpnia 2026 r. |
user |
Podstawowe informacje identyfikacyjne konta, do którego należy kontakt. |
Testowanie webhooka tagu
Obok pola adresu URL webhooka na karcie Tagi znajduje się przycisk Testuj. Wysyła on natychmiast przykładowy ładunek (payload) pod ten adres, dzięki czemu możesz potwierdzić, że Twoja automatyzacja go odbiera, bez konieczności czekania na rzeczywistą konwersację.
Test wysyła ten sam kształt contact_tags_updated, który pokazano powyżej, używając przykładowego kontaktu, z tagiem, który testujesz w added_tags oraz pustym removed_tags. To, co Twoja automatyzacja widzi w teście, jest tym samym, co zobaczy w środowisku produkcyjnym.
Warto wiedzieć o dwóch rzeczach:
- Najpierw zapisz tag. Test wyszukuje tag po jego zapisanej nazwie, więc zupełnie nowy tag lub niezapisana zmiana nazwy nie mogą być jeszcze przetestowane. Przycisk pozostaje wyszarzony, dopóki nazwa na ekranie nie będzie zgodna z zapisaną.
- Nieudany test nie wpływa na Twój webhook. Testy nigdy nie przyczyniają się do automatycznego wyłączenia po wielokrotnych awariach, opisanego w Niezawodność Webhooków.
Jeśli test się nie powiedzie, komunikat poinformuje Cię, co odpowiedział Twój punkt końcowy (na przykład 404 lub 500), co zazwyczaj wystarcza, aby wykryć błędny adres URL lub przepływ pracy, który nie jest włączony.
Webhook ukończenia zadania
Tylko w celach informacyjnych. Webhooki zadań (jako dane) są udokumentowane tutaj dla programistów; zdarzenia Task Created, Task Updated oraz Task Completed można wybrać na standardowej liście zdarzeń w formularzu webhooka, tak jak każde inne zdarzenie — zobacz Dostępne zdarzenia wyzwalające oraz 22 zdarzenia webhooka.
Ten ładunek jest wysyłany, gdy zadanie przechodzi do etapu oznaczonego jako etap ukończenia. Zadanie przenoszone między etapami niebędącymi etapami ukończenia wysyła zamiast tego strukturę taskUpdated.
Nazwa zdarzenia
taskCompleted
Kiedy jest wyzwalane
- Zadanie zostało zaktualizowane.
- Jego wartość
stagezmieniła się w porównaniu z poprzednią wartością. - Nowy etap jest skonfigurowany jako etap ukończenia w ustawieniach etapów zadań na koncie.
Format ładunku (payload)
{
"event": "taskCompleted",
"contact": {
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"human_alert_reason": null
},
"user": {
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
},
"message": {
"id": "<task-id>",
"title": "Follow up with Jane",
"description": "Confirm pricing and send proposal",
"type": "follow_up",
"priority": "high",
"stage": "<stage-id>",
"due_date": "2026-01-20T15:00:00Z",
"source": "ai",
"source_detail": "<source-detail>",
"campaign_id": "<campaign-id>",
"linked_human_alert": "<human-alert-id>",
"tags": ["qualified-lead"],
"notes": "Customer requested a callback"
}
}
| Pole | Opis |
|---|---|
event |
Zawsze taskCompleted dla tego webhooka. Przesyłany jest ten sam kształt ładunku co w taskUpdated, gdy zadanie zmienia się bez wchodzenia w etap ukończenia. |
contact |
Kontakt powiązany z zadaniem, jeśli istnieje. null, gdy nie jest powiązany. |
contact.human_alert_reason |
Powód, dla którego kontakt został oznaczony do uwagi człowieka, jeśli dotyczy. |
user |
Podstawowe informacje identyfikacyjne konta, do którego należy zadanie. |
message.id |
Unikalny identyfikator zadania. |
message.title / description |
Tytuł i opis zadania. |
message.type |
Typ zadania (na przykład follow_up, call, custom). |
message.priority |
Priorytet zadania (low, medium, high). |
message.stage |
Identyfikator etapu, w którym znajduje się obecnie zadanie. |
message.due_date |
Termin wykonania zadania, jeśli został ustawiony. |
message.source |
Co utworzyło zadanie (ai, manual, api). |
message.source_detail |
Dodatkowe szczegóły dotyczące źródła. |
message.campaign_id |
Identyfikator powiązanej kampanii lub null. |
message.linked_human_alert |
Identyfikator powiązanego alertu dla człowieka, jeśli istnieje. |
message.tags |
Tagi zastosowane do zadania. |
message.notes |
Dowolne notatki dotyczące zadania. |
Wyłączanie (lub usuwanie) webhooka
Każdy webhook posiada przełącznik włączania/wyłączania, znajdujący się bezpośrednio w jego wierszu. Wyłączenie go powoduje wstrzymanie otrzymywania zdarzeń, ale zachowuje wszystko, co skonfigurowałeś — adres URL, zdarzenia, wszelkie klucze podpisywania. Po ponownym włączeniu webhook zacznie działać od miejsca, w którym przerwał; żadne zdarzenia, które wystąpiły w czasie, gdy był wyłączony, nie zostaną dostarczone później.
Użyj tej opcji, gdy chcesz na pewien czas wstrzymać dostarczanie: Twój punkt końcowy jest przebudowywany, debugujesz uciążliwą integrację lub wstrzymujesz automatyzację.
Usuwanie webhooka (ikona kosza w jego wierszu) usuwa go na stałe, włącznie z jego kluczem podpisywania. Jeśli chcesz tylko wstrzymać dostarczanie, zamiast tego wyłącz go — usuwanie służy do sytuacji, w których całkowicie rezygnujesz z danego punktu końcowego.
To nie to samo, co automatyczne wyłączenie webhooka. Jeśli wyłączymy Twój webhook po wielokrotnych awariach (zobacz Niezawodność webhooków), powyższy przełącznik go nie przywróci. Gdy naprawisz swój punkt końcowy, edytuj webhook i zapisz go ze zmienionym adresem URL (każda zmiana adresu URL powoduje jego ponowne włączenie) lub wywołaj punkt końcowy ponownego włączania przez API — albo poproś o pomoc nasz dział wsparcia, a my włączymy go dla Ciebie.
Podpisane ładunki (weryfikacja, czy webhook faktycznie pochodzi od nas)
Każdy, kto pozna adres URL Twojego webhooka, może wysłać do niego fałszywe żądanie. Jeśli automatycznie reagujesz na webhooki — aktualizując rozliczenia, tworząc rekordy CRM — włączenie podpisywania pozwoli Ci zweryfikować, czy każde żądanie faktycznie pochodzi od nas.
Podpisywanie jest opcjonalne i domyślnie wyłączone. Włącza się je dla każdego webhooka z osobna, z poziomu widoku edycji danego webhooka (otwórz wiersz zapisanego webhooka).
Włączanie podpisywania
- Otwórz webhook (Ustawienia → Integracje → Webhooki → kliknij wiersz swojego webhooka).
- W sekcji Klucz podpisywania (Signing secret) kliknij Generuj.
- Skopiuj klucz (zaczyna się od
whsec_) i zapisz go w swoim systemie odbiorczym. Traktuj go jak hasło.
W każdej chwili możesz wrócić do tego samego panelu, aby wyświetlić, skopiować, zrotować lub wyłączyć klucz.
Co wysyłamy
Gdy podpisywanie jest włączone, każde dostarczenie dla tego webhooka zawiera dwa dodatkowe nagłówki HTTP:
| Nagłówek | Znaczenie |
|---|---|
X-Webhook-Signature |
Podpis w formacie v1=<hex>. |
X-Webhook-Timestamp |
Czas wysłania w formacie znacznika czasu Unix w sekundach. |
Te trzy elementy znajdują się w każdym dostarczeniu, niezależnie od tego, czy jest podpisane, czy nie:
| Nagłówek | Znaczenie |
|---|---|
X-Webhook-Delivery |
Unikalny identyfikator tego zdarzenia. Pozostaje taki sam przy ponownych próbach, więc służy do deduplikacji. |
X-Webhook-Attempt |
Numer próby (1 to pierwsza próba). |
X-Webhook-Event |
Nazwa zdarzenia, dzięki której możesz kierować ruch bez czytania treści. |
Jak weryfikować
Podpis to HMAC-SHA256 ciągu znaków <timestamp>.<raw request body>, przy użyciu klucza podpisywania jako klucza szyfrującego.
Weryfikuj na podstawie surowej treści żądania — dokładnie takich bajtów, jakie otrzymałeś. Jeśli Twój framework parsuje JSON i ponownie go serializuje przed sprawdzeniem, bajty mogą ulec zmianie, a podpis nie będzie pasował.
Przykład w Node.js:
const crypto = require("crypto");
function verify(rawBody, headers, secret) {
const timestamp = headers["x-webhook-timestamp"];
const signature = headers["x-webhook-signature"]; // "v1=<hex>"
// Reject anything older than 5 minutes so a captured request can't be replayed later.
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature.replace("v1=", "")), Buffer.from(expected));
}
Przykład w Pythonie:
import hashlib, hmac, time
def verify(raw_body: bytes, headers, secret: str) -> bool:
timestamp = headers["X-Webhook-Timestamp"]
signature = headers["X-Webhook-Signature"].replace("v1=", "")
# Reject anything older than 5 minutes so a captured request can't be replayed later.
if abs(time.time() - int(timestamp)) > 300:
return False
expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature, expected)
Porównuj podpisy za pomocą funkcji bezpiecznej czasowo (
timingSafeEqual/compare_digest), a nie==. Nic to nie kosztuje, a pozwala uniknąć subtelnej klasy ataków.
Rotacja klucza
Kliknij Rotuj, aby zastąpić klucz. Zmiana jest natychmiastowa: już następna dostawa jest podpisana wyłącznie nowym kluczem. Jeśli Twój punkt końcowy działa, akceptuj zarówno stary, jak i nowy klucz przez kilka minut, podczas których będziesz wdrażać nowy klucz.
Wyłączenie podpisywania po prostu zatrzymuje wysyłanie nagłówków podpisu.
Ponawianie nieudanych dostaw
Domyślnie nieudane dostarczenie nie jest ponawiane — jeśli Twój system jest w tym momencie niedostępny, zdarzenie zostaje utracone.
Włącz Ponawianie nieudanych dostarczeń w webhooku (w formularzu tworzenia/edycji), a będziemy podejmować kolejne próby:
| Próba | Kiedy |
|---|---|
| 1 | Natychmiast |
| 2 | 1 minutę później |
| 3 | 5 minut później |
| 4 | 30 minut później |
| 5 | 2 godziny później |
Łącznie zajmuje to około 2 godzin i 40 minut, dzięki czemu webhook może przetrwać okno serwisowe lub krótką awarię po Twojej stronie.
Co jest ponawiane: problemy tymczasowe — gdy Twój serwer zwraca błąd 5xx, wystąpił limit czasu (timeout) lub błąd połączenia.
Co nie jest ponawiane: jeśli Twój punkt końcowy odrzuca samo żądanie (jakikolwiek błąd 4xx), nie ponawiamy próby — wysłanie identycznego żądania ponownie wywołałoby tylko identyczne odrzucenie.
Które zdarzenia są ponawiane: webhooki tagów (contact_tags_updated), trzy zdarzenia zadań oraz podsumowanie dzienne. Pozostałe są wysyłane tylko raz, więc w ich przypadku przełącznik nie ma zastosowania. Każde zdarzenie nadal zawiera X-Webhook-Delivery, więc jedna reguła deduplikacji obejmuje je wszystkie.
Włączaj ponawianie tylko wtedy, gdy Twój punkt końcowy jest idempotentny. Ponawianie oznacza, że to samo zdarzenie może dotrzeć więcej niż raz. Użyj nagłówka
X-Webhook-Delivery, aby rozpoznać powtórzenie: pozostaje on taki sam przy każdej próbie dla jednego zdarzenia, więc możesz bezpiecznie zignorować identyfikator, który już obsłużyłeś.
Ponowne próby współpracują z automatycznym wyłączaniem po wielokrotnych awariach (zobacz Niezawodność webhooków) w oczekiwany sposób: licznik awarii zlicza całe dostarczenie dopiero po wykorzystaniu wszystkich ponownych prób — a nie każdą pojedynczą próbę z osobna.
Niezawodność webhooków
- Your AI Connector wysyła webhooki za pośrednictwem bezpiecznego połączenia (HTTPS). Upewnij się, że podany adres internetowy używa protokołu HTTPS.
- Jeśli Twój system zwróci błąd, dostarczenie zostanie uznane za nieudane.
- Monitoruj czas pracy (uptime) swojego systemu odbierającego, aby uniknąć pominięcia zdarzeń.
- W przypadku krytycznych przepływów pracy włącz Ponawianie nieudanych dostarczeń i rozważ również mechanizm awaryjny (fallback).
Webhooki są wyłączane automatycznie po wielokrotnych awariach. Jeśli adres URL Twojego webhooka wielokrotnie zwraca błędy (około 5 błędów z rzędu lub 3 z rzędu w przypadku błędów konfiguracji), Your AI Connector automatycznie przestaje wysyłać zdarzenia pod ten adres. Aby przywrócić działanie po naprawieniu punktu końcowego: edytuj webhook i zapisz go ze zmienionym adresem URL (każda zmiana adresu URL powoduje jego ponowne włączenie) lub użyj punktu końcowego ponownego włączania przez API — ponowne zapisanie z tym samym adresem URL nie wystarczy. Dział wsparcia może również włączyć go dla Ciebie.
Rozwiązywanie problemów
| Problem | Rozwiązanie |
|---|---|
| Webhook nie działa | Najpierw sprawdź, czy webhook nie jest wyłączony w swoim wierszu. Następnie potwierdź, że wybrano poprawne zdarzenia i że Twój adres URL jest dostępny z poziomu internetu. |
| Zdarzenie testowe działa, ale rzeczywiste zdarzenia nie | Upewnij się, że włączono konkretny typ zdarzenia. Jeśli oczekiwałeś żądania po przypisaniu tagu, pamiętaj, że subscribed_to_tags nie ogranicza zdarzeń webhooka do tagu — zawęża jedynie, które tagi generują powiadomienie o podsumowaniu konwersacji. Aby otrzymać żądanie po przypisaniu konkretnego tagu, ustaw adres URL webhooka dla tego tagu w zakładce Tagi agenta (lub kampanii) — zobacz Webhook aktualizacji tagów kontaktu. |
| Nic nie dociera do n8n / Make / Zapier | Prawdopodobnie używasz adresu URL testowego platformy, który nasłuchuje tylko pojedynczego zdarzenia zaraz po kliknięciu „Nasłuchuj zdarzenia testowego”. W przypadku zdarzeń na żywo zapisz produkcyjny adres URL i przełącz przepływ pracy na Aktywny. |
| Otrzymywanie zduplikowanych zdarzeń | Sprawdź, czy wiele webhooków nie wskazuje na ten sam adres URL. Jeśli opcja Ponawiaj nieudane dostarczenia jest włączona, powtórzenie jest oczekiwane, gdy Twój punkt końcowy zaakceptował zdarzenie, ale nie odpowiedział na czas — usuń duplikaty za pomocą X-Webhook-Delivery. |
| Weryfikacja podpisu zawsze kończy się niepowodzeniem | Prawie zawsze wynika to z ponownej serializacji treści przed weryfikacją. Zweryfikuj względem surowej treści żądania, podpisz <timestamp>.<body> i potwierdź, że używasz aktualnego klucza tajnego, jeśli niedawno go zmieniałeś. |
| Ponowne próby nie występują | Ponowne próby są wyłączone, chyba że włączono je dla konkretnego webhooka. Nie ponawiamy prób dla odpowiedzi 4xx. |
Blok campaign jest zawsze null |
Oczekiwane, jeśli Twoje konto korzysta z agentów: kontakty są przypisane do agenta, a nie do kampanii. Przeczytaj zamiast tego blok agent — zobacz Format danych webhooka. |
| Dane są puste lub nieprawidłowe | Sprawdź, czy Twój system odbiorczy akceptuje format JSON. Sprawdź logi serwera pod kątem błędów parsowania. |
| Adres URL webhooka zwraca błędy | Przetestuj swój adres URL za pomocą narzędzia takiego jak Postman lub webhook.site. |
| Webhook przestał działać całkowicie po awarii | Wielokrotne awarie automatycznie wyłączają webhook. Ponowne zapisanie nie włącza go ponownie — napraw swój punkt końcowy, a następnie skontaktuj się z pomocą techniczną. |
| Zapisywanie lub testowanie zwraca błąd uprawnień | Potrzebujesz uprawnienia „edycja” dla integracji. Poproś właściciela konta o jego przyznanie. |
Lista subscribed_to_tags webhooka wróciła pusta |
subscribed_to_tags nie ogranicza zdarzeń webhooka do tagu — zawęża jedynie, które tagi generują powiadomienie o podsumowaniu konwersacji. Edycja z poziomu formularza webhooka nie czyści już tej listy (naprawiono 21 lipca 2026 r.). Jeśli webhook utracił swoją listę przed tą datą, ustaw subscribed_to_tags ponownie za pomocą API Webhooków — zobacz Wyzwalacze webhooków oparte na tagach. |
Następne kroki
- Integracja z GoHighLevel — użyj webhooków, aby zintegrować Your AI Connector z GHL.
- Dostęp do API — połącz webhooki z API, aby uzyskać zaawansowaną automatyzację.
- Używanie tagów do oznaczania kontaktów — skonfiguruj tagi, które wyzwalają Twoje webhooki.