کانال تلگرام فراسوعضو شوید
بازگشت به وبلاگ
بات سرورلس تلگرام
Telegram ServerlesstgcloudTelegram Bot APICloudflare WorkersServerlessSQLite

بات سرورلس تلگرام: راهنمای کامل پلتفرم رسمی Telegram Serverless و tgcloud

34 دقیقه مطالعه

تعریف کوتاه: «Telegram Serverless» پلتفرم رسمی تلگرام برای اجرای کد بک‌اند بات‌ها و Mini Appهاست، مستقیماً روی زیرساخت خود تلگرام: ماژول‌های جاوااسکریپت شما در یک V8 sandbox ایزوله، کنار Bot API و یک پایگاه‌داده‌ی داخلی مبتنی بر SQLite اجرا می‌شوند و با دستور npx tgcloud push دیپلوی می‌شوند — بدون سرور، بدون container، بدون نگرانی از مقیاس‌پذیری. پیش از معرفی این پلتفرم رسمی، عبارت «بات سرورلس تلگرام» به الگوی اجرای بات روی پلتفرم‌های شخص‌ثالث مثل Cloudflare Workers گفته می‌شد — الگویی که همچنان معتبر و قابل استفاده است و در همین مقاله پوشش داده شده.

به‌روزرسانی مهم (ژوئیه ۲۰۲۶ / تیر ۱۴۰۵): نسخه‌ی اول این مقاله زمانی نوشته شد که تلگرام هیچ پلتفرم سرورلس رسمی نداشت و «بات سرورلس تلگرام» صرفاً یک الگوی معماری جامعه‌محور بود — و مقاله همین را با صراحت گفته بود. از آن زمان، تلگرام مستندات رسمی Telegram Serverless را منتشر کرده است. این مقاله به‌طور کامل بازبینی و به‌روزرسانی شده: بخش‌های جدید بر اساس مستندات رسمی و تست عملی خود ما نوشته شده‌اند، و الگوی قبلی (سرورلس شخص‌ثالث) هم به‌عنوان گزینه‌ی جایگزین حفظ شده است.

مقدمه

اگر تا امروز یک بات تلگرام ساخته باشید، احتمالاً با این چرخه آشنا هستید: یک VPS اجاره می‌کنید، Node.js را روی آن نصب می‌کنید، یک دامنه یا ساب‌دامنه برای Webhook تنظیم می‌کنید، گواهی SSL می‌گیرید (چون Telegram Bot API فقط HTTPS را قبول می‌کند)، یک پایگاه داده راه‌اندازی می‌کنید، فرآیند را با PM2 یا systemd به‌صورت daemon اجرا می‌کنید، و بعد باید نگران آپدیت امنیتی سرور، مانیتورینگ Uptime، و مقیاس‌پذیری در زمان افزایش ناگهانی ترافیک هم باشید.

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

  • پلتفرم رسمی Telegram Serverless — که تلگرام اخیراً معرفی کرده و کد بات شما را روی زیرساخت خود تلگرام اجرا می‌کند؛

  • الگوی سرورلس شخص‌ثالث — اجرای بات از طریق Webhook روی پلتفرم‌هایی مثل Cloudflare Workers، AWS Lambda یا Vercel، که سال‌هاست جامعه‌ی توسعه‌دهندگان از آن استفاده می‌کند.

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

دیگه به vps نیاز نداریم ؟

تلگرام حالا رسماً پلتفرم سرورلس دارد

طبق مستندات رسمی، Telegram Serverless به شما اجازه می‌دهد کد بک‌اند بات یا Mini App خود را مستقیماً روی زیرساخت تلگرام اجرا کنید. اجزای اصلی آن این‌هاست:

  • اجرای کد در V8 Isolate: هر فراخوانی در یک محیط ایزوله و سبک از موتور جاوااسکریپت اجرا می‌شود که — به گفته‌ی مستندات — نزدیک به سیستم‌های خود تلگرام قرار دارد، بنابراین فراخوانی Bot API و پایگاه‌داده سریع است.

  • Bot API داخلی: کل Bot API بدون هیچ توکن‌کشی و پیکربندی، از طریق SDK در دسترس هر ماژول است — api.sendMessage(...) و تمام متدهای فعلی و آینده.

  • پایگاه‌داده‌ی داخلی SQLite: هر بات پایگاه‌داده‌ی مخصوص به خودش را دارد که بین اجراها باقی می‌ماند (persistent) و با یک DSL شبیه Drizzle ORM تعریف و کوئری می‌شود.

  • HTTP خروجی: یک کلاینت fetch برای فراخوانی APIهای بیرونی — از جمله APIهای هوش مصنوعی — در SDK وجود دارد.

  • CLI به نام tgcloud: پل بین پوشه‌ی پروژه‌ی شما و کلود تلگرام — دیپلوی، دیف، مهاجرت پایگاه‌داده و تست، همه از خط فرمان.

  • مدیریت از داخل BotFather: طبق مستندات، کل پروژه (هندلرها، کتابخانه، دیتابیس و توکن CLI) از داخل خود BotFather هم قابل مدیریت است — حتی از موبایل.

معماری در ساده‌ترین شکل خودش این است:

      کاربر پیام می‌فرستد
              │
              ▼
        سرورهای تلگرام
              │  (بدون Webhook دستی — پلتفرم خودش مدیریت می‌کند)
              ▼
   Serverless Runtime تلگرام
   (هندلر شما در V8 Isolate)
              │
              ▼
     پایگاه‌داده‌ی داخلی SQLite
              │
              ▼
     پاسخ از طریق Bot API داخلی

تفاوت کلیدی با الگوی شخص‌ثالث: در اینجا حتی Webhook را هم خودتان مدیریت نمی‌کنید. پلتفرم، Webhook را خودش تنظیم و همگام نگه می‌دارد (دستور npx tgcloud webhook فقط برای بازرسی و همگام‌سازی مجدد است) و allowed_updates را دقیقاً بر اساس هندلرهایی که دیپلوی کرده‌اید تنظیم می‌کند — یعنی تلگرام فقط برای آپدیت‌هایی کد شما را اجرا می‌کند که واقعاً هندلر دارند.

وضعیت عرضه: چه چیزی الان واقعاً در دسترس است؟

این مهم‌ترین بخش این به‌روزرسانی است و می‌خواهم کاملاً شفاف باشد، چون ترکیب «مستندات عمومی» و «دسترسی محدود» دقیقاً جایی است که توسعه‌دهنده‌ها سردرگم می‌شوند.

خلاصه‌ی وضعیت: مستندات و ابزار رسمی عمومی هستند، اما به نظر می‌رسد دسترسی به Serverless در BotFather به‌صورت تدریجی (gradual rollout) در حال عرضه است و هنوز برای بسیاری از توسعه‌دهنده‌ها — از جمله خود ما در زمان نگارش این به‌روزرسانی — فعال نشده است. فرض نکنید همین امروز برای بات شما فعال است.

جزءوضعیتمنبعمستندات رسمی (core.telegram.org)✅ منتشر شده و عمومیمستندات رسمیCLI رسمی (tgcloud در npm)✅ قابل نصب و اجرا (نسخه‌ی 0.1.2 در تست ما)تست عملی مافرمان tgcloud login✅ اجرا می‌شود و توکن CLI می‌خواهدتست عملی مامنوی Serverless در BotFather❌ برای بسیاری از کاربران هنوز ظاهر نمی‌شودتست عملی ماCLI Access Token (پیش‌نیاز لاگین)⛔ فقط از منوی Serverless در BotFather قابل دریافت استمستندات رسمیدسترسی عمومی برای همه⏳ به نظر می‌رسد محدود / در حال عرضه‌ی تدریجیجمع‌بندی ما از مستندات + تست

