Webhooki czatu na żywo
Webhooki umożliwiają onWebChat wysyłanie zdarzeń na Twój serwer w czasie rzeczywistym. Za każdym razem, gdy coś się dzieje (rozpoczyna się nowy czat, zostaje wysłana wiadomość, czat zostaje zamknięty lub oceniony, odwiedzający zostawia wiadomość offline), wysyłamy żądanie HTTP POST z treścią JSON na wybrany przez Ciebie adres URL.
To najprostszy sposób, aby synchronizować zapisy czatów z CRM lub CMS, wysyłać e-maile uzupełniające (follow-up), tworzyć własne raporty lub powiadamiać inny system, bez cyklicznego odpytywania (pollingu).
Webhooki są dostępne we wszystkich płatnych planach oraz w trakcie 14-dniowego darmowego okresu próbnego. Każde dostarczenie jest podpisane, dzięki czemu możesz zweryfikować, że naprawdę pochodzi z onWebChat.
POST https://your-server.com/onwebchat-webhook
Content-Type: application/json
User-Agent: onWebChat-Webhooks/1.0
X-OWC-Event: chat.closed
X-OWC-Delivery: 9381
X-OWC-Signature: sha256=4f1c...c2a9
{ "event": "chat.closed", "siteid": 1234, ... }
Konfiguracja webhooków
Zaloguj się do panelu jako administrator i przejdź do Settings → Webhooks. Kliknij „Add endpoint”, wklej adres URL, który ma odbierać zdarzenia, wybierz interesujące Cię zdarzenia (lub zaznacz „All events”, co obejmuje też zdarzenia, które dodamy w przyszłości) i zapisz.
Podczas tworzenia endpointu generujemy dla niego sekret podpisywania (zaczyna się od whsec_). Użyjesz go do weryfikacji przychodzących żądań (zobacz sekcję Weryfikacja podpisów poniżej). Sekret możesz w każdej chwili wygenerować ponownie; stary przestaje wtedy natychmiast działać.
Możesz dodać wiele endpointów na stronę i przeglądać ostatnie dostarczenia, w tym status HTTP, liczbę prób i ewentualne błędy, bezpośrednio w panelu.
/* Dashboard → Settings → Webhooks */
URL : https://your-server.com/onwebchat-webhook
Events : chat.closed, message.created
Secret : whsec_3f9a... (used to verify requests)
Status : Enabled
Typy zdarzeń
Subskrybuj dowolną kombinację poniższych zdarzeń. Każda wiadomość ma pole „author” o wartości visitor, agent lub ai (oraz trigger w przypadku wiadomości wyzwalaczy w transkrypcji chat.closed), więc to samo zdarzenie message.created obejmuje rozmowy obsługiwane przez Twój zespół i przez chatbota AI.
| Zdarzenie | Wysyłane, gdy |
|---|---|
chat.created | Rozpoczyna się nowy czat (dialog). Pole source wskazuje, jak: visitor, trigger lub agent. |
chat.assigned | Agent przejmuje czat: odbiera go, przejmuje od innego agenta lub od chatbota AI albo akceptuje przekazanie. Pole source ma wartość pickup, reassign, ai_takeover lub transfer. |
message.created | W czacie zostaje wysłana nowa wiadomość. Obejmuje wiadomości od odwiedzającego, agenta i chatbota AI. |
chat.closed | Czat się kończy. Dane zawierają pełną transkrypcję, dane odwiedzającego i etykiety. |
chat.rated | Odwiedzający ocenia czat (od 1 do 5 gwiazdek). |
offline_message.created | Odwiedzający wysyła formularz offline lub kontaktowy, gdy żaden agent nie jest dostępny. |
visitor.updated | Agent aktualizuje w panelu imię, e-mail, telefon lub notatki odwiedzającego. |
visitor.banned | Agent blokuje odwiedzającego w panelu. |
visitor.unbanned | Agent odblokowuje w panelu wcześniej zablokowanego odwiedzającego. |
Format danych (payload)
Każdy webhook to obiekt JSON o tej samej strukturze zewnętrznej: nazwa zdarzenia, Twoje siteid, znacznik czasu ISO-8601 i obiekt data, którego zawartość zależy od zdarzenia.
Przykład pokazuje dane zdarzenia chat.closed, które zawierają całą rozmowę. Mniejsze zdarzenia, takie jak message.created lub chat.rated, zawierają tylko odpowiednie pola.
{
"event": "chat.closed",
"siteid": 1234,
"created_at": "2026-06-22T07:40:52.322Z",
"data": {
"chat_id": 1206836,
"started_at": "22-06-2026 10:40",
"closed_at": "2026-06-22T07:40:52.322Z",
"visitor": {
"name": "Sarah Chen",
"email": "sarah@example.com",
"phone": "",
"notes": "",
"country_code": "us",
"country": "United States",
"os": "Windows 10",
"browser": "Chrome 149.0"
},
"agents": ["Alex"],
"labels": [{ "name": "sales", "color": "#4caf50" }],
"messages": [
{ "author": "visitor", "agent_name": "", "text": "pricing info please", "time": "10:40", "date": "22-06-2026" },
{ "author": "ai", "agent_name": "", "text": "Here is a quick overview...", "time": "10:40", "date": "22-06-2026" },
{ "author": "agent", "agent_name": "Alex", "text": "Hi Sarah, I can help with a quote.", "time": "10:41", "date": "22-06-2026" }
]
}
}
Weryfikacja podpisów
Każde żądanie zawiera nagłówek X-OWC-Signature z hashem HMAC-SHA256 dokładnej, surowej treści żądania, obliczonym za pomocą sekretu podpisywania Twojego endpointu.
Aby zweryfikować żądanie, oblicz HMAC-SHA256 surowej treści żądania za pomocą swojego sekretu i porównaj go z wartością nagłówka (częścią po "sha256="). Używaj porównania w stałym czasie i zawsze hashuj surową treść, a nie jej ponownie zserializowaną wersję.
Otrzymujesz też nagłówki X-OWC-Event (nazwa zdarzenia) i X-OWC-Delivery (unikalny identyfikator dostarczenia, który pozostaje taki sam przy ponowieniach, więc możesz go użyć do usuwania duplikatów). Żądania są wysyłane z nagłówkiem User-Agent onWebChat-Webhooks/1.0.
// Node.js / Express
const crypto = require('crypto');
app.post('/onwebchat-webhook',
express.raw({ type: '*/*' }), (req, res) => {
const secret = 'whsec_your_secret';
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(req.body) // raw Buffer
.digest('hex');
const got = req.headers['x-owc-signature'] || '';
// constant-time compare; guard length first (timingSafeEqual throws on mismatch)
const a = Buffer.from(got), b = Buffer.from(expected);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.status(401).end();
const payload = JSON.parse(req.body.toString());
// ... handle payload.event ...
res.sendStatus(200);
});
Weryfikacja w PHP
Ta sama weryfikacja w PHP: odczytaj surową treść żądania, ponownie oblicz HMAC swoim sekretem i porównaj wyniki za pomocą hash_equals().
<?php
$secret = 'whsec_your_secret';
$payload = file_get_contents('php://input');
$got = $_SERVER['HTTP_X_OWC_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $got)) {
http_response_code(401);
exit;
}
$event = json_decode($payload, true);
// ... handle $event['event'] ...
http_response_code(200);
Ponowienia i automatyczne wyłączanie
Twój endpoint powinien odpowiedzieć statusem 2xx jak najszybciej, maksymalnie w ciągu 10 sekund. Każda odpowiedź inna niż 2xx, przekroczenie limitu czasu lub błąd połączenia są traktowane jako nieudana próba.
Nieudane dostarczenia są ponawiane z rosnącym opóźnieniem: po 1 minucie, 5 minutach, 20 minutach, 1 godzinie i 2 godzinach (łącznie 6 prób).
Jeśli 5 kolejnych dostarczeń nie powiedzie się mimo wszystkich ponowień, endpoint zostaje automatycznie wyłączony, a właściciel konta otrzymuje e-mail. Po usunięciu problemu włącz go ponownie w panelu. Zwrócenie statusu HTTP 410 (Gone) natychmiast wyłącza endpoint.
Attempt 1 → immediately
Attempt 2 → after 1 minute
Attempt 3 → after 5 minutes
Attempt 4 → after 20 minutes
Attempt 5 → after 1 hour
Attempt 6 → after 2 hours
5 failed deliveries in a row → endpoint disabled
Dobre praktyki
- Zawsze weryfikuj nagłówek X-OWC-Signature, zanim zaufasz otrzymanym danym.
- Odpowiadaj szybko statusem 2xx, a cięższą pracę wykonuj asynchronicznie (w kolejce), aby nie przekroczyć limitu czasu.
- Używaj X-OWC-Delivery do deduplikacji, ponieważ to samo dostarczenie może być ponowione po przejściowym błędzie.
- Udostępniaj endpoint przez HTTPS.
- Ignoruj nieznane typy zdarzeń, aby nowe zdarzenia, które dodamy później, nie zepsuły Twojej integracji.
Chcesz zacząć? Zobacz plany lub otwórz Settings → Webhooks w swoim panelu.