aidoom

وب‌هوک

به‌جای اینکه مدام وضعیت را بپرسید، ما به شما خبر می‌دهیم. برای کارهای طولانی — مثل ویدیو — این تنها روش درست است.

۱. ثبت آدرس

const endpoint = await client.webhooks.create({
  url: 'https://myapp.com/webhooks/incoming',
  events: ['job.completed', 'job.failed'],
});

// فقط همین یک بار نمایش داده می‌شود — ذخیره‌اش کنید
console.log(endpoint.secret);   // whsec_...

۲. دریافت و تأیید امضا

هر درخواست با هدر X-Signature امضا می‌شود. حتماً امضا را بررسی کنید — بدون آن، هر کسی می‌تواند به آدرس شما درخواست جعلی بفرستد.

import express from 'express';
import { webhookHandler } from '@aiproxy/sdk/middleware';

// express.raw ضروری است: امضا روی بایت‌های خام محاسبه شده
app.post('/webhooks/incoming',
  express.raw({ type: 'application/json' }),
  webhookHandler(process.env.WEBHOOK_SECRET, async (event) => {
    if (event.type === 'job.completed') {
      await markReady(event.data.id);
    }
  }));
بدنهٔ خام لازم است. اگر فریم‌ورک شما JSON را قبلاً پارس کرده باشد، بایت‌ها تغییر کرده‌اند و امضا هرگز تطبیق نمی‌کند — شایع‌ترین علت خطای «امضا معتبر نیست».

ساختار امضا

http
X-Signature: t=1735689600,v1=5257a869e7...

# رشتهٔ امضاشده:
#   "<t>.<بدنهٔ خام>"
# الگوریتم: HMAC-SHA256 با کلید whsec_

زمان داخل رشتهٔ امضاشده است، بنابراین یک درخواست ضبط‌شده نه قابل تکرار است و نه بدون کلید قابل امضای مجدد. مقایسه در زمان ثابت انجام می‌شود و درخواست‌های قدیمی‌تر از ۵ دقیقه رد می‌شوند.

رویدادها

job.completedپردازش با موفقیت تمام شد و خروجی آماده است.
job.failedپردازش ناموفق بود. اعتبار به‌صورت خودکار بازگردانده شده است.
job.cancelledپردازش توسط کاربر لغو شد.
payment.succeededپرداخت تأیید و اعتبار افزوده شد.
payment.failedپرداخت ناموفق بود.
credits.lowاعتبار حساب رو به اتمام است.

نمونهٔ محتوا

json
{
  "id": "evt_a1b2c3d4e5f6",
  "type": "job.completed",
  "created": 1735689600,
  "data": {
    "id": "job_x7y8z9",
    "tool": "face-swap",
    "status": "completed",
    "credits": 10
  }
}

تلاش مجدد

اگر سرور شما ۲xx برنگرداند، ۵ بار با فاصلهٔ فزاینده تلاش می‌کنیم (۵، ۱۰، ۲۰، ۴۰ و ۸۰ ثانیه). آدرسی که ۲۰ بار پیاپی شکست بخورد به‌صورت خودکار غیرفعال می‌شود.

سریع پاسخ دهید و کار سنگین را به صف بسپارید. اگر پاسخ دیر برسد، تلاش مجدد شروع می‌شود و همان رویداد را دوباره دریافت می‌کنید.

تست و عیب‌یابی

// ارسال یک رویداد آزمایشی
await client.webhooks.test(endpoint.id);

// دیدن اینکه دقیقاً چه فرستادیم و چه پاسخی گرفتیم
const log = await client.webhooks.deliveries(endpoint.id);
for (const d of log) {
  console.log(d.attempt, d.success, d.status, d.durationMs + 'ms', d.error);
}