این جمع‌بندی از دو منبع می‌آید: آنچه مستندات رسمی می‌گویند (که وجود منوی Serverless در BotFather را پیش‌فرض می‌گیرند) و تست دست‌اول خود ما (که نشان داد این منو برای حساب‌ها و بات‌های ما وجود ندارد). مستندات رسمی در حال حاضر هیچ اشاره‌ای به «عرضه‌ی تدریجی» یا لیست انتظار نمی‌کنند — «تدریجی بودن» برداشت ما از شواهد است، نه ادعای تلگرام.

تست واقعی ما: نصب و لاگین در عمل

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

  • npx tgcloud --version بدون مشکل اجرا شد و نسخه‌ی 0.1.2 را برگرداند — یعنی پکیج رسماً روی npm منتشر شده و عمومی است.

  • npx tgcloud login هم اجرا شد و یک prompt نمایش داد — اما نه برای توکن معمولی بات، بلکه برای CLI Access Token با قالب app<id>:<secret>. توکن آشنای Bot API (قالب 123456:AA...) اینجا پذیرفته نمی‌شود؛ این دو توکن کاملاً متفاوت‌اند (بخش بعدی را ببینید).

  • برای گرفتن CLI Access Token، طبق مستندات باید به BotFather بروید: بات → Serverless → CLI Access. اما در تست ما، منوی Serverless ظاهر نشد — نه برای یک بات موجود، نه برای یک بات کاملاً جدید، و نه حتی با یک حساب تلگرام تازه‌ساخته.

چرا این یافته مهم است؟ چون زنجیره‌ی راه‌اندازی در یک نقطه‌ی مشخص قطع می‌شود: CLI عمومی است، لاگین کار می‌کند، اما کلیدِ ورود (توکن CLI) فقط از منویی قابل دریافت است که هنوز برای همه فعال نشده. اگر شما هم CLI را نصب کردید و پشت همین در ماندید، مشکل از شما نیست — صبر کنید تا منوی Serverless برای بات شما ظاهر شود و بعد ادامه دهید. بقیه‌ی این مقاله را طوری نوشته‌ایم که وقتی دسترسی باز شد، نقشه‌ی کامل را داشته باشید.

مدل احراز هویت: دو توکن که نباید اشتباه بگیرید

تلگرام حالا عملاً دو نوع credential مختلف برای بات‌ها دارد و تجربه‌ی ما نشان داد این اولین جایی است که توسعه‌دهنده‌ها گیج می‌شوند:

Bot API TokenCLI Access Tokenقالب123456:AAxxxxxxxx...app<id>:<secret>برای چه کاریفراخوانی مستقیم Bot API (sendMessage و غیره)اتصال پروژه‌ی محلی به کلود تلگرام از طریق tgcloudاز کجا می‌آیدBotFather → API TokenBotFather → بات → Serverless → CLI Accessکجا ذخیره می‌شودهر جا خودتان امن نگه دارید.tgcloud/credentials (به‌صورت خودکار git-ignore)در CIمتغیر محیطی دلخواه شمامتغیر محیطی TGCLOUD_TOKEN

چند نکته از مستندات که ارزش دانستن دارد: بخش app<id> عمومی است و ممکن است در خروجی‌ها چاپ شود، اما بخش secret هرگز در لاگ یا خطاها ظاهر نمی‌شود. login تنها دستوری است که توکن می‌پرسد — هیچ دستور دیگری وسط کار prompt نمی‌زند (تا اسکریپت‌ها و CI هنگ نکنند)، و اگر توکن ذخیره‌شده باطل شود، CLI آن را پاک می‌کند و از شما می‌خواهد دوباره login کنید.

نکته‌ی جالب برای کسانی که با پلتفرم رسمی کار می‌کنند: داخل هندلرها اصلاً به هیچ توکنی نیاز ندارید. api در SDK از قبل به بات شما متصل است — یکی از تفاوت‌های ملموس با الگوی شخص‌ثالث که در آن باید توکن بات را در متغیر محیطی Worker نگه دارید.

ساختار پروژه در Telegram Serverless

یک پروژه‌ی سرورلس تلگرام، یک پوشه‌ی معمولی تحت کنترل نسخه است — نه build step دارد، نه node_modules در زمان اجرا، نه فایل ورودی سرور. ساختار استاندارد (خروجی npm create @tgcloud/bot):

plaintext
example_bot/
├─ docs/
│  └─ tgcloud-sdk.md    # مرجع SDK — برای شما و ابزارهای AI
├─ handlers/            # نقطه‌های ورود — یک فایل به ازای هر نوع آپدیت (flat)
│  ├─ message.js
│  └─ callback_query.js
├─ lib/                 # کد مشترک — تنها پوشه‌ای که زیرپوشه مجاز است
│  └─ internal/util.js
├─ AGENTS.md            # راهنمای پروژه برای دستیارهای کدنویسی AI
├─ package.json
├─ schema.js            # تعریف جدول‌های پایگاه‌داده — یک فایل، در ریشه
└─ .tgcloud/            # وضعیت CLI: توکن، کش، کپی مرجع (git-ignored)

سه نوع کد بیشتر وجود ندارد و مسئولیت هر کدام دقیقاً مشخص است:

  • handlers/ — نقطه‌های ورود بات. هر فایل متناظر یک نوع آپدیت تلگرام است: handlers/message.js برای پیام‌ها، handlers/callback_query.js برای دکمه‌ها، handlers/inline_query.js برای اینلاین و به همین ترتیب برای هر نوع آپدیت Bot API. وقتی آپدیتی می‌رسد، پلتفرم آن را به هندلر هم‌نام مسیریابی می‌کند و export default آن فایل را با payload بازشده صدا می‌زند (هندلر message مستقیماً شیء Message را می‌گیرد، نه کل Update را). اگر برای نوعی از آپدیت هندلری وجود نداشته باشد، آن آپدیت به‌سادگی نادیده گرفته می‌شود و کد شما اصلاً اجرا نمی‌شود — پس فقط هندلرهایی را بسازید که واقعاً لازم دارید.

  • lib/ — کد مشترک بین هندلرها: helperها، لایه‌ی دسترسی به داده، یکپارچه‌سازی با سرویس‌های بیرونی. پلتفرم هرگز ماژول‌های lib/ را مستقیم اجرا نمی‌کند؛ فقط برای import شدن وجود دارند.

  • schema.js — تعریف جدول‌های پایگاه‌داده به‌صورت named export، با یک DSL شبیه Drizzle. دیپلوی این فایل هرگز خودش دیتابیس را تغییر نمی‌دهد (بخش بعد).

سیستم ماژول هم عمداً محدود و قابل پیش‌بینی است: در زمان اجرا فقط دو چیز قابل import است — sdk (و زیرماژول‌هایش مثل sdk/db) و ماژول‌های خود پروژه با نام خام (from 'schema'، from 'lib/cart'). مسیر نسبی (./schema) و پسوند .js کامپایل نمی‌شوند، و هیچ پکیج npm ای در زمان اجرا وجود ندارد. با npx tgcloud push دقیقاً همین مجموعه — schema.js به‌علاوه‌ی فایل‌های .js داخل lib/ و handlers/ — به‌صورت اتمیک دیپلوی می‌شود و وضعیت کلود آینه‌ی پوشه‌ی شما می‌شود، شامل حذف‌ها.

پایگاه داده: SQLite داخلی و مدل مهاجرت

هر بات یک پایگاه‌داده‌ی اختصاصی مبتنی بر SQLite دارد که بین اجراها باقی می‌ماند و از هر ماژولی با db در دسترس است. اگر با Drizzle ORM کار کرده باشید، عملاً چیزی برای یادگیری ندارید — column builderها، select().from().where()، اپراتورها، onConflictDoUpdate و تگ sql همان رفتار آشنا را دارند؛ فقط از sdk/db import می‌شوند. یک نمونه‌ی واقعی از مستندات:

