Přeskočit na obsah

Webhooky

Webhooky umožňují vašim systémům přijímat v reálném čase HTTP POST notifikace, když nastanou události fronty — lístek se připojí, je zavolán, dokončen atd.

  1. Otevřete admin.jonot.io/settings/integrations.
  2. Klikněte na Přidat koncový bod.
  3. Zadejte veřejnou URL adresu HTTPS, na které váš server naslouchá.
  4. Zvolte, k jakým událostem se chcete přihlásit.
  5. Klikněte na Uložit.

Uložte si podpisový tajný klíč — zobrazí se pouze jednou. Pro ověření, že je váš koncový bod dostupný, použijte tlačítko Odeslat testovací požadavek na stránce úpravy koncového bodu.

Název událostiKdy se spustí
ticket.joinedZákazník se připojí k frontě
ticket.calledČlen personálu zavolá lístek na přepážku
ticket.completedLístek je označen jako dokončený
ticket.cancelledZákazník nebo člen personálu zruší lístek
ticket.skippedLístek je přeskočen (odklad s možností znovu vyvolat)
ticket.no_showZavolaný nebo přeskočený lístek je potvrzen jako nedostavení
queue.status_changedZmění se stav fronty (ACTIVE, PAUSED nebo CLOSED)

Každé doručení je HTTP POST s:

Content-Type: application/json
X-Jonot-Event: ticket.called
X-Jonot-Delivery-Id: <uuid>
X-Jonot-Timestamp: 2024-06-01T12:00:00.000Z
X-Jonot-Signature: v1,<base64-hmac-sha256>
X-Jonot-Payload-Version: v1

Výchozí tělo je obálka JSON. Tvar pole payload se liší podle události:

ticket.joined

{
"deliveryId": "<uuid>",
"event": "ticket.joined",
"timestamp": "2024-06-01T12:00:00.000Z",
"org": { "id": "org_…", "name": "My Org" },
"payload": {
"ticket": { "id": "tkt_…", "queueId": "q_…" },
"queue": { "id": "q_…", "name": "Main Queue" },
"location": { "id": "loc_…", "name": "Downtown" }
}
}

ticket.called / ticket.completed / ticket.skipped / ticket.no_show

{
"deliveryId": "<uuid>",
"event": "ticket.called",
"timestamp": "2024-06-01T12:00:00.000Z",
"org": { "id": "org_…", "name": "My Org" },
"payload": {
"ticket": {
"id": "tkt_…",
"number": 42,
"status": "CALLED",
"queueId": "q_…",
"createdAt": "2024-06-01T11:58:00.000Z",
"updatedAt": "2024-06-01T12:00:00.000Z"
}
}
}

ticket.cancelled

{
"deliveryId": "<uuid>",
"event": "ticket.cancelled",
"timestamp": "2024-06-01T12:00:00.000Z",
"org": { "id": "org_…", "name": "My Org" },
"payload": {
"ticketId": "tkt_…",
"queueId": "q_…"
}
}

queue.status_changed

{
"deliveryId": "<uuid>",
"event": "queue.status_changed",
"timestamp": "2024-06-01T12:00:00.000Z",
"org": { "id": "org_…", "name": "My Org" },
"payload": {
"queueId": "q_…",
"status": "PAUSED"
}
}

Jonot podepisuje každé doručení pomocí HMAC-SHA256 nad řetězcem:

<deliveryId>.<timestamp>.<body>

Ověření v Node.js (≥18):

import { createHmac, timingSafeEqual } from "node:crypto";
/**
* Returns true when the signature header is valid and the timestamp is
* within 5 minutes of now. Throws for malformed input.
*/
function verifySignature(secret, deliveryId, timestamp, body, header) {
// Replay-attack guard: reject deliveries older than 5 minutes.
const ageMs = Date.now() - new Date(timestamp).getTime();
if (Math.abs(ageMs) > 5 * 60 * 1000) return false;
const expected =
"v1," +
createHmac("sha256", secret)
.update(`${deliveryId}.${timestamp}.${body}`)
.digest("base64");
// timingSafeEqual prevents timing-oracle attacks.
// Buffers must be the same length — if lengths differ the signature is
// invalid, but we still compare a dummy value to keep constant time.
const expectedBuf = Buffer.from(expected);
const headerBuf = Buffer.from(header);
if (expectedBuf.length !== headerBuf.length) return false;
return timingSafeEqual(expectedBuf, headerBuf);
}

Výchozí tělo JSON můžete nahradit vlastní šablonou. Šablony používají zjednodušenou syntaxi Mustache:

  • {{ path.to.value }} — dosazeno a escapováno podle typu obsahu: escapováno jako řetězec JSON pro application/json, procentuálně zakódováno pro application/x-www-form-urlencoded, surově pro text/plain
  • {{{ path.to.value }}} — dosazeno surově (bez escapování)

