Gå til innholdet

Webhooks

Webhooks lar systemene dine motta sanntids HTTP POST-varsler når køhendelser skjer — en kølapp blir med i køen, ropes opp, fullføres, og så videre.

  1. Åpne admin.jonot.io/settings/integrations.
  2. Klikk Legg til endepunkt.
  3. Skriv inn en offentlig HTTPS-URL serveren din lytter på.
  4. Velg hvilke hendelser du vil abonnere på.
  5. Klikk Lagre.

Lagre signeringshemmeligheten din — den vises bare én gang. For å bekrefte at endepunktet ditt er nåbart, bruk knappen Send testforespørsel på redigeringssiden for endepunktet.

HendelsesnavnNår den utløses
ticket.joinedEn kunde stiller seg i en kø
ticket.calledEn ansatt roper opp en kølapp til skranken
ticket.completedEn kølapp markeres som fullført
ticket.cancelledEn kunde eller ansatt avbryter en kølapp
ticket.skippedEn kølapp hoppes over (en utsettelse som kan ropes opp igjen)
ticket.no_showEn oppropt eller hoppet-over kølapp bekreftes som en uteblivelse
queue.status_changedStatusen til en kø endres (ACTIVE, PAUSED, eller CLOSED)

Hver levering er en HTTP POST med:

Content-Type: application/json
X-Jonot-Event: ticket.called
X-Jonot-Delivery-Id: <uuid>
X-Jonot-Timestamp: 2024-06-01T12:00:00.000Z
X-Jonot-Signature: v1,<base64-hmac-sha256>
X-Jonot-Payload-Version: v1

Standardkroppen er en JSON-konvolutt. Formen på payload-feltet varierer etter hendelse:

ticket.joined

{
"deliveryId": "<uuid>",
"event": "ticket.joined",
"timestamp": "2024-06-01T12:00:00.000Z",
"org": { "id": "org_…", "name": "My Org" },
"payload": {
"ticket": { "id": "tkt_…", "queueId": "q_…" },
"queue": { "id": "q_…", "name": "Main Queue" },
"location": { "id": "loc_…", "name": "Downtown" }
}
}

ticket.called / ticket.completed / ticket.skipped / ticket.no_show

{
"deliveryId": "<uuid>",
"event": "ticket.called",
"timestamp": "2024-06-01T12:00:00.000Z",
"org": { "id": "org_…", "name": "My Org" },
"payload": {
"ticket": {
"id": "tkt_…",
"number": 42,
"status": "CALLED",
"queueId": "q_…",
"createdAt": "2024-06-01T11:58:00.000Z",
"updatedAt": "2024-06-01T12:00:00.000Z"
}
}
}

ticket.cancelled

{
"deliveryId": "<uuid>",
"event": "ticket.cancelled",
"timestamp": "2024-06-01T12:00:00.000Z",
"org": { "id": "org_…", "name": "My Org" },
"payload": {
"ticketId": "tkt_…",
"queueId": "q_…"
}
}

queue.status_changed

{
"deliveryId": "<uuid>",
"event": "queue.status_changed",
"timestamp": "2024-06-01T12:00:00.000Z",
"org": { "id": "org_…", "name": "My Org" },
"payload": {
"queueId": "q_…",
"status": "PAUSED"
}
}

Jonot signerer hver levering med HMAC-SHA256 over strengen:

<deliveryId>.<timestamp>.<body>

Slik verifiserer du i Node.js (≥18):

import { createHmac, timingSafeEqual } from "node:crypto";
/**
* Returns true when the signature header is valid and the timestamp is
* within 5 minutes of now. Throws for malformed input.
*/
function verifySignature(secret, deliveryId, timestamp, body, header) {
// Replay-attack guard: reject deliveries older than 5 minutes.
const ageMs = Date.now() - new Date(timestamp).getTime();
if (Math.abs(ageMs) > 5 * 60 * 1000) return false;
const expected =
"v1," +
createHmac("sha256", secret)
.update(`${deliveryId}.${timestamp}.${body}`)
.digest("base64");
// timingSafeEqual prevents timing-oracle attacks.
// Buffers must be the same length — if lengths differ the signature is
// invalid, but we still compare a dummy value to keep constant time.
const expectedBuf = Buffer.from(expected);
const headerBuf = Buffer.from(header);
if (expectedBuf.length !== headerBuf.length) return false;
return timingSafeEqual(expectedBuf, headerBuf);
}

Du kan erstatte standard JSON-kroppen med en egendefinert mal. Maler bruker en forenklet Mustache-syntaks:

  • {{ path.to.value }} — erstattes og escapes for innholdstypen: JSON-streng-escapet for application/json, prosentkodet for application/x-www-form-urlencoded, rått for text/plain
  • {{{ path.to.value }}} — erstattes rått (ingen escaping)