javascript
// schema.js
import { table, integer } from 'sdk/db';

export const counters = table('counters', {
  chatId: integer('chat_id').primaryKey(),
  seen:   integer('seen').notNull().default(0),
});
javascript
// handlers/message.js
import { api, db } from 'sdk';
import { counters } from 'schema';
import { sql } from 'sdk/db';

export default async function (message) {
  const [row] = await db.insert(counters)
    .values({ chatId: message.chat.id, seen: 1 })
    .onConflictDoUpdate({
      target: counters.chatId,
      set: { seen: sql`${counters.seen} + 1` },
    })
    .returning()
    .run();

  await api.sendMessage({
    chat_id: message.chat.id,
    text: `تا حالا ${row.seen} پیام از شما دیده‌ام.`,
  });
}

چرا push و migrate از هم جدا هستند؟

این جداسازی مهم‌ترین تصمیم طراحی پلتفرم در بخش داده است: دیپلوی کد هرگز به پایگاه‌داده دست نمی‌زند.

bash
npx tgcloud push       # دیپلوی ماژول‌ها؛ تغییرات معلقِ دیتابیس را فقط گزارش می‌کند
npx tgcloud migrate    # بازبینی و اعمال تغییرات اسکیما — با تأیید شما

وقتی schema.js تغییرکرده‌ای را push می‌کنید، پلتفرم اسکیمای جدید را ثبت می‌کند و به شما می‌گوید دیتابیس «چه تغییری خواهد کرد» — اما هیچ چیزی را اعمال نمی‌کند. دلیلش ساده و عاقلانه است: یک دیپلوی روتین کد نباید بتواند به‌طور تصادفی یک migration داده را اجرا کند. تغییر داده همیشه یک تصمیم آگاهانه و جداگانه است.

migrate تفاوت بین اسکیمای شما و دیتابیس زنده را محاسبه می‌کند و هر تغییر را بر اساس ریسک دسته‌بندی می‌کند:

وضعیتیعنی چهرفتار migratesafeافزایشی و بدون ریسک — جدول، ستون یا ایندکس جدیدهمه با هم، با یک تأیید اعمال می‌شوندwarningبالقوه مخرب یا کند — حذف چیزی، یا ایندکس روی جدول بزرگیکی‌یکی نمایش داده و هر کدام جداگانه تأیید می‌شودmanualخودکار ممکن نیست — مثل تغییر type یک ستونبا توضیح و راهکار پیشنهادی نشان داده می‌شود؛ خودتان انجام می‌دهیدundocumentedدر دیتابیس هست ولی در اسکیمای شما نیستفقط برای آگاهی نمایش داده می‌شود

دو جزئیات دیگر که نشان می‌دهد طراحی چقدر محافظه‌کارانه (به معنای خوب کلمه) است: حذف یک جدول یا ستون از schema.js باعث drop شدن آن نمی‌شود — باید صریحاً آن را .deprecated('دلیل') علامت بزنید تا در migrate بعدی به‌صورت یک warning قابل تأیید ظاهر شود. و «apply all» برای تغییرات مخرب وجود ندارد؛ هر drop یک تأیید جداگانه می‌خواهد. برای اسکریپت‌ها هم فلگ‌های --dry-run، --safe و --yes تعریف شده‌اند.

یک محدودیت مهم را همین‌جا بدانید: foreign key وجود ندارد. runtime با PRAGMA foreign_keys خاموش اجرا می‌شود و DSL عمداً .references() را با خطا متوقف می‌کند — چون یک foreign key که در سکوت کار نکند (بدون cascade و بدون محافظت از orphan) از نبودنش خطرناک‌تر است. روابط را با ستون‌های ساده (userId) مدل کنید و یکپارچگی را در کد اپلیکیشن رعایت کنید. این یک محدودیت آگاهانه‌ی پلتفرم است، نه فراموش‌کاری — از ابتدای طراحی بات به آن فکر کنید.

ساخت بات با هوش مصنوعی

مستندات رسمی یک بخش مستقل به نام Building with AI دارد و جالب اینجاست که این بخش درباره‌ی دو چیز متفاوت است که هر دو به این پلتفرم خوب می‌نشینند:

۱. ساختن بات به کمک دستیار کدنویسی AI

هر پروژه‌ی جدید با دو فایل مخصوص ابزارهای AI ساخته می‌شود: AGENTS.md (راهنمای پروژه که ابزارهایی مثل Claude Code، Cursor و opencode خودکار می‌خوانند) و docs/tgcloud-sdk.md (مرجع کامل SDK). دلیلش این است که این پلتفرم چند قرارداد غیرمعمول دارد که codegen عمومی معمولاً آن‌ها را اشتباه می‌گیرد: import با نام خام، نبودن foreign key، async بودن همه‌ی فراخوانی‌های db، یک هندلر به ازای هر نوع آپدیت، و جریان دومرحله‌ای push/migrate. با این دو فایل، دستیار AI از اول این قواعد را می‌داند. جریان کار پیشنهادی خود مستندات:

bash
npm create @tgcloud/bot my-bot
cd my-bot
# بعد دستیار AI خود را باز کنید و به زبان ساده بگویید چه باتی می‌خواهید

شما بازبینی می‌کنید، با npx tgcloud run بدون دیپلوی تست می‌گیرید، و با push و migrate زنده می‌کنید. (اگر به این حوزه علاقه دارید، مقاله‌ی WebMCP و ایجنت‌های هوش مصنوعی را هم ببینید — همین الگوی «محیطِ از قبل آماده برای ایجنت» در وب هم در حال شکل‌گیری است.)

۲. ساختن بات هوش مصنوعی (اتصال به LLM)

خود مستندات، «بات‌های مکالمه‌ای AI که وضعیت هر کاربر را در دیتابیس نگه می‌دارند» را یکی از کاربردهای ایده‌آل پلتفرم معرفی می‌کند. جریان درخواست این‌طور است:

کاربر ← پیام می‌فرستد
  │
  ▼
تلگرام ← آپدیت را به هندلر می‌رساند
  │
  ▼
هندلر Serverless ← تاریخچه را از SQLite می‌خواند
  │
  ▼
فراخوانی LLM از طریق sdk fetch
(OpenAI / Claude / Gemini — هر API مبتنی بر HTTP)
  │
  ▼
پاسخ ← ذخیره در SQLite ← ارسال با api.sendMessage

دو قابلیت مستندشده این سناریو را عملی می‌کند: اول اینکه fetch در SDK از خواندن استریمی بدنه‌ی پاسخ پشتیبانی می‌کند (for await (const chunk of res.body)) و مستندات صریحاً «خروجی token-by-token از APIهای هوش مصنوعی» را به‌عنوان کاربرد آن نام می‌برد. دوم اینکه تاریخچه‌ی مکالمه در همان دیتابیس داخلی نگهداری می‌شود — بدون سرویس جداگانه.

درباره‌ی تأخیر (latency) بگذارید دقیق باشیم، نه تبلیغاتی: مزیت این معماری در دو سرِ زنجیره است — دریافت آپدیت و فراخوانی Bot API و دیتابیس، همه داخل زیرساخت تلگرام و سریع‌اند. اما خودِ فراخوانی LLM یک درخواست HTTP به بیرون است و همان قدر طول می‌کشد که از هر جای دیگری طول می‌کشید؛ در عمل، زمانِ LLM بخش غالب کل زمان پاسخ است. چیزی که این معماری واقعاً حذف می‌کند تأخیر و پیچیدگی زیرساختِ خودتان است، نه تأخیر مدل زبانی. دو محدودیت fetch را هم در طراحی لحاظ کنید: پاسخ فقط متنی است (باینری پشتیبانی نمی‌شود) و سقف کل پاسخ ۳۲ مگابایت است.