Příklad šablony pro application/json (přihlášeno k ticket.joined):

{
"type": "{{ event }}",
"ticketId": "{{ payload.ticket.id }}",
"queueName": "{{ payload.queue.name }}"
}

Pole šablony payloadu je plnohodnotný editor kódu s:

  • Zvýrazněním syntaxe a párováním závorek pro šablony JSON.
  • Paletou proměnných — vždy viditelným řádkem tlačítek pro vkládání, po jednom pro každou dostupnou cestu proměnné pro vaše vybrané události. Kliknutím na tlačítko vložíte token {{ path }} na pozici kurzoru.
  • Živou validací — během psaní editor kontroluje jak strukturu JSON (pokud je typ obsahu application/json a nejsou přítomny surové značky {{{ }}}), tak cesty proměnných. Diagnostika se zobrazuje jako vložené značky v editoru a jako souhrnný banner pod ním:
    • Chyba — cesta, která je neznámá ve všech vašich vybraných událostech.
    • Varování — cesta, která existuje pouze pro některé z vašich vybraných událostí (u doručení ostatních událostí bude prázdná).

Validace se také spouští při uložení na serveru — zpětná vazba editoru přesně odpovídá pravidlům serveru.

Neúspěšná doručení (jiný než 2xx stav nebo chyba připojení) jsou opakována až 3krát s exponenciálním prodlením pomocí Cloudflare Queues. Po 3 selháních doručení skončí ve frontě nedoručitelných zpráv a čítač po sobě jdoucích selhání koncového bodu se zvýší.

Jakmile koncový bod nahromadí 20 po sobě jdoucích selhání, je automaticky deaktivován. Znovu jej povolíte na stránce úpravy koncového bodu; čítač se vynuluje.

Karta Doručení u každého koncového bodu zobrazuje pokusy o doručení za posledních 30 dní: typ události, stav HTTP, počet pokusů a časové razítko. Pomocí tlačítka Načíst další procházejte starší záznamy.

LimitHodnota
Koncové body na organizaci5
Vlastní hlavičky na koncový bod10
Délka hodnoty hlavičky1 024 bajtů
Velikost šablony payloadu16 KB
Časový limit doručení10 s
Uchování historie doručení30 dní
Max. rychlost doručení na organizaci120 / 60 s

Rotace podpisového tajného klíče

Sekce “Rotace podpisového tajného klíče”
  1. Otevřete stránku úpravy koncového bodu.
  2. Klikněte na Otočit podpisový tajný klíč.
  3. Potvrďte rotaci v dialogovém okně.
  4. Ihned zkopírujte nový tajný klíč — zobrazí se pouze jednou a nelze jej znovu obnovit. Pokud dialog zavřete bez uložení, musíte klíč otočit znovu, abyste získali nový čistý text.
  5. Aktualizujte svůj server tak, aby ověřoval podpisy novým tajným klíčem.

Neexistuje žádné překryvné období. Starý tajný klíč přestane ověřovat platnost okamžitě po potvrzení rotace. Naplánujte nasazení nového tajného klíče na svůj přijímač ihned po rotaci.

Uživatelské rozhraní zobrazuje Aktivní tajný klíč: ····XXXX (poslední čtyři znaky) vedle tlačítka Otočit, abyste mohli ověřit, který tajný klíč je právě platný — užitečné pro potvrzení, že váš přijímač a server jsou po rotaci synchronizovány.

Hygiena podpisového tajného klíče

Sekce “Hygiena podpisového tajného klíče”

Kdy rotovat:

  • Podezření na kompromitaci: tajný klíč se objevil v log souboru, byl sdílen s odcházejícím členem personálu nebo byl zachycen v nahrávce obrazovky.
  • Rutinní hygiena: pravidelná rotace omezuje dopad neodhaleného úniku.
  • Po jakékoli změně toho, které služby mohou tajný klíč číst (rotace správy klíčů).

Jak aktualizovat přijímač:

  1. Otočte klíč v uživatelském rozhraní administrace a zkopírujte nový tajný klíč.
  2. Aktualizujte tajný klíč v úložišti tajných klíčů vašeho přijímače (proměnná prostředí, správce tajných klíčů atd.).
  3. Nasaďte aktualizovaný přijímač.
  4. Potvrďte, že další doručení proběhne úspěšně na kartě Doručení.

Pokud jste ztratili nový tajný klíč před jeho uložením:

Otočte klíč znovu. Každá rotace vygeneruje nový náhodný tajný klíč. Předchozí čistý text nelze obnovit — na straně serveru je uložena pouze podoba zašifrovaná pomocí AEAD.