Ana içeriğe geç
Version: Peki

Tetikleyiciler, webhook'lar ve olaylar

Tetikleyici, bir otomasyonu başlatan şeydir. Otomasyon bir zamanlamanın yanında bir şey olduğu anda da başlayabilir: başka bir sistem otomasyonun webhook URL'sini çağırır ya da Peki'nin içinde bir şey olur (Peki olayı), örneğin yeni bir potansiyel müşteri kaydedilir. "Shopify'da sipariş oluşunca müşteriyi kaydet ve bana yaz" ya da "bir potansiyel müşterinin durumu Kazanıldı olunca CRM'e gönder" gibi işler için tetikleyicileri kullanın.

Tetikleyiciyi otomasyonun Kurulum sekmesinde Ne zaman altında seçersiniz: Zamanlama, Webhook ya da Peki olayı. Tetikleyiciden sonraki her şey (kontrol, ne zaman devam etsin, eylem, görev, bildir, limitler) Automations sayfasında anlatıldığı gibi çalışır.

Webhook'lar​

Bir webhook otomasyonunun kendi URL'si vardır. Başka bir sistem (Shopify, Stripe, GitHub, bir form aracı, kendi sunucunuz) bu adrese bir HTTP POST gönderir ve çalışma hemen başlar.

Webhook otomasyonu kurun​

  1. Bir otomasyon oluşturun ve Ne zaman → Webhook'u seçin.
  2. Gönderen sistem isteklerini imzalıyorsa İmza sağlayıcısını ve İmzalama anahtarı'nı seçin (İmzalar bölümüne bakın).
  3. Geri kalanını kurun: genellikle yükü okuyan bir Eylem Fonksiyonu, isterseniz bir Görev ve Bildir.
  4. Kaydedin. "Webhook URL'si kaydettikten sonra görünür."
  5. Webhook URL'si'ni kopyalayın ve gönderen servise yapıştırın. "Bir parola gibi sakla."
  6. Örnek bir yükle Bir kez çalıştır'la test edin (Copilot bunu sizin için yapabilir) ya da gerçek bir istek gönderin ve Taslak çalıştırma olarak yeniden çalıştır'ı kullanın.
  7. Otomasyonu açın.

URL​

URL şöyle görünür:

POST https://peki.ai/hooks/whk_1a2B3c4D5e6F7g8H9i0J1k2L3m4N5o6P
  • whk_ ve ardından Peki'nin ürettiği 32 rastgele karakter. Siz seçemezsiniz. Tam URL'yi panelden kopyalayın.
  • URL'nin kendisi kimlik bilgisidir: elinde olan herkes onu çağırabilir. Yalnızca editör ve üstü roller görür. İzleyiciler "Webhook URL'sini yalnızca düzenleyiciler görür. Bir düzenleyiciden iste." görür.
  • Oturum, çerez ya da API anahtarı gerekmez. Eklemeyin.
  • Yalnızca POST kabul edilir.

URL'yi yenile size yeni bir URL verir; eskisi hemen çalışmayı bırakır. URL'yi iptal et URL'yi kapatır: Yeni URL oluştur'a tıklayana kadar istekler 404 alır. Otomasyonu düzenlemek iptal edilmiş bir URL'yi geri getirmez. İki işlem de denetim kaydına yazılır.

İstek​

BölümKural
YöntemPOST
Gövde boyutuEn fazla 256 KB. Daha büyükleri 413 alır.
application/json (ayrıca …+json)JSON olarak çözülür. 64 seviyeden derin ya da geçersiz JSON metin olarak tutulur.
application/x-www-form-urlencodedBir nesneye çevrilir. Tekrarlanan alan listeye dönüşür.
Diğer her şeyMetin olarak tutulur.
Boş gövdeYük null olur.

Kontrol ve eylem Fonksiyonlarınız isteği ctx.trigger olarak okur:

{
"kind": "webhook",
"payload": { "id": "evt_1Q2w", "type": "payment_intent.succeeded", "data": { "object": { "amount": 149900, "currency": "try" } } },
"headers": { "content-type": "application/json", "user-agent": "Stripe/1.0" },
"id": "6720f0c1a2b3c4d5e6f70812"
}

headers yalnızca şu istek başlıklarını, her biri 200 karakterle kesilmiş olarak içerir. İmzalar ve kimlik bilgileri asla aktarılmaz.

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