چیت‌شیت دستورات tgcloud

چهار دستوری که روزانه استفاده می‌شوند:

bash
npx tgcloud --version   # نسخه‌ی CLI (در تست ما: 0.1.2)
npx tgcloud login       # اتصال پروژه به بات — CLI Access Token می‌خواهد
npx tgcloud push        # دیپلوی اتمیک ماژول‌ها به کلود تلگرام
npx tgcloud migrate     # بازبینی و اعمال تغییرات اسکیمای دیتابیس

و فهرست کامل دستورها طبق مرجع CLI:

دستورکارinitساخت اسکلت پروژه‌ی جدید در پوشه‌ی فعلیaddساخت یک ماژول جدید (هندلر یا ماژول lib) — مثلاً add handlers/callback_queryloginاتصال پروژه به بات و ذخیره‌ی توکن در .tgcloud/statusچه چیزی نسبت به نسخه‌ی دیپلوی‌شده تغییر کرده (کاملاً آفلاین)diffتفاوت خط‌به‌خط تغییرات (آفلاین)pushدیپلوی اتمیک؛ وضعیت کلود را آینه‌ی پوشه‌ی شما می‌کندmigrateاعمال تغییرات اسکیما با دسته‌بندی safe / warning / manualrunاجرای یک هندلر روی پلتفرم با فایل‌های محلی، بدون دیپلوی — سریع‌ترین حلقه‌ی تستfetchبه‌روزرسانی کپی مرجع محلی از کلود، بدون دست زدن به فایل‌های شماpullهم‌راستا کردن فایل‌های محلی با وضعیت کلودresetدور ریختن تغییرات محلی و بازگشت به وضعیت کلودwebhookبازرسی و همگام‌سازی مجدد Webhookِ مدیریت‌شده توسط پلتفرمcompletionاسکریپت تکمیل خودکار شل (bash/zsh/fish)

یک مکانیزم ظریف که ارزش اشاره دارد: هر پروژه یک revision صعودی در کلود دارد. اگر هم‌تیمی شما (یا ماشین دیگری) زودتر دیپلوی کرده باشد، push شما رد می‌شود تا کار او را بی‌صدا بازنویسی نکنید — بعد با fetch یا pull همگام می‌شوید، یا آگاهانه push --force می‌زنید. همین optimistic concurrency است که کار تیمی بدون فرآیند قفل‌گذاری را ممکن می‌کند.

محدودیت‌های پلتفرم رسمی

صادقانه بگوییم چه چیزهایی الان محدود یا نامشخص است. اول محدودیت‌های مستند:

  • فقط جاوااسکریپت: runtime یک V8 sandbox است؛ نه Python، نه Go، نه هیچ زبان دیگری.

  • بدون پکیج npm در زمان اجرا: فقط sdk و ماژول‌های خود پروژه قابل import هستند. نه grammY، نه Telegraf، نه هیچ کتابخانه‌ی دیگری — هر چیزی که لازم دارید یا در SDK هست یا باید خودتان در lib/ بنویسید.

  • بدون فایل‌سیستم و شبکه‌ی آزاد: دسترسی به بیرون فقط از طریق fetch در SDK است؛ پاسخ‌ها فقط متنی و حداکثر ۳۲ مگابایت.

  • کار با فایل‌ها ناقص است: ارسال و forward فایل با file_id ممکن است، اما دانلود بایت‌های فایل یا آپلود فایل جدید از داخل هندلر «هنوز» پشتیبانی نمی‌شود — مستندات خودش این را محدودیت موقت می‌نامد.

  • بدون foreign key: همان‌طور که در بخش دیتابیس گفتیم — آگاهانه و قطعی.

  • عرضه‌ی محدود: منوی Serverless در BotFather هنوز برای بسیاری از کاربران فعال نیست (تست عملی ما؛ بالاتر).

و مواردی که هنوز مستند نشده و ما هم حدس نمی‌زنیم — این‌ها «نامشخص» هستند، نه «بد»:

  • قیمت‌گذاری: مستندات فعلی هیچ اشاره‌ای به هزینه، سطح رایگان یا سقف مصرف نمی‌کند.

  • محدودیت‌های runtime: سقف زمان CPU یا مدت اجرای هر فراخوانی، سقف حافظه، و اندازه‌ی مجاز پایگاه‌داده اعلام نشده است.

  • سهمیه‌ها (quotas): تعداد فراخوانی مجاز در واحد زمان و رفتار پلتفرم زیر بار سنگین مشخص نیست.

  • وظایف زمان‌بندی‌شده: چیزی معادل Cron در مستندات فعلی وجود ندارد؛ مدل اجرا فقط واکنش به آپدیت‌هاست.

اکوسیستم هم طبیعتاً جوان است — نسخه‌ی CLI هنوز 0.x است، نمونه‌کدها و ابزارهای جانبی جامعه هنوز شکل نگرفته‌اند، و بهترین شیوه‌ها (best practices) در حال کشف شدن‌اند. هیچ‌کدام از این‌ها ایراد نیست؛ فقط یعنی این پلتفرم امروز جای پروژه‌ی جدید و آزمایش است، نه جای مهاجرت دادن بات حیاتی کسب‌وکارتان.

وابستگی به پلتفرم (Vendor Lock-in): معامله‌ای که می‌کنید

هر پلتفرم مدیریت‌شده‌ای یک معامله است و این یکی هم استثنا نیست. بیایید دو کفه‌ی ترازو را بی‌طرفانه بسنجیم.

آنچه به دست می‌آورید:

  • زیرساخت صفر — نه سرور، نه container، نه گواهی SSL، نه پیکربندی Webhook. حتی توکن هم داخل هندلر لازم نیست.

  • مقیاس‌پذیری خودکار بدون هیچ پیکربندی.

  • ساده‌ترین مسیر دیپلویی که تا امروز برای بات تلگرام وجود داشته: push و تمام.

  • دیتابیس، Bot API و runtime همه کنار هم — بدون تأخیر شبکه بین اجزا و بدون یکپارچه‌سازی دستی.

آنچه واگذار می‌کنید:

  • قابلیت انتقال کد: منطق خالص جاوااسکریپت شما قابل انتقال است، اما همه‌چیز حول SDK اختصاصی (sdk، sdk/db) نوشته می‌شود. مهاجرت بعدی به Cloudflare یا VPS یعنی بازنویسی لایه‌ی دیتابیس و API — شبیه همان قفل‌شدگی D1 در Cloudflare، نه بدتر و نه بهتر.

  • قابلیت انتقال داده: داده‌ی شما در SQLite تلگرام است. مستندات فعلی ابزار export یا backup مستقیمی معرفی نکرده است (نامشخص — شاید بعداً اضافه شود). خروج داده فعلاً یعنی کوئری گرفتن و انتقال دستی.

  • وابستگی عملیاتی کامل به تلگرام: uptime، ظرفیت، قیمت‌گذاری آینده و حتی ادامه‌ی حیات سرویس، همه تصمیم تلگرام است. برای باتی که کل کسب‌وکار شماست، این یک ریسک واقعی است که باید آگاهانه بپذیرید.

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

الگوی جایگزین: سرورلس روی پلتفرم‌های شخص‌ثالث

