İçeriğe atla
OrqLabs

Giden webhook'lar

Olay abonelikleri, 28 platform olayının listesi ve yükleri, zarf biçimi, teslim ve yeniden deneme kuralları, HMAC imza başlıkları ve Node.js doğrulama kodu, idempotency.

15 dk Son güncelleme:
Bu sayfada
  1. Kısaca
  2. Genel bilgi
  3. Uç nokta oluşturma
  4. Zarf (PlatformEventEnvelope)
  5. Olaylar (PLATFORM_EVENTS)
  6. Teslim ve yeniden deneme
  7. İmza başlıkları
  8. Doğrulama (Node.js / Express)
  9. Örnek senaryolar
  10. Sık sorulan sorular
  11. Sonraki adım

Bu rehberde: OrqLabs'taki olayları (aday nitelendi, gönderi yayınlandı, bütçe uyarısı…) kendi sisteminize anında iletirsiniz. 28 olayın listesi, imza doğrulama kodu ve yeniden deneme kuralları burada. Bu rehber yazılımcılar içindir.

⏱ 15 dakika

Kısaca

Giden webhook, OrqLabs'ın sizin sisteminize "bir şey oldu" diye haber vermesidir. Örneğin: bir aday nitelendiğinde CRM'inize kayıt açmak veya bir onay istendiğinde Slack'e düğmeli mesaj göndermek. Uç noktayı Ayarlar → Webhook'lar sayfasında tanımlarsınız; OrqLabs her olayı imzalı bir JSON olarak gönderir.

Webhook akışı: olay oluşur, OrqLabs imzalı isteği sizin adresinize gönderir, başarısız olursa yeniden dener.
Webhook akışı: olay oluşur, OrqLabs imzalı isteği sizin adresinize gönderir, başarısız olursa yeniden dener.
Entegrasyon ayrıntı paneli: ① durum, ② Bağlantıyı test et, ③ webhook adresi ve kopyala, ④ doğrulama token'ı, ⑤ Bağlantıyı kes.
Entegrasyon ayrıntı paneli: ① durum, ② Bağlantıyı test et, ③ webhook adresi ve kopyala, ④ doğrulama token'ı, ⑤ Bağlantıyı kes.

Genel bilgi

Giden webhook'lar OrqLabs'daki olayları (lead nitelendi, gönderi yayınlandı, konuşma devredildi, bütçe uyarısı…) sizin HTTP uç noktanıza anlık iletir. Üç kullanım yolu vardır:

YolNeredeNe gönderir
Olay abonelikleriAyarlar (Settings) → WebhooksSeçtiğiniz PLATFORM_EVENTS olayları, ham zarf
utility.webhookOut node'uİş akışı içindeNode'a gelen item'lar, event adı serbest (workflow.output)
leads.crmSync (WEBHOOK hedefi)İş akışı içindeLead nesnesi, lead.synced

Bu rehber olay aboneliklerine odaklanır; imza ve zarf üçünde de aynıdır.

Uç nokta oluşturma

Ayarlar → Webhooks → Yeni uç nokta:

AlanAçıklama
URLHTTPS zorunlu (üretimde); localhost yalnızca geliştirme modunda
İmza gizli anahtarı (secret)Boş bırakılırsa üretilir; bir kez gösterilir
OlaylarAşağıdaki listeden çoklu seçim; * tümü
Proje filtresiBoşsa organizasyon geneli
AktifDevre dışı uç nokta olayları biriktirmez

Kaydettikten sonra Test gönder düğmesi ping türünde bir zarf yollar; yanıtınız ve süresi ekranda görünür. Teslim geçmişi (son 7 gün) uç nokta ayrıntısında: durum kodu, deneme sayısı, gövde önizlemesi, Yeniden gönder.

Zarf (PlatformEventEnvelope)

{
  "id": "evt_01J8Z…",
  "type": "lead.qualified",
  "organizationId": "org_01J…",
  "projectId": "prj_01J…",
  "at": "2026-09-26T09:14:03.120Z",
  "payload": { … olaya özgü … }
}

id teslim başına değil olay başına benzersizdir; yeniden denemelerde aynı id gelir (idempotency anahtarı). projectId proje bağlamı olmayan olaylarda (integration.*, budget.* organizasyon düzeyinde) bulunmaz.

Olaylar (PLATFORM_EVENTS)

Lead