Görev ham yükü hiç görmez. Kişisel veriler ve anahtara benzeyen değerler maskelenmiş, kısa bir özet alır (en fazla 2 KB); bu özet güvenilmeyen veri olarak işaretlenmiş bir blok içindedir ve modele içindeki talimatları asla uygulamaması söylenir.

Yanıt​

Peki hemen yanıt verir. Çalışma arka planda olur.

DurumGövdeNe zaman
202{"accepted": true, "id": "<teslimat id>"}Kabul edildi; çalışma sıraya alındı.
200{"duplicate": true}Aynı teslimat son 24 saatte geldi. Tekrar çalışmaz.
401{"error": "Invalid signature"}İmza kontrolü başarısız oldu ya da imzalama anahtarı yok.
404{"error": "Not found"}Bilinmeyen ya da iptal edilmiş URL, otomasyon duraklatılmış ya da kapalı, ya da tetikleyicisi artık webhook değil.
413{"error": "Payload too large"}Gövde 256 KB'tan büyük.
429{"error": "Too many requests"}Hız limiti aşıldı ya da bu otomasyonun çok fazla çalışması zaten bekliyor.
503{"error": "Try again shortly"}İstek sıraya alınamadı. Sonra tekrar deneyin.

Gönderen servislerin çoğu 5xx ve 429'da yeniden dener. Kabul edilmiş bir teslimatın yeniden denemesi 200 ve duplicate: true alır.

Limitler​

LimitDeğer
Gövde boyutu256 KB
URL başına istekDakikada 60
Bir ağdan tüm URL'lere istekDakikada 600
Bir otomasyonun aynı anda çalışması4 (fazlası sırada bekler, asla düşürülmez)
Bir otomasyonun sırada bekleyen çalışması100 (fazlası 429 alır)
Tekrar penceresi24 saat

Otomasyonun kendi Günlük çalışma ve Günlük model maliyeti limitleri de geçerlidir.

Tekrarlar​

Bir teslimatın anahtarı son 24 saatte görüldüyse teslimat tekrar sayılır. Anahtar şu sırayla belirlenir:

  1. Stripe (Stripe imzası açıkken): gövdedeki olay id'si.
  2. X-Shopify-Webhook-Id, X-GitHub-Delivery ya da Idempotency-Key başlığı.
  3. Yoksa gövdenin özeti (hash).

Shopify, GitHub ya da HMAC-SHA256 imzalarında gövde özeti de sayılır; yani aynı imzalı gövde yeni bir teslimat id'siyle tekrar gönderilse bile tekrar sayılır. Tekrarlar ancak imza geçtikten sonra kontrol edilir.

Kendi sistemlerinizden bunu kontrol etmek için bir Idempotency-Key başlığı gönderin.

İmzalar​

İsteklerin gerçek olduğunu doğrulamak için İmza altında bir sağlayıcı seçin. "Geçerli imzası olmayan istekler reddedilir ve çalışmaz. İmzalama anahtarı hiçbir yere gönderilmez."

SağlayıcıBaşlıkİmzalanan
StripeStripe-Signature: t=<zaman>,v1=<hex><zaman>.<ham gövde> için HMAC-SHA256. Zaman damgası 5 dakika içinde olmalı.
ShopifyX-Shopify-Hmac-Sha256: <base64>Ham gövdenin HMAC-SHA256'sı, base64.
GitHubX-Hub-Signature-256: sha256=<hex>Ham gövdenin HMAC-SHA256'sı, hex.
HMAC-SHA256Sizin belirlediğiniz bir başlık, örneğin x-signatureHam gövdenin HMAC-SHA256'sı, hex ya da base64 (sha256= öneki olabilir).

İmzalama anahtarı agent'ın bir anahtarıdır; anahtar seçiciyle seçilir (en az 8 karakter). Gönderen sistemden kopyalayın, örneğin Shopify'ın webhook imzalama anahtarını. Model onu hiç görmez. HMAC-SHA256 için İmza başlığı'nı da doldurun.

İmzalar alınan baytların birebir aynısı üzerinden hesaplanır. İstekleri kendiniz oluşturuyorsanız gönderdiğiniz baytların aynısını imzalayın.

İmzasız webhook'lar

İmza → Yok ile "URL'yi bilen herkes bu otomasyonu başlatabilir." İmzasız istekleri kabul et'i açmadıkça imzasız bir webhook otomasyona yazma yaptıramaz (eylemi, yazan araçları, Knowledge'a ekleme). Yalnızca gönderen servis isteklerini imzalayamıyorsa açın.