تا پیش از پلتفرم رسمی، «بات سرورلس تلگرام» یعنی همین: بات شما روی Cloudflare Workers، AWS Lambda یا Vercel اجرا می‌شود و از طریق Webhook با Bot API صحبت می‌کند. این الگو همچنان کاملاً معتبر است — و تا وقتی دسترسی پلتفرم رسمی محدود است، عملاً تنها گزینه‌ی سرورلسی است که همین امروز می‌توانید استفاده کنید. مزیت‌های دیگرش هم سر جایشان است: آزادی انتخاب زبان (در Lambda)، اکوسیستم npm کامل، و ابزارهای بالغ.

معماری سنتی در مقابل معماری سرورلس

برای اینکه تفاوت را ملموس کنیم، بیایید دو رویکرد را کنار هم بگذاریم. (این مقایسه برای هر دو نوع سرورلس — رسمی و شخص‌ثالث — صادق است.)

معماری سنتی:                    معماری سرورلس:

تلگرام                          تلگرام
  │                               │
  ▼                               ▼
Webhook (دامنه + SSL شما)       Runtime سرورلس
  │                             (فقط لحظه‌ی نیاز اجرا می‌شود)
  ▼                               │
VPS همیشه‌روشن                    ▼
  │                             SQLite / دیتابیس edge
  ▼
پایگاه‌داده‌ی جدا

معیارمعماری سنتی (VPS)معماری سرورلساستقرار (Deployment)نصب دستی یا اسکریپت CI/CD روی سرورgit push یا دستور CLI، دیپلوی در چند ثانیهزیرساختمدیریت کامل توسط شما (سیستم‌عامل، پچ‌های امنیتی، فایروال)کاملاً مدیریت‌شده توسط پلتفرمهزینههزینه‌ی ثابت ماهانه، حتی وقتی بات بی‌کار استپرداخت بر اساس مصرف؛ اغلب سطح رایگان کافی استنگهداری (Maintenance)آپدیت سیستم‌عامل، Node.js، وابستگی‌ها، مانیتورینگ سرورتقریباً صفر؛ فقط کد اپلیکیشنمقیاس‌پذیریدستی یا نیازمند تنظیم Load Balancer/Auto Scalingخودکار و آنی، از صفر تا هزاران درخواستپایگاه دادهمعمولاً PostgreSQL/MySQL روی همان سرور یا سرویس جداSQLite داخلی (پلتفرم رسمی) یا دیتابیس edge مثل D1مانیتورینگنیاز به ابزار جداگانه (Prometheus، Grafana، Uptime Robot)معمولاً Dashboard و Log داخلی پلتفرمCold Startصفر (سرور همیشه روشن است)معمولاً چند میلی‌ثانیه تا چند صدم ثانیه، بسته به پلتفرمامنیتمسئولیت کامل با شماست (پچ، فایروال، SSH)سطح حمله‌ی بسیار کوچک‌تر؛ SSL و شبکه را پلتفرم مدیریت می‌کند

نکته‌ی مهم درباره‌ی ردیف Cold Start: در معماری سنتی، سروری که همیشه روشن است اصلاً cold start ندارد، اما در عوض دائم منابع مصرف می‌کند حتی وقتی هیچ پیامی نمی‌آید. در پلتفرم‌هایی که روی V8 Isolates کار می‌کنند (مثل Cloudflare Workers و — طبق مستندات — خود Telegram Serverless)، cold start معمولاً آن‌قدر کوچک است که برای یک بات چت عملاً محسوس نیست.

این معماری از داخل چطور کار می‌کند

بیایید مسیر کامل یک پیام را در الگوی شخص‌ثالث، از لحظه‌ای که کاربر در تلگرام تایپ می‌کند تا لحظه‌ای که پاسخ را می‌بیند، دنبال کنیم.

کاربر پیام می‌فرستد
        │
        ▼
  سرورهای تلگرام
        │  (HTTPS POST به آدرس Webhook شما)
        ▼
┌─────────────────────────┐
│   Edge Function          │   ← مثلاً یک Cloudflare Worker
│  (اجرای کد JavaScript)   │
└─────────────────────────┘
        │
        ▼
┌─────────────────────────┐
│  پایگاه داده (SQLite/D1) │   ← خواندن/نوشتن وضعیت کاربر،
└─────────────────────────┘      تاریخچه مکالمه، تنظیمات و غیره
        │
        ▼
  فراخوانی Telegram Bot API
     (متد sendMessage و مشابه)
        │
        ▼
     پیام به کاربر می‌رسد

مراحل به‌صورت دقیق‌تر:

  1. Incoming Update: وقتی کاربر پیامی می‌فرستد، تلگرام یک شیء JSON به نام Update می‌سازد که شامل اطلاعات پیام، فرستنده، چت، و غیره است، و آن را با یک درخواست POST به آدرس Webhook شما ارسال می‌کند.

  2. Runtime: پلتفرم serverless (مثلاً Cloudflare Workers) بلافاصله یک نمونه‌ی سبک از محیط اجرای JavaScript را فعال می‌کند — نه یک ماشین مجازی کامل، بلکه یک V8 Isolate که در حد میلی‌ثانیه آماده است.

  3. Execution: کد شما Update را پردازش می‌کند: تشخیص می‌دهد این یک دستور است یا پیام معمولی، منطق کسب‌وکار را اجرا می‌کند، و در صورت نیاز به پایگاه داده مراجعه می‌کند.

  4. SQLite: برای ذخیره‌سازی وضعیت (مثل تاریخچه‌ی مکالمه، تنظیمات کاربر، یا داده‌های سفارش)، از یک پایگاه‌داده‌ی سازگار با SQLite که مستقیماً در لبه‌ی شبکه (edge) در دسترس است استفاده می‌شود — Cloudflare D1 دقیقاً همین است: یک SQLite توزیع‌شده که بدون نیاز به سرور جداگانه، از همان Worker شما در دسترس است.

  5. Response: در نهایت کد شما یک درخواست HTTP به متدهای Bot API (مثل sendMessage) می‌زند تا پاسخ را برای کاربر ارسال کند — و اجرای تابع همان‌جا تمام می‌شود؛ هیچ فرآیندی در پس‌زمینه باقی نمی‌ماند.

این چرخه‌ی کامل، از دریافت پیام تا پاسخ، معمولاً کمتر از یک ثانیه طول می‌کشد و هیچ سروری در این میان «همیشه روشن» نیست. تفاوتش با پلتفرم رسمی را هم حالا می‌توانید دقیق ببینید: اینجا Webhook، توکن و دیتابیس را خودتان به هم وصل می‌کنید؛ آنجا پلتفرم همه را از قبل به هم وصل کرده است.

کد واقعی: یک نمونه‌ی حداقلی روی Cloudflare Workers

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

۱. معرفی آدرس Webhook به تلگرام (یک‌بار، بعد از دیپلوی Worker):

bash
curl -X POST "https://api.telegram.org/bot<TOKEN>/setWebhook" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-worker.your-subdomain.workers.dev/webhook"}'

۲. خودِ Worker — دریافت Update، ذخیره در D1، ارسال پاسخ:

javascript
export default {
  async fetch(request, env) {
    if (request.method !== "POST") return new Response("OK");

    const update = await request.json();
    const message = update.message;
    if (!message) return new Response("OK");

    const chatId = message.chat.id;
    const text = message.text ?? "";

    // خواندن/نوشتن وضعیت مکالمه در D1 (سازگار با SQLite)
    await env.DB.prepare(
      "INSERT INTO messages (chat_id, text, created_at) VALUES (?, ?, ?)"
    ).bind(chatId, text, Date.now()).run();

    await fetch(`https://api.telegram.org/bot${env.BOT_TOKEN}/sendMessage`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ chat_id: chatId, text: `پیام شما دریافت شد: ${text}` }),
    });

    return new Response("OK");
  },
};

۳. تعریف جدول در D1 (یک‌بار، قبل از اولین دیپلوی):

