یک راهنمای جدید با تمرکز بر Laravel به توسعه‌دهندگان نشان می‌دهد که چگونه با ایمن‌سازی webhook، استفاده از Redis برای تضمین یکپارچگی (idempotency) و انتقال کارهای سنگین به صف‌ها (queues)، از اتمام زمان (timeout)، تکرار اقدامات یا از کار افتادن ربات‌های تلگرام تحت فشار جلوگیری کنند.

چرا webhookهای تلگرام به چیزی فراتر از یک مسیر (route) ساده نیاز دارند

تلگرام هر تعامل کاربر با ربات را به صورت یک HTTP POST به آدرس URL مشخص‌شده توسط توسعه‌دهنده ارسال می‌کند. این پلتفرم انتظار دارد در عرض چند ثانیه پاسخ 200 OK دریافت کند؛ اگر بیشتر طول بکشد، درخواست را دوباره ارسال می‌کند. تکرار درخواست‌ها به این معناست که یک update_id یکسان می‌تواند چندین بار دریافت شود و اگر ربات در داخل همان درخواست، در پایگاه داده چیزی بنویسد یا APIهای خارجی را فراخوانی کند، ممکن است باعث ایجاد ردیف‌های تکراری، ارسال پیام‌های دوبله یا شرایط رقابتی (race conditions) شود. برای ربات‌هایی که ده‌ها یا صدها پیام در ثانیه را مدیریت می‌کنند، این تأخیر به سرعت به یک مانع بزرگ تبدیل می‌شود.

۱. نقطه پایانی (endpoint) را با یک هدر مخفی ایمن کنید

تلگرام به هر فراخوانی webhook، یک هدر X-Telegram-Bot-Api-Secret-Token اضافه می‌کند. آن هدر را با یک مقدار مخفی ذخیره شده در سرور مقایسه کنید — با استفاده از تابع hash_equals در PHP برای جلوگیری از حملات زمان‌بندی (timing attacks) — و هر درخواستی را که از سمت تلگرام نباشد، رد کنید. در Laravel، این بررسی را در یک middleware قرار دهید تا تأییدیه قبل از اینکه کنترلر با payload درگیر شود، اجرا گردد.

۲. هر به‌روزرسانی را با استفاده از Redis یکپارچه (idempotent) کنید

هر payload ورودی دارای یک update_id منحصربه‌فرد است. این راهنما پیشنهاد می‌کند که آن ID را با استفاده از پرچم NX (تنها در صورت عدم وجود) در Redis ذخیره کنید. این عملیات تنها برای اولین بار با موفقیت انجام می‌شود؛ در صورت تکرار درخواست، کلید از قبل موجود خواهد بود و webhook می‌تواند بلافاصله پاسخ 200 OK را برگرداند تا به تلگرام اعلام کند که آن به‌روزرسانی مدیریت شده است. از آنجایی که Redis در حافظه (memory) اجرا می‌شود، این بررسی تقریباً هیچ تأخیری ایجاد نمی‌کند و کلید برای شناسایی موارد تکراری باقی می‌ماند.

۳. کارهای سنگین را به پردازش‌های پس‌زمینه (background jobs) بسپارید

حتی با وجود بررسی سریع در Redis، منطق تجاری ربات — شامل نوشتن در پایگاه داده، فراخوانی APIهای شخص ثالث و ساخت پیام — هرگز نباید داخل درخواست webhook اجرا شود. به محض اینکه webhook تأیید شد و update_id ذخیره گردید، یک Laravel queued job را ارسال (dispatch) کنید. پاسخ HTTP را فوراً ارسال کنید و اجازه دهید worker کار را با سرعت خودش پردازش کند. این کار باعث می‌شود ربات کاملاً در محدوده زمانی پاسخ‌گویی تلگرام باقی بماند و از تکرار درخواست‌ها توسط پلتفرم جلوگیری می‌کند.

اصلاحات برای محیط عملیاتی (Production)

  • به محدودیت‌های نرخ (rate limits) احترام بگذارید. وقتی ربات از محدودیت‌های ثانیه‌ای خود فراتر می‌رود، تلگرام خطای 429 Too Many Requests را همراه با هدر Retry-After برمی‌گرداند. کارگران صف (queue workers) باید آن هدر را بخوانند و قبل از تلاش مجدد برای اجرای کارِ شکست‌خورده، متوقف شوند.
  • قبل از پاسخ دادن، ذخیره کنید. ابتدا هرگونه داده کاربر را در پایگاه داده بنویسید؛ ربات تنها پس از یک commit موفق باید پیام تأیید را ارسال کند. این ترتیب از سناریوهایی جلوگیری می‌کند که در آن پیام به کاربر می‌رسد اما رکورد مربوط به آن هرگز ثبت نمی‌شود.
  • payloadهای callback را کوتاه کنید. تلگرام حجم callback_data را در 64 بایت محدود می‌کند. داده‌های بزرگتر را در پایگاه داده ذخیره کنید و برای رعایت محدودیت، فقط یک ID مرجع را در payload دکمه ارسال کنید.

خلاصه مطلب: احراز هویت درخواست، حذف موارد تکراری با Redis و واگذاری کارها به صف‌ها (queues)، به توسعه‌دهندگان Laravel اجازه می‌دهد ربات‌های تلگرامی بسازند که فوراً پاسخ می‌دهند، در محدوده نرخ مجاز باقی می‌مانند و با افزایش تقاضای کاربران، به شکلی تمیز مقیاس‌پذیر می‌شوند.