Skip to content

Webhooks

Webhooks huruhusu mifumo yako kupokea arifa za HTTP POST za wakati halisi wakati matukio ya foleni yanapotokea — tiketi inapojiunga, kuitwa, kukamilika, na kadhalika.

  1. Fungua admin.jonot.io/settings/integrations.
  2. Bofya Ongeza sehemu ya mwisho.
  3. Ingiza URL ya umma ya HTTPS ambayo seva yako inasikiliza.
  4. Chagua matukio unayotaka kujiandikisha kupokea.
  5. Bofya Hifadhi sehemu ya mwisho.

Hifadhi siri yako ya uthibitishaji — inaonyeshwa mara moja tu. Ili kuhakikisha sehemu yako ya mwisho inafikika, tumia kitufe cha Tuma ombi la majaribio katika ukurasa wa kuhariri sehemu ya mwisho.

Jina la tukioLinapofyatuka
ticket.joinedMteja anajiunga na foleni
ticket.calledMfanyakazi anaita tiketi kwenye dawati la huduma
ticket.completedTiketi inawekwa alama ya kukamilika
ticket.cancelledMteja au mfanyakazi anaghairi tiketi
ticket.skippedTiketi inarukwa (uahirishaji unaoweza kukumbukwa tena)
ticket.no_showTiketi iliyoitwa au kurukwa inathibitishwa kutokuwepo
queue.status_changedHali ya foleni inabadilika (ACTIVE, PAUSED, au CLOSED)

Kila uwasilishaji ni HTTP POST yenye:

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

Mwili wa kawaida ni bahasha ya JSON. Muundo wa sehemu ya payload unatofautiana kulingana na tukio:

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 inasaini kila uwasilishaji kwa HMAC-SHA256 juu ya mfuatano huu:

<deliveryId>.<timestamp>.<body>

Kuhakiki katika 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);
}

Unaweza kubadilisha mwili wa kawaida wa JSON na kiolezo maalum. Violezo hutumia sintaksia ya Mustache-lite:

  • {{ path.to.value }} — inabadilishwa na kuchakatwa (escaped) kulingana na aina ya maudhui: imechakatwa kama mfuatano wa JSON kwa application/json, imesimbwa kwa asilimia kwa application/x-www-form-urlencoded, ghafi kwa text/plain
  • {{{ path.to.value }}} — inabadilishwa ghafi (bila kuchakatwa)

Mfano wa kiolezo kwa application/json (kilichojiandikisha kwa ticket.joined):

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

Sehemu ya kiolezo cha mzigo ni kihariri kamili cha msimbo chenye:

  • Uangaziaji wa sintaksia na ulinganishaji wa mabano kwa violezo vya JSON.
  • Orodha ya vigezo — safu inayoonekana daima ya vitufe vya kuweka, kimoja kwa kila njia ya kigezo kinachopatikana kwa matukio uliyochagua. Bofya kitufe ili kuweka alama ya {{ path }} mahali pa kishale.
  • Uthibitishaji wa moja kwa moja — unapoandika, kihariri kinaangalia muundo wa JSON (wakati aina ya maudhui ni application/json na hakuna lebo ghafi za {{{ }}}) na njia za vigezo. Utambuzi unaonekana kama alama za ndani ya kihariri na kama bango la muhtasari chini yake:
    • Hitilafu — njia isiyojulikana katika matukio yote uliyochagua.
    • Onyo — njia inayopatikana kwa baadhi tu ya matukio uliyochagua (itakuwa tupu kwa uwasilishaji wa matukio mengine).

Uthibitishaji pia unafanyika wakati wa kuhifadhi kwenye seva — maoni ya kihariri yanaakisi kanuni za seva kwa usahihi kabisa.

Uwasilishaji ulioshindwa (hali isiyo ya 2xx au hitilafu ya muunganisho) unajaribiwa tena hadi mara 3 kwa kurudisha nyuma kwa kasi inayoongezeka (exponential back-off) na Cloudflare Queues. Baada ya kushindwa mara 3, uwasilishaji unaingia kwenye foleni ya barua-zilizokufa na kihesabu cha kushindwa mfululizo cha sehemu ya mwisho kinaongezeka.

Mara sehemu ya mwisho inapofikia kushindwa mara 20 mfululizo, inazimwa kiotomatiki. Iwashe tena kutoka ukurasa wa kuhariri sehemu ya mwisho; kihesabu kinarudi sifuri.

Kichupo cha Uwasilishaji katika kila sehemu ya mwisho kinaonyesha majaribio ya uwasilishaji ya siku 30 zilizopita: aina ya tukio, hali ya HTTP, idadi ya majaribio, na muhuri wa muda. Tumia kitufe cha Pakia zaidi kupitia rekodi za zamani zaidi.

KikomoThamani
Sehemu za mwisho kwa kila shirika5
Vichwa maalum kwa sehemu ya mwisho10
Urefu wa thamani ya kichwabaiti 1 024
Ukubwa wa kiolezo cha mzigo16 KB
Muda wa kusubiri uwasilishajisekunde 10
Uhifadhi wa historia ya uwasilishajisiku 30
Kiwango cha juu cha uwasilishaji kwa shirika120 / sekunde 60
  1. Fungua ukurasa wa kuhariri sehemu ya mwisho.
  2. Bofya Zungushia siri ya uthibitishaji.
  3. Thibitisha uzunguzishaji katika kisanduku cha mazungumzo.
  4. Nakili siri mpya mara moja — inaonyeshwa mara moja tu na haiwezi kurejeshwa. Ukifunga kisanduku cha mazungumzo bila kuihifadhi, lazima uzunguzishe tena ili kupata maandishi mapya wazi.
  5. Sasisha seva yako ili kuhakiki saini kwa siri mpya.

Hakuna kipindi cha mwingiliano. Siri ya zamani inaacha kuhakiki mara tu unapothibitisha uzunguzishaji. Panga kupeleka siri mpya kwa mpokezi wako mara moja baada ya kuzungusha.

Kiolesura kinaonyesha Active secret: ····XXXX (herufi/nambari nne za mwisho) karibu na kitufe cha Kuzungusha ili uweze kuhakiki ni siri gani inayotumika sasa — muhimu kwa kuthibitisha kwamba mpokezi wako na seva viko sawa baada ya uzunguzishaji.

Wakati wa kuzungusha:

  • Tuhuma ya uvunjifu: siri ilionekana katika faili la kumbukumbu, ilishirikiwa na mfanyakazi anayeondoka, au ilinaswa katika kinasa-skrini.
  • Usafi wa kawaida: kuzungusha mara kwa mara kunapunguza wigo wa madhara ya uvujaji usiogunduliwa.
  • Baada ya mabadiliko yoyote kuhusu ni huduma zipi zinazoweza kusoma siri hiyo (uzunguzishaji wa usimamizi wa funguo).

Jinsi ya kusasisha mpokezi:

  1. Zungusha katika kiolesura cha usimamizi na unakili siri mpya.
  2. Sasisha siri hiyo katika hifadhi ya siri ya mpokezi wako (kigezo cha mazingira, msimamizi wa siri, n.k.).
  3. Peleka mpokezi uliosasishwa.
  4. Thibitisha kuwa uwasilishaji unaofuata umefaulu katika kichupo cha Uwasilishaji.

Ukipoteza siri mpya kabla ya kuihifadhi:

Zungusha tena. Kila uzunguzishaji unazalisha siri mpya ya nasibu. Maandishi wazi ya awali hayawezi kurejeshwa — ni umbo lililosimbwa kwa AEAD tu linalohifadhiwa upande wa seva.