İçeriğe geç

Webhooks

Webhooks, bir sıra olayı gerçekleştiğinde sisteminize bir HTTP POST isteği gönderir. Olaylar arasında bir sıra numarasının sıraya katılması, çağrılması veya tamamlanması yer alır.

  1. admin.jonot.io/settings/integrations adresini açın.
  2. Uç nokta ekle’ye tıklayın.
  3. Sunucunuzun dinlediği herkese açık bir HTTPS URL’si girin.
  4. Hangi olaylara abone olacağınızı seçin.
  5. Kaydet’e tıklayın.

İmzalama gizli anahtarınız göründüğünde kopyalayıp saklayın; Jonot bunu yalnızca bir kez gösterir. Jonot’un uç noktanıza ulaşabildiğini denetlemek için uç nokta düzenleme sayfasındaki Test isteği gönder düğmesini kullanın.

Olay adıNe zaman tetiklenir
ticket.joinedBir müşteri sıraya katılır
ticket.calledBir personel bir sıra numarasını gişeye çağırır
ticket.completedBir sıra numarası tamamlandı olarak işaretlenir
ticket.cancelledBir müşteri veya personel bir sıra numarasını iptal eder
ticket.skippedBir sıra numarası atlanır (tekrar çağrılabilir bir erteleme)
ticket.no_showÇağrılmış veya atlanmış bir sıra numarası gelmedi olarak onaylanır
queue.status_changedBir sıranın durumu değişir (ACTIVE, PAUSED veya CLOSED)

Her teslimat, aşağıdakilere sahip bir HTTP POST’tur:

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

Varsayılan gövde bir JSON nesnesidir. payload alanının içeriği olaya göre değişir:

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, her teslimatı aşağıdaki dize üzerinde HMAC-SHA256 ile imzalar:

<deliveryId>.<timestamp>.<body>

Node.js’de (≥18) doğrulamak için:

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

Varsayılan JSON gövdesini özel bir şablonla değiştirebilirsiniz. Şablonlar Mustache-lite sözdizimini kullanır:

  • {{ path.to.value }} — Jonot değeri yerleştirir ve içerik türüne göre kaçış uygular: application/json için JSON dizesi kaçışı, application/x-www-form-urlencoded için yüzde kodlaması, text/plain için kaçış yok.
  • {{{ path.to.value }}} — Jonot değeri kaçış uygulamadan yerleştirir.

application/json için örnek şablon (ticket.joined olayına abone):

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

Yük şablonu alanı, aşağıdaki özelliklere sahip tam bir kod düzenleyicidir:

  • JSON şablonları için sözdizimi vurgulama ve parantez eşleştirme.
  • Değişken listesi — seçtiğiniz olaylar için kullanılabilen değişken yollarına ait bir düğme satırı. İmleç konumuna bir {{ path }} belirteci eklemek için bir düğmeye tıklayın.
  • Canlı doğrulama — siz yazarken düzenleyici değişken yollarını denetler. İçerik türü application/json olduğunda ve şablonda ham {{{ }}} etiketi bulunmadığında JSON yapısını da denetler. Düzenleyici sorunları kodun içinde işaretler ve altlarında listeler:
    • Hata — seçtiğiniz olayların hiçbirinde bulunmayan bir yol.
    • Uyarı — yalnızca seçtiğiniz olayların bir kısmında bulunan bir yol (diğer olayların teslimatlarında boş olacaktır).

Kaydettiğinizde sunucu aynı doğrulama kurallarını çalıştırır.

Cloudflare Queues, başarısız bir teslimatı en fazla 3 kez yeniden dener ve her yeniden denemeden önce daha uzun bekler. Uç nokta 2xx aralığının dışında bir durum döndürdüğünde veya bir bağlantı hatası oluştuğunda teslimat başarısız sayılır. İlk deneme ve 3 yeniden denemenin tümü başarısız olursa teslimat ölü mektup kuyruğuna taşınır ve uç noktanın ardışık başarısızlık sayacı artar.

Jonot, 20 ardışık başarısızlıktan sonra bir uç noktayı otomatik olarak devre dışı bırakır. Uç nokta düzenleme sayfasından yeniden etkinleştirebilirsiniz. Bu, sayacı sıfırlar.

Her uç noktadaki Teslimatlar sekmesi, son 30 günlük teslimat denemelerini gösterir: olay türü, HTTP durumu, deneme sayısı ve zaman damgası. Daha eski kayıtlara göz atmak için Daha fazla yükle düğmesini kullanın.

SınırDeğer
Kuruluş başına uç nokta sayısı5
Uç nokta başına özel başlık sayısı10
Başlık değeri uzunluğu1.024 bayt
Yük şablonu boyutu16 KB
Teslimat zaman aşımı10 sn
Teslimat geçmişi saklama süresi30 gün
Kuruluş başına maksimum teslimat hızı120 / 60 sn
  1. Uç nokta düzenleme sayfasını açın.
  2. İmzalama gizli anahtarını döndür’e tıklayın.
  3. Döndürmeyi iletişim kutusunda onaylayın.
  4. Yeni gizli anahtarı hemen kopyalayın. Jonot bunu bir kez gösterir ve geri getiremez. İletişim kutusunu saklamadan kapatırsanız, yeni bir değer almak için gizli anahtarı tekrar döndürün.
  5. Sunucunuzu yeni gizli anahtarla imzaları doğrulayacak şekilde güncelleyin.

Eski ve yeni gizli anahtar aynı anda çalışmaz. Eski gizli anahtar, döndürmeyi onayladığınız anda istekleri doğrulamayı durdurur. Döndürmenin hemen ardından webhook’larınızı alan sistemi güncelleyin.

Arayüz, Döndür düğmesinin yanında Etkin gizli anahtar: ····XXXX gösterir. Son dört karakter, bir döndürmeden sonra hangi gizli anahtarın etkin olduğunu doğrulamanıza yardımcı olur.

Ne zaman döndürülmeli:

  • Sızıntı şüphesi: gizli anahtar bir günlük dosyasında göründü, ayrılan bir çalışanla paylaşıldı veya bir ekran kaydında yakalandı.
  • Düzenli döndürme: gizli anahtarı periyodik olarak değiştirmek, sızmış bir anahtarın ne kadar süre kullanılabileceğini sınırlar.
  • Erişim değişiklikleri: gizli anahtarı hangi hizmetlerin okuyabileceğini değiştirdikten sonra döndürün.

Alıcıyı nasıl güncellersiniz:

  1. Yönetim arayüzünde döndürün ve yeni gizli anahtarı kopyalayın.
  2. Alıcı sistemin kullandığı gizli anahtarı güncelleyin. Bir ortam değişkeninde, gizli anahtar yöneticisinde veya başka bir güvenli gizli anahtar deposunda saklayın.
  3. Güncellenmiş alıcıyı dağıtın.
  4. Bir sonraki teslimatın Teslimatlar sekmesinde başarılı olduğunu doğrulayın.

Kaydetmeden önce yeni gizli anahtarı kaybettiyseniz:

Tekrar döndürün. Her döndürme yeni bir rastgele gizli anahtar üretir. Sunucu yalnızca şifrelenmiş bir biçim sakladığı için Jonot önceki okunabilir değeri geri getiremez.