sql
CREATE TABLE IF NOT EXISTS messages (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  chat_id INTEGER NOT NULL,
  text TEXT,
  created_at INTEGER NOT NULL
);

همین سه قطعه، یک بات کارکننده‌ی کامل است: Webhook معرفی شده، Worker پیام را می‌گیرد و در D1 ذخیره می‌کند، و پاسخ را برمی‌گرداند. نسخه‌ی پروداکشن‌آماده به موارد بیشتری نیاز دارد (اعتبارسنجی هدر X-Telegram-Bot-Api-Secret-Token، مدیریت خطای شبکه، و جداسازی منطق دستورات)، اما ساختار پایه همین است.

مقایسه‌اش با نمونه‌ی رسمی در بخش دیتابیس آموزنده است: آنجا نه setWebhook بود، نه env.BOT_TOKEN، نه ساخت دستی جدول — هر سه را پلتفرم جذب کرده بود. این دقیقاً همان «boilerplate»ای است که Telegram Serverless حذف می‌کند.

مزایای این رویکرد

این مزایا بین هر دو مسیر سرورلس (رسمی و شخص‌ثالث) مشترک‌اند:

بهره‌وری توسعه‌دهنده: بدون نیاز به تنظیم SSH، فایروال، یا پیکربندی Nginx، توسعه‌دهنده می‌تواند مستقیماً روی منطق بات تمرکز کند. زمان بین «ایده» تا «اولین دیپلوی» می‌تواند از چند روز به چند دقیقه کاهش پیدا کند.

کاهش هزینه: بیشتر پلتفرم‌های serverless سطح رایگان سخاوتمندانه‌ای دارند. یک بات با ترافیک متوسط (مثلاً چند هزار پیام در روز) اغلب کاملاً در محدوده‌ی رایگان Cloudflare Workers یا Vercel جا می‌شود، در حالی که کوچک‌ترین VPS معمولاً حداقل ۵ دلار در ماه هزینه دارد — حتی وقتی بات کاملاً بی‌کار است. (قیمت‌گذاری پلتفرم رسمی تلگرام هنوز اعلام نشده.)

دیپلوی سریع‌تر: با CLI پلتفرم (wrangler deploy در Cloudflare، tgcloud push در پلتفرم رسمی) یا حتی یک git push ساده، نسخه‌ی جدید کد در عرض چند ثانیه زنده می‌شود.

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

امنیت: چون سروری برای پچ کردن یا مدیریت وجود ندارد، سطح حمله (attack surface) به‌شدت کوچک‌تر است. مدیریت گواهی SSL، فایروال شبکه، و ایزوله‌سازی محیط اجرا به‌طور کامل به عهده‌ی پلتفرم است.

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

محدودیت‌های الگوی شخص‌ثالث

هیچ معماری‌ای بدون Trade-off نیست، و این یکی هم استثنا نیست. (محدودیت‌های پلتفرم رسمی را بالاتر جداگانه بررسی کردیم.)

قفل‌شدگی به فروشنده (Vendor Lock-in): کدی که با API اختصاصی یک پلتفرم (مثلاً D1Database در Cloudflare Workers) نوشته می‌شود، به‌سادگی به پلتفرم دیگری قابل انتقال نیست. مهاجرت از Cloudflare Workers به AWS Lambda معمولاً به معنای بازنویسی بخش قابل‌توجهی از لایه‌ی زیرساخت است.

محدودیت زمان اجرا (Execution Limits): توابع serverless معمولاً یک سقف زمانی سخت‌گیرانه دارند. Cloudflare Workers در سطح رایگان محدودیت زمان CPU دارد (نه زمان کل درخواست) و در سطح پولی این محدودیت بازتر می‌شود؛ AWS Lambda حداکثر ۱۵ دقیقه اجازه‌ی اجرا می‌دهد. برای منطق ساده‌ی بات این کاملاً کافی است، اما برای عملیات سنگین، محدودکننده می‌شود.

کارهای طولانی‌مدت (Long-running Jobs): اگر بات شما نیاز به یک فرآیند پس‌زمینه دارد که ساعت‌ها طول بکشد (مثلاً پردازش دسته‌ای فایل‌ها یا polling مداوم یک سرویس خارجی)، معماری serverless گزینه‌ی مناسبی نیست؛ این نوع کار باید در جای دیگری (مثل یک Worker Queue یا Cron Job جدا) انجام شود.

بارهای سنگین محاسباتی: پردازش تصویر، مدل‌های یادگیری ماشین سنگین، یا هر عملیاتی که به CPU/GPU زیادی نیاز دارد، معمولاً با محدودیت‌های منابع پلتفرم‌های edge سازگار نیست.

نیازمندی‌های سازمانی: شرکت‌های بزرگ اغلب به کنترل کامل روی شبکه (VPC)، انطباق با استانداردهای خاص (مثل نگهداری داده در یک منطقه‌ی جغرافیایی مشخص)، یا معماری‌های چندلایه‌ی پیچیده نیاز دارند که با مدل ساده‌ی serverless هم‌خوانی کامل ندارد.

مقایسه‌ی کامل: Telegram Serverless، Cloudflare Workers، Vercel و AWS Lambda

حالا که هر دو مسیر را می‌شناسید، بیایید چهار گزینه‌ی اصلی را کنار هم بگذاریم. ستون Telegram Serverless بر اساس مستندات رسمی است و مواردی که هنوز اعلام نشده، صادقانه «نامشخص» علامت خورده‌اند.

معیارTelegram ServerlessCloudflare WorkersVercel (Edge/Functions)AWS LambdaRuntimeV8 sandbox — فقط JS، بدون npmV8 Isolate — JS/TS + WASMNode.js / Edge (V8)Container — زبان‌های متعدددیپلویtgcloud push (اتمیک)wrangler deploygit push / CLIConsole / SAM / CDK / TerraformWebhook تلگرامخودکار — پلتفرم مدیریت می‌کنددستی (setWebhook)دستی (setWebhook)دستی + API Gatewayپایگاه‌دادهSQLite داخلی (Drizzle-like)D1، KV، Durable ObjectsVercel Postgres/KV و سرویس‌های خارجیDynamoDB، RDS، هر سرویس AWSمقیاس‌پذیریخودکار (طبق مستندات)خودکارخودکارخودکارCold StartIsolate سبک؛ عدد رسمی اعلام نشدهبسیار کم (میلی‌ثانیه)کم تا متوسطمتوسط تا کندقیمتنامشخص — هنوز اعلام نشدهسطح رایگان سخاوتمندانهیکپارچه با پلن Vercelپرداخت به‌ازای اجراقفل‌شدگیبالا (SDK و دیتابیس اختصاصی)متوسط تا بالا (D1/KV)متوسطمتوسط تا بالا (اکوسیستم AWS)بهترین کاربردبات خالص تلگرامی، ساده‌ترین راه ممکنبات با نیاز به کنترل بیشتر + edge واقعیباتی که بخشی از پروژه‌ی وب/Next.js استیکپارچگی عمیق با زیرساخت AWS

نگاه نزدیک‌تر به سه پلتفرم شخص‌ثالث

Cloudflare Workers روی مدل V8 Isolates کار می‌کند — یعنی به‌جای اجرای یک container کامل برای هر درخواست، کد شما در یک نمونه‌ی سبک از موتور جاوااسکریپت کروم اجرا می‌شود. نتیجه‌ی مستقیم این معماری، سریع‌ترین cold start در بین گزینه‌های شخص‌ثالث است. از نظر ذخیره‌سازی، ترکیب D1 (سازگار با SQLite)، KV و Durable Objects دقیقاً همان چیزی است که برای اکثر بات‌های تلگرام لازم است، و سطح رایگان آن یکی از سخاوتمندانه‌ترین‌هاست.