OlayNe zamanpayload başlıca alanlar
lead.createdYeni lead (form, webhook, ajan, içe aktarma)lead { id, name, email, phone, company, website, status, score, tags, source }
lead.updatedHerhangi bir alan/durum değişimilead, changes { field: { from, to } }, actor
lead.qualifiedDurum QUALIFIED oldulead, score, scoreReason, agentRunId?
lead.repliedLead outreach/kampanyaya yanıt verdilead, conversationId, channel, text

Mesajlaşma

OlayNe zamanpayload
message.receivedGelen mesajconversationId, channel, contactId, contactName, text, mediaUrl?, leadId?
message.sentGiden mesaj (bot/insan/kampanya)conversationId, channel, to, text, sender (bot/human/campaign), messageId
conversation.openedYeni konuşmaconversationId, channel, contactId, leadId?
conversation.handoffİnsana devirconversationId, reason, assignedToId?, by (bot/human)
conversation.closedKapatıldıconversationId, resolvedBy (bot/human), durationSec

İçerik

OlayNe zamanpayload
post.createdTaslak oluşturuldupost { id, platform, body, status, scheduledAt, integrationId }
post.approvedOnaylandıpost, approvedBy, editedBody?
post.publishedYayınlandıpost, externalId, url, publishedAt
post.failedYayın hatasıpost, error { code, message, retryable }

Kampanya

OlayNe zamanpayload
campaign.startedKampanya başladıcampaign { id, name, channel, total }
campaign.finishedBitti/iptalcampaign, stats { sent, delivered, read, replied, failed, skipped }

İş akışı ve ajan

OlayNe zamanpayload
workflow.run.startedRun başladırunId, workflowId, workflowName, triggerType
workflow.run.finishedRun SUCCEEDEDrunId, workflowId, status, costUsd, durationMs, itemCount
workflow.run.failedRun FAILEDrunId, workflowId, error, failedNodeId, failedNodeName
agent.run.finishedAjan çalıştırması bitti (her durum)agentRunId, type, status (succeeded/failed/budget_exceeded/max_steps), summary, usage { inputTokens, outputTokens, costUsd, modelId }, reportId?
agent.report.createdRapor kaydedildireport { id, type, title, summary, metrics }, agentType, agentRunId

Analitik

OlayNe zamanpayload
analytics.syncedGünlük GA4/GSC çekimi bittiintegrationId, source (ga4/gsc), date, metrics { sessions, users, conversions, … }
analytics.thresholdEşik kuralı tetiklendiruleId, metric, value, threshold, compare, direction

Entegrasyon

OlayNe zamanpayload
integration.connectedYeni bağlantıintegrationId, provider, name, projectId?
integration.errorAUTH/UPSTREAM hatası; yeniden yetkilendirme gerekliintegrationId, provider, code, message

Onay ve bütçe

OlayNe zamanpayload
approval.requestedOnay görevi oluştuapprovalId, title, description, runId, nodeId, expiresAt
approval.resolvedOnaylandı/reddedildiapprovalId, decision (approved/rejected), by, comment?, editedPayload?
budget.warningAylık bütçe %80scope (organization/workflow), limitUsd, usedUsd, pct
budget.exceededBütçe aşıldıscope, limitUsd, usedUsd, runId?

Toplam 28 olay. trigger.event node'unda bunların bir alt kümesi seçilebilir; webhook'lar hepsini alır.

Teslim ve yeniden deneme

  • Teslim webhooks-out kuyruğu üzerinden asenkron yapılır; olay ile teslim arası genellikle < 2 sn.
  • İstek: POST, Content-Type: application/json, gövde zarf; zaman aşımı 10 sn.
  • Başarı: herhangi bir 2xx. Gövde okunmaz.
  • Başarısızlık (bağlantı hatası, zaman aşımı, 3xx/4xx/5xx): üstel geri çekilmeyle 5 deneme (yaklaşık 1 dk, 5 dk, 15 dk, 30 dk sonra; toplam ~1 saat). 410 Gone alınırsa uç nokta otomatik devre dışı bırakılır.
  • Ardışık 100 başarısız teslimden sonra uç nokta pasife alınır ve organizasyon sahibine bildirim gider.
  • Sıra garantisi yoktur; at alanına göre sıralayın.
  • Yük boyutu 256 KB ile sınırlıdır; büyük nesneler (lead, post) kısaltılabilir, …Id alanlarıyla API'den tam kaydı çekin.

İmza başlıkları

