Ringhum.

Deweloperzy

Webhooki

Odbieraj podpisane powiadomienia HTTPS, gdy połączenia się kończą, przyjmowane są wiadomości, zmieniają się wizyty, zamówienia i rezerwacje, albo kończy się kampania, oraz sprawdzaj, czy każde z nich naprawdę pochodzi od Ringhum.

5 min czytania Zaktualizowano 24 września 2026

Na tej stronie

Webhook wysyła żądanie HTTPS do Twojego serwera w chwili, gdy coś dzieje się w Twojej przestrzeni roboczej. Używaj webhooków zamiast odpytywania API: gdy połączenie się kończy, od razu otrzymujesz podsumowanie, wynik, zebrane dane i transkrypcję. Każde dostarczenie jest podpisane sekretem znanym tylko Tobie i Ringhum, więc Twój serwer może odrzucić wszystko, co nie pochodzi od Ringhum.

Dodaj punkt końcowy

Tylko Właściciel i Administratorzy przestrzeni roboczej mogą dodawać, testować i usuwać punkty końcowe.

  1. Otwórz Deweloperzy w pasku bocznym.
  2. W karcie Webhooki kliknij Dodaj punkt końcowy.
  3. Wpisz URL punktu końcowego. Musi zaczynać się od https://.
  4. W sekcji Zdarzenia zaznacz zdarzenia, które Cię interesują. call.ended jest zaznaczone za Ciebie.
  5. Kliknij Dodaj punkt końcowy.
  6. Skopiuj sekret podpisujący z zielonego pola (zaczyna się od whsec_) i zapisz go na swoim serwerze. Kliknij Gotowe.

Ważne: Sekret podpisujący jest pokazywany tylko raz. Jeśli go zgubisz, usuń punkt końcowy i dodaj go ponownie, aby otrzymać nowy sekret.

Możesz dodać tyle punktów końcowych, ile potrzebujesz. Webhooki obejmują każdego asystenta w przestrzeni roboczej. Punktami końcowymi możesz też zarządzać przez API, za pomocą POST /webhooks i klucza z uprawnieniem write.

Zdarzenia

Zdarzenie Kiedy jest wysyłane
call.started Połączenie zostało odebrane przez asystenta
call.ended Połączenie się zakończyło i zostało podsumowane (zawiera transkrypcję i podsumowanie)
call.transferred Połączenie zostało przekazane do człowieka
message.taken Asystent przyjął wiadomość
appointment.booked Asystent umówił wizytę
appointment.rescheduled Wizyta została przełożona na nowy termin
appointment.cancelled Wizyta została odwołana
order.created Zamówienie zostało złożone (przez asystenta, ręcznie lub przez API)
order.updated Zamówienie przeszło do nowego statusu
order.cancelled Zamówienie zostało odwołane
reservation.created Pokój został zarezerwowany (przez asystenta, ręcznie lub przez API)
reservation.updated Rezerwacja przeszła do nowego statusu (potwierdzona, zameldowana, wymeldowana, nieobecność)
reservation.cancelled Rezerwacja została odwołana
campaign.completed Kampania wychodząca zakończyła dzwonienie do swojej listy
test.ping Kliknąłeś Wyślij test

Jak wygląda dostarczenie

Każde dostarczenie to POST z treścią JSON i tymi nagłówkami:

POST https://example.com/hooks/ringhum
Content-Type: application/json
User-Agent: Ringhum-Webhooks/1.0
X-Ringhum-Event: call.ended
X-Ringhum-Timestamp: 1789250000
X-Ringhum-Signature: v1=5f1a…

{
  "id": "evt_8f2k…",
  "type": "call.ended",
  "created_at": "2026-09-24T14:03:11+00:00",
  "data": {
    "call_id": 4812,
    "direction": "inbound",
    "from": "+14155550132",
    "to": "+14155550100",
    "assistant_id": 3,
    "status": "completed",
    "outcome": "message_taken",
    "sentiment": "neutral",
    "duration_seconds": 94,
    "summary": "Caller asked for a quote for a kitchen repair…",
    "extracted": { "name": "Dana Lee", "reason": "Quote" },
    "transcript": [
      { "role": "assistant", "content": "Hello, you've reached…" },
      { "role": "user", "content": "Hi, I'd like a quote…" }
    ]
  }
}

Obiekt data zależy od zdarzenia:

  • call.ended i message.taken: pola połączenia powyżej.
  • call.started i call.transferred: call_id, direction, from, to, assistant_id, status i started_at.
  • appointment.*: appointment_id, title, status, starts_at, ends_at, timezone, customer (imię, telefon, e-mail), contact_id, service, staff, call_id i notes.
  • order.*: order_id, number, status, fulfillment, customer, address, items z opcjami i cenami, currency, subtotal, fee, total, source, call_id oraz, dla odwołań, cancel_reason.
  • reservation.*: reservation_id, number, status, room, check_in, check_out, nights, adults, children, guest, currency, nightly, total i source.
  • campaign.completed: campaign_id, name oraz liczniki postępu kampanii.