AWS Lambda پیشگام مفهوم serverless است و از نظر بلوغ اکوسیستم، یکپارچگی با سایر سرویس‌های AWS (مثل DynamoDB، S3 و API Gateway)، و آزادی انتخاب زبان (Python، Go، دات‌نت و غیره) قدرتمندترین گزینه است. نقطه‌ضعفش cold start کندتر به‌خاطر مدل container است. اگر تیم شما از قبل روی AWS است، همین یکپارچگی می‌تواند تعیین‌کننده باشد.

Vercel اساساً برای فرانت‌اند (به‌خصوص Next.js) طراحی شده. اگر بات تلگرام شما بخشی از یک پروژه‌ی بزرگ‌تر با داشبورد وب یا لندینگ‌پیج است، همه‌چیز در یک ریپازیتوری و یک دیپلوی جمع می‌شود — تجربه‌ی توسعه‌ی بسیار روانی است. SQLite بومی ندارد اما با Vercel Postgres و دیتابیس‌های edge خارجی به‌راحتی یکپارچه می‌شود.

آیا بات‌های موجود باید مهاجرت کنند؟

پاسخ کوتاه: بستگی دارد، و تصمیم باید بر اساس واقعیت‌های فنی بات شما گرفته شود، نه صرفاً به این دلیل که «serverless مد روز است» — یا حالا، به این دلیل که «رسمی شده».

جدول تصمیم بر اساس جایی که الان هستید:

پلتفرم فعلی شماتوصیه‌ی ماVPS سنتیاگر بات واکنشی و کم‌ترافیک است، مهاجرت به سرورلس (فعلاً شخص‌ثالث؛ رسمی وقتی دسترسی گرفتید) تقریباً همیشه به‌صرفه است. اگر به Cron و فرآیند طولانی وابسته‌اید، بمانید یا معماری ترکیبی بسازید.Railway / Render / هاست مدیریت‌شدهوضعیت بینابینی دارید؛ دردِ نگهداری‌تان کم است. فقط اگر هزینه آزارتان می‌دهد یا می‌خواهید ساده‌سازی کنید مهاجرت کنید — عجله‌ای نیست.Cloudflare Workersبمانید. شما همین حالا سرورلس هستید، با ابزار بالغ‌تر و بدون محدودیت npm. پلتفرم رسمی را برای پروژه‌ی بعدی‌تان آزمایش کنید، نه برای بازنویسی این یکی.Firebase Functionsاگر فقط برای بات تلگرام از آن استفاده می‌کنید، Cloudflare Workers یا پلتفرم رسمی (پس از دسترسی) سبک‌تر و ارزان‌ترند. اگر به بقیه‌ی اکوسیستم Firebase وابسته‌اید، بمانید.n8n / ابزارهای No-codeبرای اتوماسیون‌های ساده، n8n منطقی است — مهاجرت نکنید. وقتی منطق پیچیده شد و به کد واقعی نیاز پیدا کردید، مستقیم سراغ یکی از دو مسیر سرورلس بروید.Webhook سنتی روی هاست اشتراکی (PHP و مشابه)بهترین کاندیدای مهاجرت. هاست اشتراکی نه مقیاس‌پذیری دارد نه قابلیت اطمینان؛ حتی سطح رایگان Workers ارتقای جدی است.

مهاجرت منطقی است وقتی:

  • بات شما ترافیک متوسط تا پایین دارد و بیشتر منابع سرور فعلی بلااستفاده می‌ماند.

  • منطق بات عمدتاً واکنشی است (پاسخ به پیام) و نیازی به فرآیندهای پس‌زمینه‌ی طولانی ندارد.

  • هزینه یا بار نگهداری سرور فعلی برای شما یا تیم‌تان مشکل‌ساز شده است.

  • می‌خواهید مقیاس‌پذیری خودکار داشته باشید بدون درگیر شدن با تنظیمات زیرساخت.

مهاجرت منطقی نیست وقتی:

  • بات به وظایف زمان‌بندی‌شده یا فرآیندهای طولانی‌مدت (بیش از چند ثانیه) وابسته است.

  • از یک پایگاه‌داده‌ی رابطه‌ای سنگین با کوئری‌های پیچیده استفاده می‌کنید که به‌سختی با مدل edge سازگار می‌شود.

  • تیم شما از قبل زیرساخت پایداری روی VPS دارد و مهاجرت هزینه‌ی مهندسی بیشتری نسبت به مزایای آن دارد.

  • نیازمندی‌های سازمانی خاص (انطباق، کنترل شبکه، محل نگهداری داده) دارید که با مدل serverless همخوانی ندارد.

در بسیاری از موارد، رویکرد ترکیبی منطقی‌تر است: منطق سبک و واکنشی بات (دریافت پیام و پاسخ سریع) روی serverless، و فرآیندهای سنگین‌تر (مثل پردازش دسته‌ای یا Cron Job‌های طولانی) همچنان روی یک سرور یا سرویس صف‌بندی جدا.

کاربردهای عملی

الگوی بات سرورلس تلگرام — رسمی یا شخص‌ثالث — برای طیف وسیعی از سناریوهای واقعی مناسب است:

  • بات‌های پشتیبانی مشتری: پاسخ‌گویی خودکار به سؤالات متداول، هدایت کاربر به بخش صحیح، و در صورت نیاز، انتقال مکالمه به یک اپراتور انسانی.

  • بات‌های CRM: ثبت لیدها و مخاطبین مستقیماً از طریق تلگرام، بدون نیاز به فرم جداگانه.

  • مدیریت سفارش: پیگیری وضعیت سفارش، اطلاع‌رسانی تغییر وضعیت، و حتی پردازش سفارش‌های ساده مستقیماً در چت.

  • اعلان‌ها (Notifications): ارسال هشدار قیمت، یادآوری، یا اعلان‌های سیستمی از یک سرویس بک‌اند به کاربران.

  • دستیارهای هوش مصنوعی: اتصال بات به یک مدل زبانی (LLM) برای پاسخ‌گویی هوشمند، خلاصه‌سازی، یا ترجمه — با ذخیره‌ی تاریخچه‌ی مکالمه در همان پایگاه‌داده‌ی SQLite. مستندات رسمی این را صریحاً یکی از کاربردهای ایده‌آل پلتفرم می‌داند.

  • بک‌اند Mini Appها: پلتفرم رسمی علاوه بر بات‌ها، بک‌اند Mini Appهای تلگرام را هم پوشش می‌دهد — ذخیره‌ی داده‌ی کاربر و سرو محتوای پویا.

  • بازی‌ها و ابزارها: جدول امتیازات، کوییزها و ابزارهای تعاملی.

  • بات‌های داخلی سازمانی: اتوماسیون فرآیندهای داخلی تیم، مثل ثبت مرخصی، گزارش روزانه، یا هشدارهای مانیتورینگ سرور — بدون نیاز به یک اپلیکیشن جداگانه.

آینده‌ی این اکوسیستم

اینجا باید یک اعتراف صادقانه بکنم: در نسخه‌ی اول همین مقاله نوشتم که «بعید است خودِ تلگرام وارد بازار میزبانی serverless شود، چون خارج از حوزه‌ی اصلی محصولش است.» دقیقاً همان اتفاقی که بعید می‌دانستم، افتاد. این را حذف نمی‌کنم و پشتش قایم نمی‌شوم — درسش مهم‌تر از آبروی پیش‌بینی است: تلگرام سال‌هاست به سمت پلتفرم‌شدن حرکت می‌کند (Mini Appها، Stars، و حالا Serverless) و ظاهراً هر جایی که توسعه‌دهنده‌ها اصطکاک دارند، بالقوه محصول بعدی تلگرام است.

