Webhookuri
Primiți evenimentele sesiunilor Dumneavoastră în propriul sistem: fiecare livrare este semnată HMAC-SHA256, se reîncearcă cu așteptări exponențiale și poartă un identificator unic, ca receptorul Dumneavoastră să poată fi idempotent.
Când se folosesc webhookurile
Ca să reacționați la ce se întâmplă în sală fără să interogați repetat: platforma vă cheamă când o sesiune începe sau se încheie, când o întrebare se închide sau când rezultatele ei devin definitive. Livrarea este cel puțin o dată – se poate repeta, dar nu eșuează niciodată în tăcere –, motiv pentru care receptorul Dumneavoastră trebuie să fie idempotent.
Catalogul de evenimente
Servit de API la /public/v1/limits – această pagină nu păstrează nicio copie.
- presentation.import.completed
- presentation.import.failed
- question.activated
- question.closed
- question.results.finalized
- report.ready
- session.ended
- session.paused
- session.resumed
- session.started
Anteturile fiecărei livrări
X-Votinova-EventTipul evenimentului, exact așa cum apare în catalog.X-Votinova-Delivery-IdUnic pentru fiecare livrare – cheia Dumneavoastră de deduplicare.X-Votinova-TimestampSecunde epoch; face parte din ce se semnează, așa că o livrare reluată nu poate fi redatată.X-Votinova-SignatureHMAC-SHA256 în hexazecimal, fără prefix.
Corpul este JSON compact, cu evenimentul și toți identificatorii implicați – aceasta este, octet cu octet, livrarea de exemplu semnată:
{"event":"session.ended","session_id":"68b2e3d4c5f607182930a5bc"}Verificarea semnăturii
Fiecare livrare este semnată cu HMAC-SHA256 peste marca de timp, un punct și corpul mesajului, folosind drept cheie secretul punctului final. Comparați rezultatul cu antetul X-Votinova-Signature.
- Semnați corpul BRUT. Dacă îl analizați și îl reserializați, se schimbă spațiile albe, iar semnătura nu mai corespunde.
- Comparați în timp constant, nu cu ==.
const crypto = require("node:crypto");
function verify(headers, rawBody, secret) {
const timestamp = headers["x-votinova-timestamp"];
const signature = headers["x-votinova-signature"];
const expected = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}secret whsec_3f8a1c92d4e5b6a7
timestamp 1785321600
body {"event":"session.ended","session_id":"68b2e3d4c5f607182930a5bc"}
HMAC-SHA256(secret, timestamp + "." + body)
= 10a86171bd92f5fcf8c28b873978e0214302cc2291c54cc016d18347f3ee7c38Reîncercări
Livrări prin webhook: cel mult 8 încercări, cu așteptări crescânde (în secunde): 21, 45, 95, 171, 369, 732, 1480. Odată epuizate, livrarea devine nelivrabilă și poate fi retrimisă manual.
Idempotență
Folosiți X-Votinova-Delivery-Id drept cheie de deduplicare: o livrare poate sosi de mai multe ori, iar efectul ei trebuie aplicat o singură dată.
X-Votinova-Delivery-Id
Bune practici
- Răspundeți 200 imediat ce livrarea este pusă la adăpost și prelucrați-o pe coada Dumneavoastră – un receptor lent adună reîncercări.
- Verificați ÎNTOTDEAUNA semnătura înainte de a analiza conținutul: fără ea, oricine vă știe adresa poate inventa evenimente.
- Deduplicați după X-Votinova-Delivery-Id: cel puțin o dată înseamnă că aceeași livrare vă poate chema de două ori.
- După 10 eșecuri la rând, punctul final se pune singur în pauză; reactivați-l din panou sau prin API, după ce receptorul Dumneavoastră și-a revenit.