Uwaga: Gdy asystent umawia wizytę podczas połączenia, możesz otrzymać appointment.booked dwa razy. Jedno jest wysyłane w chwili umówienia, z polami wizyty. Drugie jest wysyłane po podsumowaniu połączenia, z polami połączenia. Sprawdź, czy data ma appointment_id czy call_id, i użyj pola id, aby uniknąć dwukrotnego przetworzenia tego samego dostarczenia.

Zweryfikuj podpis

Podpis to HMAC-SHA256 znacznika czasu, kropki i surowej treści żądania, z kluczem będącym sekretem podpisującym Twojego punktu końcowego. Jest wysyłany jako v1= wraz z heksadecymalnym skrótem.

  1. Odczytaj surową treść dokładnie tak, jak została odebrana, przed jakimkolwiek parsowaniem JSON.
  2. Zbuduj ciąg {X-Ringhum-Timestamp}.{surowa treść}.
  3. Oblicz HMAC-SHA256 ze swoim sekretem i dodaj przedrostek v1=.
  4. Porównaj to z X-Ringhum-Signature, używając porównania w stałym czasie.
  5. Odrzuć żądanie, jeśli znacznik czasu jest starszy niż pięć minut, aby zablokować powtórzone żądania.

Node.js:

const crypto = require('crypto');

function isValid(req, rawBody, secret) {
  const ts = req.header('X-Ringhum-Timestamp');
  const sig = req.header('X-Ringhum-Signature') || '';
  const expected = 'v1=' + crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && sig.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}

PHP:

$ts = $_SERVER['HTTP_X_RINGHUM_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_RINGHUM_SIGNATURE'] ?? '';
$expected = 'v1=' . hash_hmac('sha256', $ts . '.' . file_get_contents('php://input'), $secret);
if (! hash_equals($expected, $sig) || abs(time() - (int) $ts) > 300) {
    http_response_code(400);
    exit;
}

Odpowiedzi, limity czasu i ponowienia

  • Odpowiedz dowolnym statusem 2xx, aby potwierdzić dostarczenie. Wolniejszą pracę wykonuj po odpowiedzi.
  • Ringhum czeka na Twoją odpowiedź do 10 sekund.
  • Jeśli Twój punkt końcowy nie odpowie statusem 2xx, dostarczenie jest próbowane maksymalnie 3 razy łącznie: od razu, ponownie po około 10 sekundach, i ostatni raz około 60 sekund później. Potem jest porzucane.
  • Dostarczenia mogą docierać w innej kolejności. Użyj created_at oraz identyfikatorów w data, aby ustawić je w kolejności.

Tabela Webhooki pokazuje ostatni status HTTP każdego punktu końcowego i kiedy został wysłany. Nieudany punkt końcowy pozostaje aktywny; Ringhum go za Ciebie nie wyłącza.

Testuj, wstrzymuj i usuwaj

  • Wyślij test wysyła od razu zdarzenie test.ping, a komunikat pokazuje status HTTP zwrócony przez Twój punkt końcowy.
  • Przełącznik Aktywny wstrzymuje punkt końcowy. Zdarzenia, które mają miejsce, gdy jest wyłączony, nie są wysyłane później.
  • Usuń usuwa punkt końcowy i jego sekret.

Najczęstsze pytania

Czym różni się to od aplikacji Zapier, Make i n8n w Integracjach? Te połączenia korzystają ze strony Integracje i jej sześciu typów zdarzeń. Ich treść to {"event", "workspace", "sent_at", "data"}, a gdy ustawisz sekret, nagłówek podpisu to X-Ringhum-Signature: sha256=…, czyli HMAC-SHA256 samej treści. Webhooki deweloperskie, opisane tutaj, obejmują więcej zdarzeń i używają podpisu v1= ze znacznikiem czasu. Zobacz Wybór, co jest wysyłane.

Mój punkt końcowy zwraca 2xx, ale mój kod nic nie widzi. Sprawdź, czy zdarzenie jest zaznaczone dla tego punktu końcowego, czy punkt końcowy jest aktywny oraz czy Twoja zapora sieciowa pozwala na żądania z internetu.

Dlaczego weryfikacja podpisu się nie udaje? Najczęściej treść została sparsowana i ponownie zakodowana przed haszowaniem. Haszuj surowe bajty dokładnie tak, jak zostały odebrane.

Nadal masz problem?

Napisz na [email protected] lub wyślij nam wiadomość. Plany Team i Scale mają priorytetowe wsparcie.

Skontaktuj się z pomocą