با این دیدگاه اصلاح‌شده، روندهایی که به نظر می‌رسد ادامه پیدا کنند:

  • تکمیل تدریجی پلتفرم رسمی: عرضه‌ی گسترده‌تر منوی Serverless در BotFather، اعلام قیمت‌گذاری و سهمیه‌ها، و رفع محدودیت‌های فعلی (کار با فایل‌ها که مستندات صریحاً «موقت» می‌نامد، و احتمالاً وظایف زمان‌بندی‌شده).

  • رقابت جدی‌تر بر سر تجربه‌ی توسعه: حالا که تلگرام ساده‌ترین مسیر ممکن را تعریف کرده (بدون webhook، بدون توکن، بدون دیتابیس جدا)، پلتفرم‌های شخص‌ثالث و فریم‌ورک‌های بات برای ساده‌سازی تحت فشار بیشتری هستند.

  • ادغام عمیق‌تر با هوش مصنوعی: هم در لایه‌ی ساخت (AGENTS.md و ابزارهای AI-friendly که تلگرام از روز اول در پروژه‌ها گذاشته) و هم در لایه‌ی محصول (بات‌های LLM-محور با تاریخچه در SQLite).

  • بلوغ پایگاه‌داده‌های edge-native: Cloudflare D1، Turso و راه‌حل‌های مشابه پخته‌تر می‌شوند و محدودیت‌های SQLite توزیع‌شده کمتر.

پرسش‌های متداول

آیا تلگرام یک پلتفرم سرورلس رسمی برای بات‌ها دارد؟

بله — این تغییر مهم نسبت به گذشته است. تلگرام مستندات رسمی Telegram Serverless را در core.telegram.org منتشر کرده: اجرای کد بات در V8 sandbox روی زیرساخت خود تلگرام، با پایگاه‌داده‌ی SQLite داخلی و CLI رسمی به نام tgcloud. البته دسترسی از طریق BotFather هنوز برای همه فعال نشده است.

چرا منوی Serverless در BotFather من نیست؟

در تست عملی ما (ژوئیه ۲۰۲۶) هم این منو برای بات‌های موجود، بات جدید و حتی حساب تازه ظاهر نشد. شواهد نشان می‌دهد عرضه تدریجی است. ابزار و مستندات عمومی‌اند، اما کلید فعال‌سازی (توکن CLI) فقط از همین منو قابل دریافت است — اگر ندارید، فعلاً باید صبر کنید یا از الگوی شخص‌ثالث استفاده کنید.

تفاوت CLI Access Token با توکن معمولی بات چیست؟

توکن Bot API (قالب 123456:AA...) برای فراخوانی متدهای بات است؛ CLI Access Token (قالب app<id>:<secret>) فقط برای اتصال tgcloud به پروژه‌ی کلود شماست و از مسیر BotFather → Serverless → CLI Access گرفته می‌شود. این دو قابل تعویض نیستند.

آیا در Telegram Serverless می‌توان از پکیج‌های npm استفاده کرد؟

خیر. در زمان اجرا فقط SDK پلتفرم (sdk و زیرماژول‌هایش) و ماژول‌های خود پروژه قابل import هستند. هر منطق دیگری را باید خودتان در lib/ بنویسید.

پایگاه‌داده‌ی Telegram Serverless چیست؟

هر بات یک پایگاه‌داده‌ی اختصاصی مبتنی بر SQLite دارد که بین اجراها باقی می‌ماند. اسکیمای آن در schema.js با DSLای شبیه Drizzle تعریف می‌شود و تغییرات با tgcloud migrate — جدا از دیپلوی کد — اعمال می‌شوند. نکته‌ی مهم: foreign key عمداً پشتیبانی نمی‌شود.

آیا بات سرورلس رایگان است؟

Bot API تلگرام رایگان است. قیمت‌گذاری پلتفرم رسمی Serverless هنوز اعلام نشده. در الگوی شخص‌ثالث، هزینه به مصرف شما بستگی دارد و اکثر بات‌های کوچک تا متوسط در سطح رایگان Cloudflare Workers یا Vercel جا می‌شوند.

بهترین پلتفرم سرورلس برای بات تلگرام کدام است؟

اگر به پلتفرم رسمی دسترسی دارید و بات شما خالص تلگرامی و جاوااسکریپتی است، ساده‌ترین مسیر همان است. در غیر این صورت Cloudflare Workers به‌خاطر cold start بسیار کم و D1 برای اکثر بات‌ها انتخاب اول است؛ اگر پروژه از قبل روی AWS یا Vercel است، همان اکوسیستم منطقی‌تر است.

تفاوت webhook و polling در بات تلگرام چیست؟

در polling، بات مدام از سرورهای تلگرام می‌پرسد پیام جدیدی هست، که نیاز به یک فرآیند همیشه‌روشن دارد. در webhook، تلگرام خودش هنگام دریافت پیام جدید، درخواست را مستقیماً به آدرس شما ارسال می‌کند. در پلتفرم رسمی حتی webhook هم خودکار مدیریت می‌شود و لازم نیست خودتان تنظیمش کنید.

آیا می‌توان یک بات موجود روی VPS را به سرورلس مهاجرت داد؟

بله، اما ابتدا بررسی کنید که آیا بات به فرآیندهای پس‌زمینه‌ی طولانی یا پایگاه‌داده‌ی رابطه‌ای پیچیده وابسته است یا نه. برای پلتفرم رسمی، محدودیت‌های اضافه (فقط JS، بدون npm، بدون foreign key) را هم در نظر بگیرید.

آیا زبان برنامه‌نویسی محدود به جاوااسکریپت است؟

در پلتفرم رسمی تلگرام: بله، فقط جاوااسکریپت. در الگوی شخص‌ثالث: خیر — AWS Lambda از Python، Go، دات‌نت و زبان‌های دیگر هم پشتیبانی می‌کند و Cloudflare Workers علاوه بر JS/TS از WASM.

جمع‌بندی

داستان این مقاله خودش خلاصه‌ی خوبی از این اکوسیستم است: زمانی که نسخه‌ی اولش را نوشتم، «بات سرورلس تلگرام» یک الگوی جامعه‌محور بود و تلگرام هیچ محصول رسمی‌ای نداشت — و مقاله همین را شفاف گفته بود. حالا تلگرام با Telegram Serverless دقیقاً همین را به محصول رسمی تبدیل کرده: کد شما در V8 sandbox کنار Bot API، دیتابیس SQLite داخلی، دیپلوی با یک دستور، و مدیریت حتی از داخل BotFather.

وضعیت عملی امروز این است: مستندات و CLI عمومی‌اند، اما دسترسی هنوز برای همه باز نشده — تست عملی خود ما به دیوارِ نبودن منوی Serverless در BotFather خورد. تا وقتی نوبت شما برسد، الگوی شخص‌ثالث (به‌خصوص Cloudflare Workers + D1) همچنان یک مسیر بالغ، ارزان و آماده‌ی پروداکشن است — و همه‌چیز آن در همین مقاله هست.

توصیه‌ی نهایی من: برای بات جدید بعدی‌تان، اول BotFather را چک کنید. اگر منوی Serverless را دارید، پلتفرم رسمی را امتحان کنید — مسیر push/migrate و دیتابیس داخلی، ساده‌ترین تجربه‌ی ساخت بات تلگرام تا امروز است. اگر ندارید، با Workers شروع کنید و کدتان را طوری لایه‌بندی کنید که مهاجرت بعدی ارزان باشد. در هر دو حالت، دورانِ اجاره‌ی VPS برای یک بات ساده عملاً تمام شده است.

این مطلب برایتان مفید بود؟

شمارش آرا پس از ۵ رأی نمایش داده می‌شود.

مقالات مرتبط