Gelen webhook'lar
Webhook tetikleyicisi olan bir otomasyonun kendi URL'si vardır. Başka bir sistem bu URL'ye istek gönderdiğinde otomasyon, isteğin gövdesini girdi olarak alıp hemen çalışır. "Yeni sipariş geldi", "ödeme başarısız oldu" ya da "biri iletişim formunu doldurdu" gibi durumlar için kullanın. Bu sayfa gönderen tarafı kuran kişi içindir; otomasyonun kendisini kurmak için bkz. Tetikleyiciler.
Webhook URL'si
https://peki.ai/hooks/whk_9fK2mQ7xR4tV1bN8cZ5wL3pH6yJ0dS2a
- Her otomasyonun kendi URL'si vardır. Kaydettikten sonra otomasyonda Webhook URL'si altında görünür. Yalnızca düzenleyiciler görür.
- URL kimlik bilgisinin kendisidir: ona sahip olan herkes onu çağırabilir. "Bir parola gibi sakla."
- URL'yi yenile yeni bir URL verir; eskisi hemen çalışmayı bırakır. URL'yi iptal et URL'yi kapatır; yenisini oluşturana kadar istekler reddedilir.
- API anahtarı ya da başka bir başlık gerekmez.
Aynı URL API temel adresi altında da çalışır (https://peki.ai/api/hooks/whk_…).
İstek gönderme
POST /hooks/{hookId}
Yalnızca POST kabul edilir. Gövde otomasyonun girdisi olur:
Content-Type | Otomasyonun aldığı |
|---|---|
application/json ya da herhangi bir …+json | Ayrıştırılmış JSON. Geçerli JSON değilse ya da 64 seviyeden derin iç içe geçmişse, ham metin. |
application/x-www-form-urlencoded | Alanlardan oluşan bir nesne. Birden fazla kez gönderilen alan listeye dönüşür. |
| Diğer her şey | Metin olarak gövde. |
| Boş gövde | Hiçbir şey (null). |
Şu istek başlıkları otomasyona iletilir (her biri 200 karaktere kısaltılır): content-type, user-agent, x-shopify-topic, x-shopify-shop-domain, x-shopify-webhook-id, x-github-event, x-github-delivery, x-github-hook-id, idempotency-key, x-request-id. Diğer başlıklar iletilmez.
curl -X POST https://peki.ai/hooks/whk_9fK2mQ7xR4tV1bN8cZ5wL3pH6yJ0dS2a \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-10482-created" \
-d '{"event": "order.created", "order": {"id": 10482, "total": 1249.90, "currency": "TRY", "email": "[email protected]"}}'
await fetch('https://peki.ai/hooks/whk_9fK2mQ7xR4tV1bN8cZ5wL3pH6yJ0dS2a', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Idempotency-Key': `order-${order.id}-created` },
body: JSON.stringify({ event: 'order.created', order }),
});
Yanıtlar
| Durum | Gövde | Anlamı | Gönderen yeniden denemeli mi? |
|---|---|---|---|
202 | { "accepted": true, "id": "…" } | Kabul edildi. Çalıştırma hemen başlar. | Hayır |
200 | { "duplicate": true } | Son 24 saatte zaten alındı; yeniden çalışmaz. | Hayır |
401 | { "error": "Invalid signature" } | İmza kontrolü açık ve imza eksik ya da yanlış. | Hayır, imzayı düzeltin |
404 | { "error": "Not found" } | Bilinmeyen, yenilenmiş ya da iptal edilmiş URL ya da otomasyon duraklatılmış veya kapalı. | Hayır |
413 | { "error": "Payload too large" } | Gövde 256 KB'tan büyük. | Hayır, daha az gönderin |
429 | { "error": "Too many requests" } | Hız sınırı ya da bu otomasyon için bekleyen çok fazla çalıştırma var. | Evet, daha sonra |
503 | { "error": "Try again shortly" } | Kuyruğa alınamadı. Hiçbir şey çalışmadı. | Evet |
202, otomasyon çalışmadan önce, istek kabul edilir edilmez döner. Gönderen asla agent'ı beklemez.
Duraklatılmış bir otomasyon da bilinmeyen bir URL gibi 404 döner; böylece URL hiçbir şeyi ele vermez. Reddedilen istek yine de otomasyonun İstekler listesinde nedeniyle birlikte görünür.
İmzalar
İmza kontrolü olmadan URL'ye sahip olan herkes otomasyonu başlatabilir: "URL'yi bilen herkes bu otomasyonu başlatabilir. İmzaları kontrol etmek için bir sağlayıcı seç." Gönderen servis isteklerini imzalıyorsa kontrolü mutlaka açın.
Otomasyonda İmza altında sağlayıcıyı ve İmzalama anahtarını seçin: gönderen servisin size verdiği, bu agent için Ayarlar → Gizli anahtarlar bölümünde kaydettiğiniz anahtar. "İmzalama anahtarı yalnızca gelen isteklerin imzalarını kontrol eder; Peki onu hiçbir yere göndermez."
| Sağlayıcı | Kontrol edilen başlık | Nasıl imzalanır |
|---|---|---|
| Stripe | Stripe-Signature | t= zaman damgası ve {t}.{ham gövde} üzerinden v1= HMAC-SHA256. Zaman damgası 5 dakika içinde olmalı. |
| Shopify | X-Shopify-Hmac-Sha256 | Ham gövdenin Base64 HMAC-SHA256 değeri. |
| GitHub | X-Hub-Signature-256 | sha256= ve ham gövdenin hex HMAC-SHA256 değeri. |
| HMAC-SHA256 | Adını verdiğiniz İmza başlığı, ör. x-signature | Anahtarınızla ham gövdenin HMAC-SHA256 değeri; hex ya da base64, isteğe bağlı olarak başında sha256=. |
İmza, alınan baytların birebir kendisi üzerinden kontrol edilir. İmzalama ile gönderme arasında JSON'u yeniden biçimlendirmeyin.
Kendi sisteminizden gelen istekleri imzalama
HMAC-SHA256 ile istediğiniz bir başlık adını kullanın:
import crypto from 'node:crypto';
const body = JSON.stringify({ event: 'form.submitted', name: 'Ayşe Yılmaz', phone: '+90 532 123 45 67' });
const signature = crypto.createHmac('sha256', process.env.PEKI_SIGNING_SECRET).update(body).digest('hex');
await fetch(process.env.PEKI_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-signature': `sha256=${signature}` },
body,
});
BODY='{"event":"form.submitted","name":"Ayşe Yılmaz"}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$PEKI_SIGNING_SECRET" -hex | sed 's/^.* //')
curl -X POST "$PEKI_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "x-signature: sha256=$SIG" \
-d "$BODY"
Yazma yapan imzasız istekler
Bir otomasyon bir yere yazıyorsa (eylemi, veri değiştiren araçlar, Bilgi) ve imza kontrolü yoksa, ancak İmzasız istekleri kabul et seçeneğini açtıktan sonra çalışır: "URL'yi bilen herkes bu otomasyona yazma yaptırabilir". Bunu yalnızca gönderen servis isteklerini imzalayamıyorsa açın.
Tekrarlar
Servisler hızlı cevap alamadıklarında webhook'ları yeniden gönderir. Peki her olayı bir kez çalıştırır ve 24 saat içindeki bir tekrara 200 {"duplicate": true} ile cevap verir. Bir istek şunlardan biri aynıysa aynı olay sayılır:
- Stripe olay
iddeğeri (Stripe için), - ya da
X-Shopify-Webhook-Id,X-GitHub-DeliveryveyaIdempotency-Keybaşlığı, - ya da birebir aynı gövde.
Shopify, GitHub ve HMAC-SHA256 için aynı imzalı gövde, yeni bir teslimat kimliğiyle gelse de tekrar sayılır; böylece ele geçirilmiş bir istek yeniden oynatılamaz.
Kendi sisteminizden, olay için sabit bir kimlik taşıyan bir Idempotency-Key başlığı gönderin, ör. order-10482-created. Böylece gövde biraz değişse bile bir yeniden deneme asla iki kez çalışmaz.
Sınırlar
| Sınır | Değer |
|---|---|
| Gövde boyutu | 256 KB |
| Webhook URL'si başına dakikadaki istek | 60 |
| Tek bir ağdan, tüm webhook URL'lerine dakikadaki istek | 600 |
| Tekrar penceresi | 24 saat |
| İstekler listesinde gösterilenler | son 20, 30 gün saklanır |
Sınır aşıldığında istek 429 alır ve çalışmaz. İstek kabul edildikten sonra otomasyonun kendi günlük çalıştırma ve harcama sınırları da geçerlidir.
İstekler listesi
Webhook'u olan her otomasyon son İstekler'ini gösterir: zaman, durum, Boyut ve kişisel verileri maskelenmiş kısa bir gövde önizlemesi. Gövdenin tamamı saklanmaz. Bir istekten Taslak çalıştırma olarak yeniden çalıştır ile hiçbir şey yazmadan değişikliklerinizi deneyebilirsiniz. "Son 20 · saklanan önizlemeyle çalışır: kişisel veriler maskelenir."
Reddedilen istekler (duraklatılmış, çok büyük, hız sınırına takılmış, hatalı imza) da webhook başına dakikada en fazla 20 tane olmak üzere kaydedilir. İmza hataları ayrıca çalışma alanının denetim kaydına (audit log) yazılır.
Örnek: Shopify'da sipariş oluşturuldu
- Peki panelinde Webhook tetikleyicili bir otomasyon oluşturun. İmza altında Shopify'ı seçin ve Shopify'ın webhook imzalama anahtarını İmzalama anahtarı olarak kaydedin.
- Kaydedin ve Webhook URL'sini kopyalayın.
- Shopify'da Settings → Notifications → Webhooks bölümüne gidin, Order creation için JSON biçiminde bir webhook oluşturun ve URL'yi yapıştırın.
- Shopify'dan bir test bildirimi gönderin ve otomasyondaki İstekler listesini kontrol edin.