Webhook'lar

Bir şey olduğunda — sipariş verildiğinde, potansiyel müşteri geldiğinde, ödeme düştüğünde — Era'nın senin sunucunu çağırmasını sağla ve bu uç noktaları koddan yönet.

Era'daki her işlem olaylar yayımlar (retail.order_placed, crm.lead_captured, finance.payment_recorded …). Webhook, seçtiğin olayları imzalı olarak ve yeniden deneyerek senin bir adresine gönderir. Bu rehber olay seçmeyi ve uç noktaları API üzerinden yönetmeyi anlatır; isteğin kendisi — gövde, başlıklar, imza denetimi, yeniden denemeler — Giden webhook sayfasında, başka sistemlerden gelen çağrıları almak da Gelen webhook sayfasındadır.

Hangi olaylar var

Başvurudaki her modül sayfası bir Olaylar tablosuyla biter: olayın adı, ne olduğu ve taşıdığı alanlar. Örneğin:

Bir işlemin bölümü kendisinin yayımladığı olayları da listeler; her API çağrısı da bunları events içinde döndürür. Böylece bir webhook'un tam olarak ne alacağını görürsün.

Olaylar alanına adları virgülle ayırarak yazarsın. retail.* bir modülün bütün olayları demektir; boş liste ise bütün olaylar.

Koddan uç nokta oluştur

Webhook yönetmek platform:manage izni ister — anahtarı, işletmenin platform ayarlarını yönetebilen birinin hesabından oluştur ya da öyle biriyle giriş yap. Webhook'ların kendi kaynağı yoktur (bir uç noktanın adresi, alıcının kimlik bilgisidir); platform işlemleriyle yönetilirler:

curl -X POST https://app.getera.io/api/v1/actions/platform.create_webhook \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"direction": "outbound", "name": "Siparişler depoya", "target_url": "https://wms.example.com/era", "events": "retail.order_placed,retail.order_canceled"}'
const res = await era.actions.run("platform.create_webhook", {
  direction: "outbound",
  name: "Siparişler depoya",
  target_url: "https://wms.example.com/era",
  events: "retail.order_placed,retail.order_canceled",
})
const { id, signing_secret } = res.result as { id: string; signing_secret: string }
era run platform.create_webhook --direction outbound --name "Siparişler depoya" \
  --target-url https://wms.example.com/era --events "retail.order_placed,retail.order_canceled"
Yanıt
{ "ok": true, "result": { "id": "…", "signing_secret": "whsec_…" }, "events": ["platform.webhook_created"] }

Gizli anahtar bir kez gösterilir

signing_secret yalnız bu yanıtta döner. Hemen alıcı tarafta sakla; Era onu şifreli tutar ve bir daha göstermez. Kaybettiysen yenile (aşağıda).

Uç nokta hemen etkin olur. Adres herkese açık bir https adresi olmalıdır; değilse insecure_url, invalid_url ya da name_taken ile reddedilir. İsteğe bağlı: timeout_ms (varsayılan 15000) ve max_attempts (varsayılan 5).

Yönet

Ne içinÇağrıGirdi
Adresi, olayları ya da sınırları değiştirplatform.update_webhookwebhook_id, sonra name, target_url, events, timeout_ms, max_attempts'tan istediklerin
Deneme olayı gönder ya da bir gönderimi yineleplatform.send_test_deliverywebhook_id, isteğe bağlı replay_of (bir gönderim kimliği)
İmza anahtarını değiştirplatform.rotate_webhook_secretwebhook_id — eski anahtar 24 saat daha imzalar
Duraklat ya da sürdürplatform.set_webhook_activewebhook_id, active
Kaldırplatform.delete_webhookwebhook_id (platform:delete ister)

Hepsi ekranda da vardır: Ayarlar → Gelişmiş → Webhook'lar (/settings/webhooks), her uç noktanın gönderim geçmişiyle birlikte.

Doğru karşıla

  1. Gövdeye güvenmeden önce imzayı doğrula — x-era-signature, <zaman>.<ham gövde> üzerinde bir HMAC-SHA256'dır; kod Giden webhook sayfasında.
  2. Hızlıca 2xx yanıt ver, işi sonra yap. Başka her yanıt ya da zaman aşımı başarısız deneme sayılır ve giderek uzayan aralıklarla yeniden denenir.
  3. idempotency-key başlığına (<uç nokta kimliği>:<olay kimliği>) göre tekrarları ayıkla — yeniden denemelerde değişmez.
  4. Gövdedekinden fazlası gerekiyorsa güncel hâli oku: data kimlikleri taşır; kaydı GET /api/v1/<kaynak>/<id> ile oku.
  5. Başarısızlıkları izle. Art arda çok sayıda başarısızlıktan sonra uç nokta kendini kapatır ve Era platform.webhook_disabled yayımlar; tek bir başarı sayacı sıfırlar.
En küçük alıcı (Node)
import { createServer } from "node:http"
import { verifyEraSignature } from "./verify" // Giden webhook sayfasındaki kod

createServer(async (req, res) => {
  const chunks: Buffer[] = []
  for await (const c of req) chunks.push(c as Buffer)
  const raw = Buffer.concat(chunks).toString("utf8")
  if (!verifyEraSignature(raw, String(req.headers["x-era-signature"] ?? ""), process.env.ERA_WEBHOOK_SECRET!)) {
    res.writeHead(401).end()
    return
  }
  res.writeHead(204).end() // önce yanıt ver
  const event = JSON.parse(raw) as { event: string; data: Record<string, unknown> }
  if (event.event === "retail.order_placed") queueForPicking(event.data.id as string)
}).listen(8080)

Sunucu yerine iş akışı

Bir olayda yapmak istediğin şey Era'nın içindeyse — mesaj göndermek, görev açmak, bir kaydı güncellemek — o olayı tetikleyici yapan bir iş akışı kullan: çalıştıracağın bir sunucu gerekmez. Bkz. İş akışları.