P Pitchbar مستندات

مرجع API

وب‌هوک‌های خروجی

وب‌هوک‌های خروجی به Pitchbar اجازه می‌دهند زمانی که رویداد جالبی رخ می‌دهد، رویدادها را به نقطه پایانی شما ارسال کند. آنها را به ازای هر فضای کاری در /app/integrations/webhooks پیکربندی کنید.

سطح v1 — کوچک اما پایدار
امروزه فقط یک رویداد ارسال می‌شود: lead.captured. تحویل تک‌تلاش است (بدون تلاش مجدد) با امضای HMAC-SHA256. رویدادهای سطح مکالمه (conversation.started، conversation.message، conversation.routed) به تعویق افتاده و هنوز منتشر نشده‌اند.

پیکربندی

هر اشتراک وب‌هوک دارای موارد زیر است:

  • آدرس — نقطه پایانی شما. HTTPS به‌شدت توصیه می‌شود.
  • رویدادها — در حال حاضر فقط lead.captured.
  • کلید مخفی امضا — به‌طور خودکار تولید می‌شود. برای HMAC بدنه استفاده می‌شود.
  • فعال — کلید تغییر وضعیت.

هدرها

ارسال‌کننده این هدرها را ارسال می‌کند:

هدرمقدار
Content-Typeapplication/json
X-Pitchbar-Signaturet={timestamp},v1={hmac} — امضای زمان‌دار به سبک Stripe
X-Pitchbar-Webhook-Idیک UUID منحصربه‌فرد برای این تحویل. از آن برای حذف تکراری در سمت خود استفاده کنید.
X-Pitchbar-Eventنام رویداد (مثلاً lead.captured) تا مسیریاب شما مجبور نباشد قبل از ارسال، بدنه را تجزیه کند.

چرخش کلید مخفی

اگر مشکوک هستید که کلید مخفی نشت کرده است، آن را از /app/integrations ← کارت وب‌هوک ← چرخش کلید مخفی بچرخانید. مقدار جدید یک بار در یک مودال نشان داده می‌شود — بلافاصله آن را در تأییدکننده خود کپی کنید. کلید مخفی قدیمی لحظه‌ای که چرخش کامل می‌شود، از کار می‌افتد. تحویل‌های در حال انجام تا زمانی که کامل شوند، همچنان از کلید مخفی قدیمی استفاده می‌کنند. یک ورودی integration.webhook_secret_rotated در گزارش حسابرسی ثبت می‌شود.

تأیید امضا

امضا یک HMAC-SHA256 از "{timestamp}.{body}" با استفاده از کلید مخفی امضای اشتراک است. برای تأیید:

// Node
const crypto = require('crypto');

function verify(rawBody, signatureHeader, secret) {
    const parts = Object.fromEntries(
        signatureHeader.split(',').map(p => p.split('='))
    );
    const ts = parts.t;
    const sig = parts.v1;

    const expected = crypto
        .createHmac('sha256', secret)
        .update(`${ts}.${rawBody}`)
        .digest('hex');

    return crypto.timingSafeEqual(
        Buffer.from(expected),
        Buffer.from(sig)
    );
}

همیشه از مقایسه زمان‌ثابت استفاده کنید (timingSafeEqual در Node، hash_equals در PHP) تا از حملات زمان‌بندی جلوگیری کنید. اگر t قدیمی‌تر از حدود ۵ دقیقه است، تحویل را رد کنید — محافظت در برابر پخش مجدد در سمت شما قرار دارد.

معانی تحویل

هر تحویل یک POST HTTP با زمان‌بندی ۵ ثانیه است. هیچ تلاش مجدد داخلی وجود ندارد: یک پاسخ غیر 2xx یا زمان‌بندی، رویداد را حذف می‌کند. اگر نقطه پایانی شما به‌طور موقت از کار بیفتد، آن رویداد را از دست خواهید داد. الگوی توصیه‌شده:

  • سریع پاسخ 2xx دهید. به صف خود بافر کرده و به‌صورت ناهمگام پردازش کنید.
  • توانایی idempotency. از occurred_at رویداد + محتویات data برای حذف تکراری استفاده کنید — هنوز شناسه به ازای هر تحویل وجود ندارد.
  • تطابق. برای داده‌های حیاتی کسب‌وکار، به‌طور دوره‌ای از لیست مدیریت مشتریان بالقوه به‌جای تکیه صرف بر وب‌هوک‌ها، دریافت کنید.

payload رویدادها

lead.captured

{
    "event": "lead.captured",
    "occurred_at": "2026-05-07T12:00:00Z",
    "data": {
        "lead_id": "01HXY...",
        "agent_id": "01HXY...",
        "conversation_id": "01HXZ...",
        "name": "الکس",
        "email": "alex@example.com",
        "phone": "+1...",
        "fields": { "company": "آکمه" }
    }
}

مجموعه فیلدهای دقیق به آنچه بازدیدکننده در فرم درون‌خطی پر کرده است و هر فیلد سفارشی که روی دستیار فروش تعریف کرده‌اید بستگی دارد. کلیدها پایدار هستند. مقادیر缺失 به‌جای عدم وجود، null هستند.

وب‌هوک‌های Stripe (ورودی)

اینها جداگانه هستند — Stripe به /billing/webhook ارسال می‌کند و Cashier هدر استاندارد Stripe-Signature را با استفاده از STRIPE_WEBHOOK_SECRET تأیید می‌کند. آنها وضعیت اشتراک را هدایت می‌کنند. شما اینها را از صفحه یکپارچه‌سازی‌ها پیکربندی نمی‌کنید. آنها دغدغه مدیریت پلتفرم هستند.

تست محلی

یک وب‌هوک را به https://webhook.site یا یک آدرس محلی تونل‌شده (ngrok) اشاره دهید. از طریق محیط آزمایشی یا ویجت زنده یک مشتری بالقوه ارسال کنید. وب‌هوک در عرض یک ثانیه فعال می‌شود.

نقشه راه

سطح وب‌هوک به‌رویدادهای سطح مکالمه، یک شناسه به ازای هر تحویل و معانی حداقل یک‌بار تلاش مجدد گسترش خواهد یافت. تا آن زمان، برای وضعیتی که فراتر از lead.captured است، از نقاط پایانی مدیریت نظرسنجی کنید.

زبان خود را انتخاب کنید