Gå til indhold

Webhooks

Webhooks sender HTTP POST-beskeder til dine systemer i realtid, når en kølap oprettes, kaldes, afsluttes eller ændres på anden måde.

  1. Åbn admin.jonot.io/settings/integrations.
  2. Klik på Tilføj endpoint.
  3. Indtast en offentlig HTTPS-URL, din server lytter på.
  4. Vælg hvilke hændelser, du vil abonnere på.
  5. Klik på Gem endpoint.

Gem signeringshemmeligheden. Den vises kun én gang. Brug Send testanmodning på endpointets redigeringsside.

HændelsesnavnHvornår den udløses
ticket.joinedEn kunde stiller sig i en kø
ticket.calledEt personalemedlem kalder en kølap til servicedisken
ticket.completedEn kølap markeres som afsluttet
ticket.cancelledEn kunde eller et personalemedlem annullerer en kølap
ticket.skippedEn kølap springes over (en genopkaldelig udskydelse)
ticket.no_showEn kaldt eller oversprunget kølap bekræftes som en udeblivelse
queue.status_changedEn køs status ændres (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

Standardindholdet er et JSON-objekt. Formen på feltet payload varierer efter hændelse:

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>

Sådan verificerer 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-indholdet med en tilpasset skabelon. Skabeloner bruger Mustache-lite-syntaks:

  • {{ path.to.value }} — indsættes og escapes for indholdstypen: som en JSON-streng for application/json, procentkodet for application/x-www-form-urlencoded, rå for text/plain
  • {{{ path.to.value }}} — indsættes råt (ingen escaping)

Eksempel på skabelon for application/json (abonneret på ticket.joined):

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

Feltet til payloadskabelonen er en kodeeditor med:

  • Syntaksfremhævning og parentesmatchning til JSON-skabeloner.
  • Variabel-palette — en altid synlig række med indsætningsknapper, én pr. tilgængelig variabelsti for dine valgte hændelser. Klik på en knap for at indsætte et {{ path }}-token ved markøren.
  • Live-validering — mens du skriver, tjekker editoren både JSON-strukturen (når indholdstypen er application/json, og ingen rå {{{ }}}-tags er til stede) og variabelstier. Diagnostik vises som markører i editoren og i en samlet besked under den:
    • Fejl — en sti, der er ukendt i alle dine valgte hændelser.
    • Advarsel — en sti, der kun findes for nogle af dine valgte hændelser (den vil være tom for leveringer af de andre hændelser).

Serveren validerer også ved gemning. Editorens beskeder følger de samme regler.

Cloudflare Queues prøver en mislykket levering igen op til 3 gange med stigende intervaller. Det gælder svar uden for 2xx og forbindelsesfejl. Hvis det første forsøg og alle 3 gentagne forsøg mislykkes, flyttes leveringen til dead-letter-køen, og endpointets tæller for fortløbende fejl øges.

Når et endpoint har akkumuleret 20 fortløbende fejl, deaktiveres det automatisk. Genaktivér det fra endpointets redigeringsside; tælleren nulstilles til nul.

Fanen Leveringer på hvert endpoint viser de seneste 30 dages leveringsforsøg: hændelsestype, HTTP-status, antal forsøg og tidsstempel. Brug knappen Indlæs flere til at bladre gennem ældre poster.

GrænseVærdi
Endpoints pr. organisation5
Tilpassede headers pr. endpoint10
Headerværdiens længde1.024 bytes
Payload-skabelonens størrelse16 KB
Leveringstimeout10 sek.
Opbevaring af leveringshistorik30 dage
Maks. leveringsrate pr. organisation120/60 sek.
  1. Åbn endpointets redigeringsside.
  2. Klik på Rotér signeringshemmelighed.
  3. Bekræft rotationen i dialogen.
  4. Kopiér den nye hemmelighed med det samme — den vises kun én gang og kan ikke gendannes. Afviser du dialogen uden at gemme den, skal du rotere igen for at få en ny klartekst.
  5. Opdatér din server til at verificere signaturer med den nye hemmelighed.

Der er ingen overgangsperiode. Den gamle hemmelighed stopper med at verificere, så snart du bekræfter rotationen. Planlæg at udrulle den nye hemmelighed til din modtager umiddelbart efter rotationen.

Brugerfladen viser Aktiv hemmelighed: ····XXXX (de sidste fire tegn) ved siden af Rotér-knappen, så du kan bekræfte, hvilken hemmelighed der er gældende. Brug dem til at kontrollere, at modtageren og serveren bruger samme hemmelighed efter en rotation.

Hvornår du skal rotere:

  • Mistanke om kompromittering: hemmeligheden dukkede op i en logfil, blev delt med en fratrædende medarbejder eller blev fanget i en skærmoptagelse.
  • Regelmæssig rotation begrænser følgerne af en uopdaget eksponering.
  • Efter enhver ændring af, hvilke tjenester der kan læse hemmeligheden (rotation af nøglestyring).

Sådan opdaterer du modtageren:

  1. Rotér i admin-brugerfladen, og kopiér den nye hemmelighed.
  2. Opdatér hemmeligheden i din modtagers hemmelighedslager (miljøvariabel, hemmelighedshåndtering osv.).
  3. Udrul den opdaterede modtager.
  4. Bekræft, at den næste levering lykkes under fanen Leveringer.

Har du mistet den nye hemmelighed, før du gemte den:

Rotér igen. Hver rotation genererer en ny tilfældig hemmelighed. Den tidligere klartekst kan ikke gendannes — kun en AEAD-krypteret form gemmes på serveren.