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, щойно доставка в безпеці, і обробляйте її у власній черзі — повільний приймач накопичує повтори.
- ЗАВЖДИ перевіряйте підпис перед розбором: без цього будь-хто, хто знає Вашу URL-адресу, може вигадувати події.
- Дедуплікуйте за X-Votinova-Delivery-Id: доставка щонайменше один раз означає, що та сама доставка може прийти двічі.
- Після 10 невдач поспіль кінцева точка призупиняється сама; увімкніть її знову з панелі або через API, коли Ваш приймач відновиться.