Webhookit

Vastaanota istuntojesi tapahtumat omaan taustajärjestelmääsi: jokainen toimitus on HMAC-SHA256-allekirjoitettu, uudelleenyritykset kasvavat eksponentiaalisesti, ja mukana on yksilöivä tunnus, jotta vastaanottimesi voi olla idempotentti.

Milloin webhookeja kannattaa käyttää

Kun haluat reagoida istuntohuoneessa tapahtuvaan ilman jatkuvaa kyselyä: alusta kutsuu sinua, kun istunto alkaa tai päättyy, kysymys sulkeutuu tai sen tulokset viimeistellään. Toimitus on vähintään kerran -tyyppinen – se voi toistua, mutta ei koskaan epäonnistu hiljaisesti – ja siksi vastaanottimesi on oltava idempotentti.

Tapahtumaluettelo

API tarjoaa sen osoitteessa /public/v1/limits – tämä sivu ei säilytä kopiota.

  • presentation.import.completed
  • presentation.import.failed
  • question.activated
  • question.closed
  • question.results.finalized
  • report.ready
  • session.ended
  • session.paused
  • session.resumed
  • session.started

Otsakkeet jokaisessa toimituksessa

  • X-Votinova-EventTapahtuman tyyppi täsmälleen sellaisena kuin se on luettelossa.
  • X-Votinova-Delivery-IdToimituskohtainen ja yksilöivä – tällä tunnistat kaksoiskappaleet.
  • X-Votinova-TimestampEpoch-sekunteina; kuuluu allekirjoitettavaan osaan, joten uusittua toimitusta ei voi päivätä uudelleen.
  • X-Votinova-SignatureHMAC-SHA256 heksana, ilman etuliitettä.

Runko on tiivistä JSON-muotoa ja sisältää tapahtuman sekä kaikki siihen liittyvät tunnukset – tämä on tavu tavulta se allekirjoitettu esimerkkitoimitus:

{"event":"session.ended","session_id":"68b2e3d4c5f607182930a5bc"}

Allekirjoituksen varmistaminen

Jokainen toimitus allekirjoitetaan HMAC-SHA256:lla aikaleimasta, pisteestä ja rungosta, avaimena päätepisteen salaisuus. Vertaa tulosta X-Votinova-Signature-otsakkeeseen.

  • Allekirjoita RAAKA runko. Jäsentäminen ja uudelleensarjallistaminen muuttaa välilyöntejä, eikä allekirjoitus enää täsmää.
  • Vertaa vakioajassa, älä ==-operaattorilla.
Varmennettu oikeaa toimitusta vasten
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

Uudelleenyritykset

Webhook-toimitusta yritetään enintään 8 kertaa, ja odotusajat kasvavat näin: 21, 45, 95, 171, 369, 732, 1480 sekuntia. Kun yritykset on käytetty, toimitus siirtyy kuolleiden kirjeiden jonoon, ja sen voi lähettää uudelleen käsin.

Idempotenssi

Käytä X-Votinova-Delivery-Id-otsaketta kaksoiskappaleiden tunnistamiseen: sama toimitus voi saapua useammin kuin kerran, mutta sen vaikutus saa toteutua vain kerran.

X-Votinova-Delivery-Id

Parhaat käytännöt

  • Vastaa 200 heti, kun toimitus on turvassa, ja käsittele se omassa jonossasi – hidas vastaanotin kerryttää uudelleenyrityksiä.
  • Varmista allekirjoitus AINA ennen jäsentämistä: ilman sitä kuka tahansa URL-osoitteesi tunteva voi keksiä tapahtumia.
  • Poista kaksoiskappaleet X-Votinova-Delivery-Id-otsakkeen perusteella: vähintään kerran tarkoittaa, että sama toimitus voi tulla kahdesti.
  • Kymmenen peräkkäisen epäonnistumisen jälkeen päätepiste keskeyttää itsensä; ota se uudelleen käyttöön paneelista tai API:n kautta, kun vastaanottimesi on taas pystyssä.