به محتوای اصلی

وبهوک (Webhook) چیست و چطور بدون سرور راه‌اندازی‌اش کنیم؟

وبهوک یعنی سرویس شما را صدا بزند، نه برعکس. تفاوتش با polling، شکل رویداد، تأیید امضا، تلاش مجدد، و راه‌اندازی بدون نوشتن حتی یک خط بک‌اند.

عاطفه امیری۵ دقیقه مطالعه
در این مطلب

وبهوک (Webhook) ساده‌ترین راه برای این است که سیستم شما بفهمد یک اتفاق افتاده — بدون اینکه هر چند ثانیه بپرسد «چیزی شده؟». به‌جای اینکه شما سرویس را صدا بزنید، سرویس شما را صدا می‌زند. این مقاله می‌گوید وبهوک دقیقاً چیست، چه فرقی با polling دارد، چطور امنش کنید، و چطور بدون نوشتن بک‌اند راهش بیندازید.

وبهوک چیست؟

در API معمولی، شما درخواست می‌فرستید و جواب می‌گیرید. وبهوک این جهت را برعکس می‌کند: شما یک آدرس HTTP اعلام می‌کنید، و هر بار اتفاق مشخصی افتاد، سرویس یک درخواست POST به آن آدرس می‌فرستد و می‌گوید چه شده.

به همین دلیل گاهی به آن «API معکوس» یا «callback مبتنی بر HTTP» هم می‌گویند. مثال‌های آشنا: درگاه پرداخت که نتیجه‌ی تراکنش را اعلام می‌کند، سرویس پیامک که وضعیت تحویل را برمی‌گرداند، یا مخزن گیت که بعد از هر push خبر می‌دهد.

وبهوک در برابر polling

معیارPolling (پرسیدن دوره‌ای)Webhook
چه کسی شروع می‌کندکلاینت شماسرویس
تأخیربه بازه پرسیدن بستگی داردتقریباً بلادرنگ
مصرف منابعبالا — بیشتر درخواست‌ها خالی‌اندفقط وقتی اتفاقی افتاده
پیچیدگی کلاینتکمنیاز به یک آدرس عمومی و قابل دسترس
از دست رفتن رویدادکم — دوباره می‌پرسیدنیاز به تلاش مجدد و بررسی تکراری‌ها

قاعده‌ی سرانگشتی: اگر بازه‌ی پرسیدن‌تان زیر یک دقیقه شده، احتمالاً به وبهوک نیاز دارید.

وبهوک به چه دردی می‌خورد؟

سناریوهایی که در پروژه‌های واقعی بیشترین کاربرد را دارند:

  • اطلاع‌رسانی: ثبت سفارش جدید → پیامک به مدیر فروشگاه یا پیام در گروه کاری.
  • همگام‌سازی: رکورد جدید → درج در یک سامانه‌ی حسابداری یا CRM موجود.
  • اتوماسیون: اتصال به ابزارهایی مثل n8n یا اسکریپت کوچک خودتان، بدون اینکه لازم باشد بک‌اند اصلی را دست بزنید.
  • پردازش سنگین خارج از مسیر درخواست: تولید فاکتور PDF یا پردازش تصویر، بعد از اینکه رکورد ثبت شد.

نکته‌ی معمارانه: وبهوک دریچه‌ی خروج است. هر جا منطقی لازم شد که موتور قوانین بدون کد نمی‌تواند بیانش کند، به‌جای بازنویسی کل بک‌اند، رویداد را به چیزی می‌سپارید که همین حالا دارید.

یک رویداد وبهوک چه شکلی است؟

در فیکارو برای هر موجودیت می‌توانید به رویدادهای ساخت، ویرایش و حذف مشترک شوید. بدنه‌ی درخواستی که به آدرس شما می‌رسد این شکلی است:

{
  "id": "0192f3a1-8c4e-7b2d-9f10-3a5b7c9d1e2f",
  "type": "order.create",
  "entity": "order",
  "op": "create",
  "timestamp": "2026-08-05T09:12:44Z",
  "record": { "id": "0192f3...", "status": "pending", "total": 4200000 }
}

در رویداد ویرایش، علاوه بر record یک کلید old هم می‌آید تا بفهمید دقیقاً چه چیزی عوض شده است.

امنیت وبهوک: چطور مطمئن شویم درخواست واقعی است؟

آدرس وبهوک شما عمومی است؛ هرکسی می‌تواند به آن POST بزند. بدون تأیید امضا، هر کسی می‌تواند وانمود کند سفارشی ثبت شده. برای همین هر تحویل، سه هدر همراه دارد:

X-Fikaro-Signature:  sha256=<hmac-sha256-hex>
X-Fikaro-Timestamp:  <unix-timestamp>
X-Fikaro-Webhook-Id: <webhook-id>

امضا با کلید مخفی وبهوک، روی زمان و بدنه‌ی خام با هم ساخته می‌شود — به‌شکل timestamp و بعد یک نقطه و بعد بدنه. یعنی زمان هم بخشی از چیزی است که امضا می‌شود، و نتیجه‌اش این است که یک درخواست ضبط‌شده را نمی‌شود بعداً با زمان تازه دوباره فرستاد.

بررسی در سمت گیرنده:

import crypto from "node:crypto";