Eksempelmal for application/json (abonnert på ticket.joined):

{
"type": "{{ event }}",
"ticketId": "{{ payload.ticket.id }}",
"queueName": "{{ payload.queue.name }}"
}

Feltet for nyttelastmalen er en fullstendig kodeeditor med:

  • Syntaksmarkering og parentesmatching for JSON-maler.
  • Variabelpalett — en alltid synlig rad med innsettingsknapper, én per tilgjengelig variabelbane for de valgte hendelsene dine. Klikk på en knapp for å sette inn et {{ path }}-tegn ved markøren.
  • Live-validering — mens du skriver, sjekker redigeringsverktøyet både JSON-strukturen (når innholdstypen er application/json og ingen rå {{{ }}}-tagger er til stede) og variabelbanene. Diagnostikk vises som innebygde markører i redigeringsverktøyet og som et sammendragsbanner under det:
    • Feil — en bane som er ukjent i alle de valgte hendelsene dine.
    • Advarsel — en bane som bare finnes for noen av de valgte hendelsene dine (den vil være tom for leveringer av de andre hendelsene).

Validering kjører også ved lagring på serveren — tilbakemeldingen i redigeringsverktøyet gjenspeiler serverreglene nøyaktig.

Mislykkede leveringer (ikke-2xx eller tilkoblingsfeil) forsøkes på nytt opptil 3 ganger med eksponentiell tilbaketrekning av Cloudflare Queues. Etter 3 mislykkede forsøk havner leveringen i dødbrev-køen, og endepunktets teller for påfølgende feil øker.

Så snart et endepunkt samler opp 20 påfølgende feil, deaktiveres det automatisk. Aktiver det på nytt fra endepunktets redigeringsside; telleren nullstilles.

Fanen Leveranser på hvert endepunkt viser leveringsforsøkene fra de siste 30 dagene: hendelsestype, HTTP-status, antall forsøk, og tidsstempel. Bruk knappen Last inn mer for å bla gjennom eldre oppføringer.

GrenseVerdi
Endepunkter per organisasjon5
Egendefinerte hoder per endepunkt10
Lengde på hodeverdi1 024 bytes
Størrelse på nyttelastmal16 KB
Leveringstidsavbrudd10 s
Oppbevaringstid for leveringshistorikk30 dager
Maks leveringsrate per organisasjon120 / 60 s
  1. Åpne redigeringssiden for endepunktet.
  2. Klikk Bytt signeringshemmelighet.
  3. Bekreft rotasjonen i dialogen.
  4. Kopier den nye hemmeligheten umiddelbart — den vises bare én gang og kan ikke gjenopprettes. Hvis du lukker dialogen uten å lagre den, må du rotere på nytt for å få en ny klartekstverdi.
  5. Oppdater serveren din til å verifisere signaturer med den nye hemmeligheten.

Det finnes ikke noe overlappingsvindu. Den gamle hemmeligheten slutter å verifisere så snart du bekrefter rotasjonen. Planlegg å distribuere den nye hemmeligheten til mottakeren din umiddelbart etter rotasjonen.

Grensesnittet viser Aktiv hemmelighet: ····XXXX (de siste fire tegnene) ved siden av Bytt-knappen, slik at du kan bekrefte hvilken hemmelighet som gjelder for øyeblikket — nyttig for å bekrefte at mottakeren din og serveren er synkronisert etter en rotasjon.

Når du bør rotere:

  • Mistenkt kompromittering: hemmeligheten dukket opp i en loggfil, ble delt med en ansatt som sluttet, eller ble fanget i en skjermopptak.
  • Rutinehygiene: regelmessig rotasjon begrenser skadeomfanget av en uoppdaget eksponering.
  • Etter enhver endring i hvilke tjenester som kan lese hemmeligheten (rotasjon av nøkkelforvaltning).

Slik oppdaterer du mottakeren:

  1. Roter i admin-grensesnittet og kopier den nye hemmeligheten.
  2. Oppdater hemmeligheten i mottakerens hemmelighetslager (miljøvariabel, hemmelighetsforvalter osv.).
  3. Distribuer den oppdaterte mottakeren.
  4. Bekreft at neste levering lykkes i fanen Leveranser.

Hvis du mistet den nye hemmeligheten før du lagret den:

Roter på nytt. Hver rotasjon genererer en ny tilfeldig hemmelighet. Den forrige klarteksten kan ikke gjenopprettes — bare en AEAD-kryptert form lagres på serversiden.