Başlıkİçerik
X-AgentFlow-EventZarfın type alanı (lead.qualified)
X-AgentFlow-TimestampGönderim zamanı, Unix saniye
X-AgentFlow-Signaturesha256=<hex> – "<timestamp>.<ham gövde>" dizesi üzerinden uç noktanın secret'ı ile HMAC-SHA256
X-AgentFlow-DeliveryTeslim denemesi kimliği (yeniden denemelerde değişir; id değişmez)
User-AgentAgentFlow-Webhooks/1.0

Bu başlık adları OrqLabs'un belgelenen sözleşmesidir; ilk teslimde uç noktanızın loglarından doğrulayın. İmza, X-AgentFlow-Timestamp değeri, bir nokta ve ham gövdenin birleştirilmesiyle ("<timestamp>.<gövde>") hesaplanır; zaman damgası imzaya dahil olduğu için tekrar saldırılarına karşı 5 dakikalık tolerans uygulayın ve id ile idempotency sağlayın.

Doğrulama (Node.js / Express)

import express from "express";
import crypto from "node:crypto";

const app = express();
const SECRET = process.env.ORQLABS_WEBHOOK_SECRET;
const seen = new Set(); // üretimde Redis/DB kullanın

app.post("/orqlabs/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const sig = req.get("X-AgentFlow-Signature") ?? "";
  const ts = Number(req.get("X-AgentFlow-Timestamp") ?? 0);

  // 1) Zaman toleransı (5 dk)
  if (Math.abs(Date.now() / 1000 - ts) > 300) return res.status(401).send("stale");

  // 2) HMAC-SHA256: "<timestamp>.<ham gövde>" üzerinden
  const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(`${ts}.`).update(req.body).digest("hex");
  const a = Buffer.from(sig), b = Buffer.from(expected);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.status(401).send("bad signature");

  // 3) Idempotency
  const event = JSON.parse(req.body.toString("utf8"));
  if (seen.has(event.id)) return res.status(200).send("dup");
  seen.add(event.id);

  // 4) Hızlı yanıt, işlemi arka plana al
  res.status(200).send("ok");
  setImmediate(() => handle(event));
});

function handle(event) {
  switch (event.type) {
    case "lead.qualified":
      // CRM'e yaz
      break;
    case "approval.requested":
      // Slack'e onay düğmeli mesaj gönder
      break;
    case "budget.warning":
      // Finans ekibine uyarı
      break;
  }
}

app.listen(3001);

Önemli: express.json() kullanmayın; gövde ayrıştırıldıktan sonra yeniden serileştirilirse imza tutmaz. Ham gövdeyi (express.raw) doğrulayın.

Python (FastAPI) için aynı mantık: hmac.new(secret, f"{timestamp}.".encode() + raw_body, hashlib.sha256).hexdigest() ve hmac.compare_digest.

Örnek senaryolar

SenaryoOlaylarUç noktanız ne yapar
Slack'te tek tıkla onayapproval.requested, approval.resolvedSlack Block Kit mesajı; düğme → POST /orgs/:orgId/approvals/:id/approve
CRM senkronulead.qualified, lead.replied, lead.updatedSalesforce/Pipedrive'a upsert
İçerik arşivipost.publishedYayınlanan gönderiyi veri ambarına yaz
Maliyet izlemeagent.run.finished, budget.warningusage.costUsd toplamı; eşikte PagerDuty
Müşteri destek entegrasyonuconversation.handoffZendesk/Freshdesk bileti aç
Veri gölü*Tüm zarfları S3/BigQuery'e yaz

Sık sorulan sorular

Aynı olay iki kez gelebilir mi? Evet; adresiniz geç yanıt verirse yeniden denenir. Zarftaki id alanıyla tekilleştirin.

İmza neden tutmuyor? İmza ham gövde üzerinden hesaplanır. Gövdeyi JSON olarak ayrıştırıp yeniden serileştirmeyin; "<timestamp>.<ham gövde>" kullanın.

Adresim kapalıyken olaylar kaybolur mu? Yaklaşık 1 saat boyunca 5 kez denenir. Teslim geçmişinden Yeniden gönder ile elle de gönderebilirsiniz.

Sonraki adım

OrqLabs ile başlayın

İlk iş akışınızı bugün kurun

Ücretsiz planla başlayın: hesaplarınızı bağlayın, bir şablon seçin, onay adımlarıyla kontrol sizde kalsın. Kredi kartı gerekmez.