function verify(rawBody, headers, secret) {
  const ts = headers["x-fikaro-timestamp"];
  // پنجره زمانی: هر چیزی قدیمی‌تر از ۵ دقیقه رد شود
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;

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

  // مقایسه زمان-ثابت؛ مقایسه معمولی رشته‌ها نشتی زمانی دارد
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(headers["x-fikaro-signature"]),
  );
}

امضا را روی بدنه‌ی خام بررسی کنید، نه روی خروجی JSON.parse. اگر بدنه را اول تجزیه و دوباره سریالایز کنید، حتی یک تفاوت در فاصله‌ها یا ترتیب کلیدها امضا را باطل می‌کند.

تحویل ناموفق، تلاش مجدد و رویدادهای تکراری

اینترنت قابل اعتماد نیست و سرویس گیرنده گاهی پایین است. سه چیزی که هر گیرنده‌ی وبهوکی باید در نظر بگیرد:

  • تلاش مجدد: تحویل ناموفق تا پنج بار با فاصله‌ی فزاینده تکرار می‌شود — از ۳۰ ثانیه تا چند ساعت. سرویسی که یک ساعت پایین بوده، رویداد را بعد از برگشتن می‌گیرد.
  • خاموشی خودکار: اگر یک آدرس پشت سر هم شکست بخورد، وبهوک به‌طور خودکار غیرفعال و دلیلش ثبت می‌شود. اندپوینت مرده‌ای که برای همیشه تلاش مجدد بگیرد، وبهوک‌های سالم را زیر نویز خودش پنهان می‌کند.
  • بررسی تکراری بودن (idempotency): به‌خاطر تلاش مجدد، ممکن است یک رویداد دو بار برسد. فیلد id رویداد را ذخیره کنید و اگر قبلاً دیده‌اید، بی‌صدا رد شوید. بدون این، یک قطعی شبکه تبدیل به دو پیامک برای مشتری می‌شود.

قاعده‌ی چهارم هم عملی است: سریع جواب بدهید. رویداد را در صف بگذارید و بلافاصله ۲۰۰ برگردانید. پردازش سنگین داخل هندلر وبهوک، تحویل را به تایم‌اوت می‌برد و چرخه‌ی تلاش مجدد را بی‌دلیل روشن می‌کند.

چرا آدرس داخلی و لوکال‌هاست پذیرفته نمی‌شود

آدرس وبهوک ورودی‌ای است که سرور بعداً خودش آن را صدا می‌زند. اگر بدون محافظ رها شود، تبدیل به راهی برای رسیدن به شبکه‌ی داخلی می‌شود — مثلاً اشاره به سرویس متادیتای ابری یا به خود دیتابیس، و بعد خواندن جوابش از لاگ تحویل‌ها. به همین دلیل آدرس‌هایی که به محدوده‌های خصوصی و رزروشده می‌رسند رد می‌شوند، و این بررسی دو بار انجام می‌شود: یک بار موقع ذخیره‌ی آدرس، و یک بار درست قبل از هر تحویل — چون DNS می‌تواند بعد از تأیید اولیه به آدرس خصوصی برگردانده شود.

برای توسعه‌ی محلی، از یک تونل عمومی (مثل ngrok) استفاده کنید تا آدرس واقعاً از بیرون قابل دسترس باشد.

راه‌اندازی بدون نوشتن بک‌اند

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

اگر منطقی که می‌خواهید داخل خود مسیر درخواست اتفاق بیفتد — مثلاً «سفارش زیر صفر رد شود» یا «مبلغ کل خودکار حساب شود» — وبهوک ابزار درستش نیست؛ موتور قوانین همان لحظه و قبل از ذخیره اعمال می‌شود. وبهوک برای کاری است که بعد از ثبت اتفاق می‌افتد.

برای دیدن تصویر کامل بک‌اند، API آماده و REST API و وب سرویس را ببینید.

سوالات متداول

فرق وبهوک با API چیست؟
در API شما درخواست می‌فرستید و جواب می‌گیرید؛ در وبهوک سرویس به آدرس شما درخواست می‌فرستد. یکی «پرسیدن» است و دیگری «خبر دادن». معمولاً هر دو را کنار هم استفاده می‌کنید.
برای دریافت وبهوک حتماً به سرور نیاز دارم؟
به یک آدرس عمومی و قابل دسترس نیاز دارید، ولی لازم نیست سرور کامل باشد. یک تابع بدون سرور، یک اسکریپت روی هر هاستی، یا ابزارهای اتوماسیون مثل n8n همگی می‌توانند گیرنده باشند.
اگر سرویس من موقع ارسال وبهوک پایین باشد چه می‌شود؟
تحویل ناموفق چند بار با فاصله فزاینده تکرار می‌شود، تا چند ساعت. اگر یک آدرس مدت طولانی پشت سر هم شکست بخورد، وبهوک به‌طور خودکار غیرفعال می‌شود و دلیلش در پنل نمایش داده می‌شود.
چطور جلوی پردازش دوباره یک رویداد را بگیرم؟
شناسه رویداد (فیلد id) را ذخیره کنید و قبل از پردازش بررسی کنید که قبلاً دیده نشده باشد. چون تلاش مجدد وجود دارد، رسیدن یک رویداد بیش از یک بار حالت عادی است، نه استثنا.

مطالب مرتبط