Başarısız imza kontrolleri İstekler'de ve denetim kaydında görünür.

İstekler​

URL'nin altında İstekler son 20 isteği gösterir ("Henüz istek yok. İstekler burada 30 gün görünür."). Her satırda zaman, durum, neden ve boyut vardır:

DurumAnlamı
Kabul edildiSıraya alındı; Çalıştırmayı aç çalışmasına götürür.
TekrarSon 24 saatte görüldü; çalışmadı.
Geçersiz imzaİmza kontrolü başarısız oldu.
Çok fazla istekBir hız limiti aşıldı.
Çok büyük256 KB'tan büyük.
Otomasyon kapalıOtomasyon duraklatılmıştı ya da kapalıydı.

Gövdenin önizlemesini görmek için bir satırı açın: en fazla 2 KB, kişisel veriler ve anahtara benzeyen değerler maskelenmiş. Peki tam gövdeyi asla saklamaz. Taslak çalıştırma olarak yeniden çalıştır, otomasyonu bu saklanan önizlemeyle hiçbir şey göndermeden ve yazmadan çalıştırır.

Reddedilen istekler URL başına dakikada en fazla 20 kez kaydedilir; böylece bir istek seli listeyi doldurmaz.

curl ile örnekler​

Önce URL'nizi ve anahtarınızı ayarlayın:

HOOK_URL='https://peki.ai/hooks/whk_REPLACE_WITH_YOUR_URL_ID_000000'
SECRET='imzalama-anahtariniz'

İmzasız JSON (yalnızca yazmayan otomasyonlar için ya da İmzasız istekleri kabul et açıkken):

curl -i -X POST "$HOOK_URL" \
-H 'Content-Type: application/json' \
--data-raw '{"ad":"Elif Yılmaz","telefon":"+905321234567","ilgi":"Diş beyazlatma"}'
HTTP/1.1 202 Accepted
Content-Type: application/json

{"accepted":true,"id":"6720f0c1a2b3c4d5e6f70812"}

Bir form gönderimi nesneye dönüşür ({"ad": "Elif Yılmaz", "hizmet": "Diş taşı temizliği"}):

curl -i -X POST "$HOOK_URL" \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'ad=Elif Yılmaz' --data-urlencode 'hizmet=Diş taşı temizliği'

x-signature başlığı ve bir idempotency anahtarıyla HMAC-SHA256:

BODY='{"olay":"form.gonderildi","ad":"Mehmet Demir","telefon":"+905551112233"}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')
curl -i -X POST "$HOOK_URL" \
-H 'Content-Type: application/json' \
-H "x-signature: $SIG" \
-H 'Idempotency-Key: form-2026-10-26-0001' \
--data-raw "$BODY"

GitHub biçimi:

BODY='{"action":"opened","issue":{"number":42,"title":"Giriş yapılamıyor"}}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')
curl -i -X POST "$HOOK_URL" \
-H 'Content-Type: application/json' \
-H 'X-GitHub-Event: issues' \
-H "X-GitHub-Delivery: $(uuidgen)" \
-H "X-Hub-Signature-256: sha256=$SIG" \
--data-raw "$BODY"

Shopify biçimi (base64 imza):

BODY='{"id":820982911946154500,"email":"[email protected]","total_price":"1499.00","currency":"TRY"}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -binary | base64)
curl -i -X POST "$HOOK_URL" \
-H 'Content-Type: application/json' \
-H 'X-Shopify-Topic: orders/create' \
-H "X-Shopify-Webhook-Id: $(uuidgen)" \
-H "X-Shopify-Hmac-Sha256: $SIG" \
--data-raw "$BODY"

Stripe biçimi (zaman damgalı):

BODY='{"id":"evt_1Q2w3e4r","type":"checkout.session.completed","data":{"object":{"amount_total":149900,"currency":"try"}}}'
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')
curl -i -X POST "$HOOK_URL" \
-H 'Content-Type: application/json' \
-H "Stripe-Signature: t=$TS,v1=$SIG" \
--data-raw "$BODY"

Aynı Stripe isteğini iki kez gönderirseniz ikincisi 200 ve {"duplicate":true} alır, çünkü olay id'si aynıdır.

ipucu
--data-raw ya da --data-binary kullanın

