Webhooky
Webhooky jsou způsob, jak se váš backend dozví o věcech, které se dějí asynchronně — konec relací, dokončení post-processingu nahrávání, ukotvení auditních řetězců na TSA. Zaregistrujte URL, ověřte podpis u každého POST, dispečujte podle typu události.
Typy událostí
| Událost | Kdy |
|---|---|
session.created | Nová relace přes SPA nebo veřejné API |
session.completed | Relace ukončena (ručně nebo přes API) |
participant.joined | Uživatel v terénu (nebo pozorovatel) se připojil k relaci |
participant.left | Účastník se odpojil |
evidence.added | Zachycen nový snímek / anotace / tabule / klip / dokument |
recording.ready | K dispozici post-processované artefakty nahrávání |
audit.anchored | Hlava řetězce ukotvena u jedné z nakonfigurovaných TSA |
signature.completed | Podepsané PDF (SES/AES/QES) je připraveno ke stažení |
webhook.test | Vyvoláno tlačítkem „Test fire“ v administraci SPA, s malým syntetickým payloadem |
Podoba obálky
{
"id": "evt_01HGB9...",
"type": "session.completed",
"created_at": "2026-05-23T11:42:15Z",
"org_id": 42,
"data": {
/* event-specific payload — full resource shape */
}
} id je stabilní napříč opakováními — použijte jej jako idempotency key na straně příjemce.
Hlavička podpisu
Každý POST nese hlavičku NB-Signature ve formátu ve stylu Stripe:
NB-Signature: t=1716461235,v1=5257a8...3e2c1f Hodnota v1 je HMAC-SHA256(secret, "{timestamp}.{body}") v hex. Hodnota t je Unixové časové razítko v okamžiku podpisu. 5minutové okno tolerance odchylky odmítá replaye starších payloadů.
Ověřování v kódu
Node
import { NexBasira, InvalidSignatureError } from "@nexbasira/node";
const nb = new NexBasira({ apiKey: "...", apiSecret: "..." });
// Express handler — important: use express.raw() so the body is the
// untouched bytes the signature was computed over.
app.post("/nb-webhook", express.raw({ type: "application/json" }), (req, res) => {
const sig = req.header("NB-Signature")!;
const secret = process.env.NB_WEBHOOK_SECRET!;
let event;
try {
event = nb.webhooks.constructEvent(req.body, sig, secret);
} catch (err) {
if (err instanceof InvalidSignatureError) {
return res.status(401).send("bad signature");
}
throw err;
}
// event is now type-narrowed by event.type
return handleEvent(event, res);
}); Python
from nexbasira import NexBasira, InvalidSignatureError
nb = NexBasira(api_key="...", api_secret="...")
# Flask handler — get the raw body, not request.get_json()
@app.post("/nb-webhook")
def webhook():
sig = request.headers["NB-Signature"]
secret = os.environ["NB_WEBHOOK_SECRET"]
try:
event = nb.webhooks.construct_event(request.data, sig, secret)
except InvalidSignatureError:
return ("bad signature", 401)
return handle_event(event) Chování opakování
Doručení je považováno za úspěšné, když váš endpoint vrátí 2xx do 30 s. Cokoli jiného spouští exponenciální backoff:
30s → 5m → 1h → 6h → 24h → DROPPED Po 50 po sobě jdoucích selháních napříč všemi událostmi se endpoint automaticky deaktivuje. Administrátor organizace jej může znovu povolit z administrace SPA, jakmile je příjemce opět v provozu.
Idempotence na vaší straně
Doručení webhooků se mohou opakovat. Použijte event.id jako klíč pro deduplikaci:
-- Postgres example
INSERT INTO webhook_deliveries (event_id, processed_at)
VALUES ($1, NOW())
ON CONFLICT (event_id) DO NOTHING
RETURNING event_id;
-- If RETURNING is empty, this is a duplicate — skip the side-effect. Podpisové tajné klíče
Každý registrovaný webhook endpoint má vlastní podpisový tajný klíč whsec_*. Prostý text se zobrazí právě jednou při registraci endpointu (nebo jeho rotaci); poté ukládáme kopii šifrovanou pomocí Fernet a zobrazujeme pouze prvních 6 znaků pro identifikaci.
Rotujte přes SPA → Admin → Webhooks → Rotate secret. Stávající příjemci budou odmítat podepsané události, dokud nebudou aktualizováni novým tajným klíčem — naplánujte rotaci na dobu nasazení.
Testovací odeslání
Každý registrovaný endpoint má v administraci SPA tlačítko „Test fire“, které odešle obálku webhook.test, abyste mohli ověřit svého příjemce před ostrým provozem. Testovací obálka má stejný tvar jako reálná událost, ale se syntetickým payloadem označeným "test": true v data.
Protokol doručení
SPA → Admin → Webhooks zobrazuje posledních 100 doručení na endpoint s HTTP stavem, počtem pokusů, posledním tělem odpovědi (zkráceným) a časovými razítky. Filtrujte podle stavu / endpointu pro ladění problémů příjemce.