Webhooks
Получавайте събитията на сесиите си в своя сървър: всяко доставяне е подписано с HMAC-SHA256, повтаря се с експоненциално нарастващо изчакване и носи уникален идентификатор, за да може приемникът Ви да е идемпотентен.
Кога да използвате webhooks
За да реагирате на случващото се в залата, без да питате постоянно: платформата Ви се обажда, когато сесия започне или приключете, когато въпрос се затвори или резултатите му станат окончателни. Доставянето е поне веднъж — може да се повтори, никога не се проваля мълчаливо — затова приемникът Ви трябва да е идемпотентен.
Каталог на събитията
Обслужва се от API на /public/v1/limits — тази страница не пази копие.
- presentation.import.completed
- presentation.import.failed
- question.activated
- question.closed
- question.results.finalized
- report.ready
- session.ended
- session.paused
- session.resumed
- session.started
Заглавки при всяко доставяне
X-Votinova-EventТипът на събитието, точно както е в каталога.X-Votinova-Delivery-IdУникален за всяко доставяне — Вашият ключ за премахване на дубликати.X-Votinova-TimestampСекунди от епохата; част от подписаното, така че повторено доставяне не може да бъде преправено с нова дата.X-Votinova-SignatureHMAC-SHA256 в шестнайсетичен вид, без представка.
Тялото е компактен JSON със събитието и всеки участващ идентификатор — това е, байт по байт, подписаният примерен запис:
{"event":"session.ended","session_id":"68b2e3d4c5f607182930a5bc"}Проверка на подписа
Всяко доставяне се подписва с HMAC-SHA256 върху времевия печат, точка и тялото, с ключ тайния ключ на крайната точка. Сравнете резултата със заглавката X-Votinova-Signature.
- Подписвайте НЕОБРАБОТЕНОТО тяло. Разчитането и повторното му сериализиране променя интервалите и подписът спира да съвпада.
- Сравнявайте в постоянно време, а не с ==.
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)
= 10a86171bd92f5fcf8c28b873978e0214302cc2291c54cc016d18347f3ee7c38Повторни опити
Доставяния на webhook: най-много 8 на брой, с нарастващи изчаквания от 21, 45, 95, 171, 369, 732, 1480 секунди. Щом се изчерпят, доставянето се отбелязва като окончателно неуспешно и може да се повтори ръчно.
Идемпотентност
Използвайте X-Votinova-Delivery-Id като ключ за премахване на дубликати: едно доставяне може да пристигне повече от веднъж, а ефектът Ви трябва да се приложи само веднъж.
X-Votinova-Delivery-Id
Добри практики
- Отговорете с 200 веднага щом доставянето е на сигурно място, и обработвайте в собствената си опашка — бавен приемник трупа повторни опити.
- ВИНАГИ проверявайте подписа, преди да разчетете тялото: без това всеки, който знае адреса Ви, може да измисля събития.
- Премахвайте дубликати по X-Votinova-Delivery-Id: „поне веднъж“ значи, че едно и също доставяне може да дойде два пъти.
- След 10 последователни неуспеха крайната точка се спира сама; включете я отново от панела или по API, щом приемникът Ви се върне.