curl -d gövdeyi değiştirebilir (dosyalardaki satır sonlarını siler) ve o zaman imza artık tutmaz. Birebir aynı baytları imzalayın ve gönderin.

Peki olayları​

Bir olay otomasyonu Peki'nin içinde bir şey olduğunda başlar. Ne zaman → Peki olayı'nı seçin ve Olay'ı belirleyin:

OlayEtiketNe zaman başlar
record.createdKayıt oluşturulduAgent'ın tablolarından birinde bir kayıt oluşturulduğunda.
record.updatedKayıt güncellendiBir kaydın değerleri gerçekten değiştiğinde (yalnızca yeni bir konuşma bağlantısı değişiklik sayılmaz).
conversation.handed_offKonuşma devredildiAgent bir müşteri konuşmasını ekibine devrettiğinde.
conversation.resolvedKonuşma çözüldüBiri Inbox'ta bir müşteri konuşmasını çözdüğünde.
approval.decidedOnay karara bağlandıBir ekip arkadaşı bir onay isteğini onayladığında ya da reddettiğinde.

Olaylar testlerden hiç gelmez: test kayıtları, test konuşmaları, taslağın onay istekleri ve Copilot'un ve otomasyonların gizli konuşmaları olay üretmez. Süresi dolan bir onay karar sayılmaz, olay üretmez.

Olaylar değişikliğin kendisiyle birlikte yazılır; hizmet yeniden başlasa bile kaybolmaz. Her olay, eşleşen her otomasyonu bir kez başlatır.

Kayıt olaylarını filtreleyin​

Kayıt oluşturuldu ve Kayıt güncellendi için olayı daraltabilirsiniz:

  • Tablo: Herhangi bir tablo ya da agent'ın bir tablosu.
  • Alan (tablodan sonra): Herhangi bir alan ya da tek bir alan. "Bir alan seçersen yalnızca o alan değiştiğinde çalışır (değer verirsen o değere değiştiğinde)."
  • Değer (alandan sonra): alanın değiştiği değer. Seçim alanları seçeneklerini sunar. Metin büyük-küçük harf gözetmeden; sayılar ve true/false değerine göre karşılaştırılır.

Örnek: Kayıt güncellendi · Potansiyel müşteriler · Durum · Kazanıldı yalnızca bir potansiyel müşterinin durumu Kazanıldı olduğunda çalışır. (Değeri, tablodaki seçeneğin yazıldığı biçimde girin.)

Filtreler kaydın sonraki hâline göre değil, değişikliğin olduğu andaki değerlere göre değerlendirilir.

Olay yükleri​

Her olay için ctx.trigger.payload:

record.created / record.updated
{
"table": "leads",
"tableId": "t_x7k2ab",
"recordId": "6720f0c1a2b3c4d5e6f70812",
"title": "Elif Yılmaz",
"data": { "name": "Elif Yılmaz", "phone": "+905321234567", "status": "Kazanıldı", "budget": { "amount": 25000, "currency": "TRY" } },
"changedFields": ["status"]
}
conversation.handed_off
{ "conversationId": "6720…", "channel": "webchat", "customerId": "671f…", "customerName": "Elif Yılmaz", "reason": "İade istiyor" }
conversation.resolved
{ "conversationId": "6720…", "channel": "telegram", "customerId": "671f…", "customerName": "Elif Yılmaz", "resolvedBy": "Can" }
approval.decided
{
"approvalId": "6721…", "decision": "approved", "status": "approved", "kind": "record", "name": "leads",
"preview": "Save to Leads: name Elif Yılmaz, status Kazanıldı", "conversationId": "6720…", "recordId": "6720…"
}

data, kaydın değerlerini alan anahtarlarıyla tutar. customerId, customerName, conversationId, recordId ve automationId yalnızca varsa görünür. Onaylanan eylem çalışamadıysa status failed olabilir.

Döngü koruması​

Bir otomasyon kendisi de olaylara yol açabilir; örneğin eylemi bir kayıt kaydeder. Peki her olayın arkasındaki otomasyon zincirini tutar:

  • Bir olay, kendisine yol açan çalışmanın otomasyonunu asla başlatmaz.
  • Tek bir olaydan art arda 3 otomasyon çalıştıktan sonra zincir durur.

