وبهوک
بهجای اینکه مدام وضعیت را بپرسید، ما به شما خبر میدهیم. برای کارهای طولانی — مثل ویدیو — این تنها روش درست است.
۱. ثبت آدرس
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);
}