Bu şekilde durdurulan bir çalışma Atlandı — döngü olarak kaydedilir. Bir otomasyonun zaten 100 bekleyen çalışması varsa yeni bir olay Atlandı — önceki çalışma sürüyor olarak kaydedilir ve düşürülür.

Eylemler​

Eylem, agent'ınızın Fonksiyonlarından birinin kontrol ve koşuldan sonra, yazma izniyle ve modelsiz çalışmasıdır. Bir otomasyonun diğer sistemlerle konuşma yolu budur: bir potansiyel müşteriyi CRM'e göndermek, bir destek kaydı açmak, bir tabloyu güncellemek.

// Eylem Function'ı: kazanılan müşteriyi CRM'e gönder
export default async (input, ctx) => {
const musteri = ctx.trigger.payload.data;
const res = await ctx.fetch('https://api.ornek-crm.com.tr/v1/firsatlar', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ ad: musteri.name, telefon: musteri.phone, tutar: musteri.budget?.amount }),
secret: { name: 'CRM_API_KEY' },
});
return { ok: res.ok, message: `Kazanılan yeni fırsat CRM'e gönderildi: ${musteri.name}` };
};
  • ctx.trigger çalışmayı neyin başlattığını tutar. ctx.records agent'ın tablolarını okur ve kaydeder. ctx.store otomasyonun hafızasıdır.
  • Yazma işlemleri otomasyonu kaydettiğinizde, editör ya da üstü bir rolü olan biri tarafından onaylanır.
  • Fonksiyonda Onay gerekir açıksa eylem, aynı girdiyi ve tetikleyiciyi (64 KB'a kadar) tutan bir onay isteğine dönüşür. Bir ekip arkadaşı onaylayınca çalışır. Onaylar sayfasına bakın.
  • Görev yoksa model de yok. Görev olmadığında eylemin döndürdüğü message Telegram sohbetlerine gönderilir. Böyle bir çalışmanın maliyeti neredeyse sıfırdır.
  • Deneme çalışmasında eylemin yazan istekleri sistem tarafından yanıtlanır ve hiç gönderilmez; kayıt kaydetmeleri yalnızca raporlanır.

Eylem başarısız olursa çalışma Fonksiyonun hatasıyla başarısız olur.

Giden çağrılar için ayrı bir "giden webhook" ayarı gerekmez: bunları eylem (ya da HTTP aracı olan bir görev) yapar.

Bir tetikleyiciyi test edin​

Bir webhook ya da olay otomasyonunun Bir kez çalıştır sekmesinde örnek bir yükle yapılan çalışma gerçek bir tetikleyici gibi davranır: örnek ctx.trigger.payload olur. Copilot, URL'yi nereye yapıştıracağınızı söylemeden önce bunu gerçekçi bir örnekle (bir Shopify siparişi, bir potansiyel müşteri) yapar. Örnek en fazla 256 KB olabilir ve çalışmadan hemen sonra silinir.

İstekler altından Taslak çalıştırma olarak yeniden çalıştır, saklanan maskelenmiş bir önizlemeyi yeniden oynatır. Her zaman deneme çalışmasıdır.

Bir tetikleyicinin başlattığı çalışmalar Çalışmalar sekmesinde neyin başlattığını gösterir: Webhook isteği, Peki olayı: Kayıt oluşturuldu, Örnekle bir kez çalıştır ya da zincirleme olaylar için "1 otomasyondan sonra".

Örnek: Shopify siparişinden potansiyel müşteriye ve mesaja​

  1. Ayarlar → Gizli anahtarlar altında Shopify'ın webhook imzalama anahtarını bir imzalama anahtarı olarak kaydedin.
  2. Bir otomasyon oluşturun: Ne zaman → Webhook, İmza → Shopify, anahtarı seçin.
  3. Eylem: siparişi ctx.trigger.payload'dan okuyan, müşteriyi ctx.records.save('leads', …) ile kaydeden ve { "message": "… adlı müşteriden yeni sipariş: 1.499 ₺" } döndüren bir Fonksiyon.
  4. Bildir: sizin Telegram sohbetiniz. Görev yok.
  5. Kaydedin, URL'yi kopyalayın ve Shopify → Settings → Notifications → Webhooks altına yapıştırın (olay: Order creation, biçim: JSON).
  6. Örnek bir siparişle Bir kez çalıştır'ı kullanın (deneme çalışması), oluşacak potansiyel müşteriyi ve mesajı kontrol edin, sonra otomasyonu açın.

İlgili sayfalar​