ربات تلگرام
راهنمای انتخاب هاست ربات تلگرام بر اساس سورس، لوکیشن و منابع
برای انتخاب هاست ربات تلگرام باید اول بدانید ربات آپدیت ها را با وبهوک می گیرد یا با getUpdates، با PHP نوشته شده یا پایتون، و به چه سرویس هایی بیرون از تلگرام وصل می شود. نوع سرویس و لوکیشن از همین جواب ها درمی آید.
ربات تلگرام برنامه ای است که آپدیت ها را از تلگرام می گیرد و با فراخوانی متدهای Bot API جواب می دهد. هاست ربات تلگرام باید با همان روشی کار کند که سورس با آن نوشته شده است. رباتی که روی هاست اشتراکی چند دقیقه کار می کند و بعد خاموش می شود، معمولاً با polling نوشته شده و روی سرویسی رفته که برای وبهوک ساخته شده است.
ربات تلگرام از هاست چه می خواهد
نیاز ربات به هاست به روش دریافت آپدیت بستگی دارد. با وبهوک، هاست فقط باید یک آدرس HTTPS داشته باشد که به درخواست های تلگرام جواب بدهد. با getUpdates، برنامه ربات باید بدون وقفه روی سرور روشن بماند.
آپدیت یعنی هر اتفاقی که ربات باید از آن باخبر شود، مثل پیام کاربر یا کلیک روی دکمه شیشه ای. تلگرام آپدیت را یا خودش با وبهوک (متد setWebhook) به هاست می فرستد، یا ربات آن را با متد getUpdates می گیرد. طبق مستندات Bot API تا وقتی وبهوک فعال است، getUpdates کار نمی کند، پس باید یکی از این دو را انتخاب کنید.
روش وبهوک
در این روش آدرس یک فایل روی هاست را با setWebhook به تلگرام معرفی می کنید. از آن به بعد هر آپدیت به شکل یک درخواست HTTPS POST با بدنه JSON به همان آدرس می رسد. اسکریپت اجرا می شود، جواب می دهد و تمام می شود، و بین دو پیام هیچ پردازه ای از ربات روی سرور روشن نیست. صفحه های PHP یک سایت هم همین طور اجرا می شوند، برای همین وبهوک روی هاست اشتراکی cPanel مشکلی ندارد.
آدرس وبهوک باید HTTPS با گواهی معتبر باشد و روی یکی از پورت های ۴۴۳، ۸۰، ۸۸ یا ۸۴۴۳ جواب بدهد، پس دامنه و SSL فقط در همین روش لازم می شوند. اگر اسکریپت کدی خارج از 2xx برگرداند، تلگرام همان درخواست را چند بار دیگر می فرستد. شرط های گواهی، کد فایل دریافت کننده و پارامترهای setWebhook را در آموزش تنظیم وبهوک ربات تلگرام روی cPanel نوشته ایم.
روش getUpdates یا long polling
در این روش برنامه ربات پشت سر هم از تلگرام می پرسد آپدیت تازه ای هست یا نه. دامنه و SSL لازم نیست، ولی برنامه باید ساعت ها و روزها بی وقفه اجرا شود. هاست اشتراکی برای چنین پردازه ای ساخته نشده است. تعداد پردازه ها در آن سقف دارد و پردازه ای که مدت طولانی منابع بگیرد ممکن است بسته شود.
تلگرام آپدیت های تحویل نشده را حداکثر ۲۴ ساعت نگه می دارد. اگر ربات چند ساعت خاموش بماند، پیام ها بعد از روشن شدن می رسند، ولی آپدیت های قدیمی تر از یک روز از بین می روند.
| وبهوک (setWebhook) | getUpdates (long polling) | |
|---|---|---|
| دامنه و SSL | لازم است | لازم نیست |
| پردازه همیشه روشن | لازم نیست | لازم است |
| روی هاست اشتراکی cPanel | بدون مشکل | معمولاً مشکل ساز |
| اگر اسکریپت خطا بدهد | تلگرام درخواست را دوباره می فرستد | برنامه باید offset را خودش درست جلو ببرد |
| نمونه های رایج | سورس های تک فایلی PHP، اپ های Flask و جنگو | اسکریپت های پایتون با run_polling یا start_polling |
هاست PHP یا پایتون برای ربات تلگرام
ربات PHP که با وبهوک کار می کند روی هاست cPanel اجرا می شود، به شرط اینکه نسخه PHP با سورس جور باشد. ربات پایتون روی cPanel فقط در حالت وبهوک و داخل یک فریم ورک وب مثل Flask یا جنگو اجرا می شود. اگر ربات پایتون با polling نوشته شده و نمی خواهید تغییرش بدهید، سرور مجازی لازم دارید.
نسخه PHP در سورس های آماده
بخش بزرگی از سورس های آماده فارسی با PHP نوشته شده اند و با وبهوک کار می کنند. معمولاً یک فایل مثل index.php یا bot.php ورودی تلگرام را می خواند و جواب می دهد. در این سورس ها اول نسخه PHP را چک کنید. توابعی مثل each() و create_function() در PHP 8 حذف شده اند و سورس قدیمی که از آن ها استفاده می کند روی نسخه جدید خطای 500 می دهد. سورس های تازه هم اغلب روی PHP 7 اجرا نمی شوند.
در هاست cPanel با CloudLinux، نسخه PHP و افزونه هایی مثل curl، mbstring و pdo_mysql را از بخش Select PHP Version تنظیم می کنید. قابلیت تنظیم نسخه PHP در فهرست ویژگی های پلن های هاست ربات تلگرام پیکوهاست آمده است.
ربات پایتون روی cPanel
کتابخانه های python-telegram-bot و aiogram هر دو روش را پشتیبانی می کنند، ولی بیشتر مثال های آماده با polling شروع می شوند، مثلاً با run_polling در python-telegram-bot یا start_polling در aiogram. متد run_webhook در python-telegram-bot هم وب سرور داخلی خودش را روی یک پورت راه می اندازد، و روی هاست اشتراکی نمی توانید پورت عمومی باز کنید.
در cPanel با CloudLinux، اپلیکیشن پایتون از بخش Setup Python App ساخته می شود. این ابزار یک محیط مجازی با نسخه پایتون دلخواه می سازد و برنامه را از طریق Passenger به شکل اپلیکیشن WSGI اجرا می کند. پس ربات پایتون روی این هاست به یک view در Flask یا جنگو نیاز دارد که بدنه JSON را از تلگرام بگیرد و به کتابخانه ربات بدهد. روند کامل این کار در راه اندازی ربات پایتون با جنگو روی cPanel توضیح داده شده است.
هاست پایتون هلند و هاست پایتون آلمان پیکوهاست دسترسی Terminal، چند نسخه پایتون و دیتابیس PostgreSQL دارند. با Terminal پکیج ها را با pip نصب می کنید و migrationهای جنگو را اجرا می کنید.
دیتابیس، کران جاب و محدودیت حجم فایل
اگر ربات وضعیت کاربر، سفارش ها یا فهرست اعضا را نگه می دارد، MySQL یا PostgreSQL انتخاب بهتری از فایل JSON و SQLite است. در وبهوک چند درخواست هم زمان اجرا می شوند و نوشتن هم زمان در یک فایل JSON ممکن است داده را خراب کند. SQLite هم در هر لحظه فقط یک عملیات نوشتن را می پذیرد. بقیه منتظر می مانند و اگر انتظار طول بکشد، با خطای database is locked متوقف می شوند. پلن های هاست ربات تلگرام پیکوهاست هر دو دیتابیس MySQL و PostgreSQL را دارند و تعداد دیتابیس در آن ها محدود نیست.
کران جاب برای کارهای زمان بندی شده است، مثل ارسال یادآوری و پاک کردن داده های قدیمی، یا فرستادن پیام همگانی در دسته های کوچک. بعضی ها یک اسکریپت getUpdates را هر دقیقه با کران اجرا می کنند تا ربات polling را روی هاست اشتراکی زنده نگه دارند. در این حالت جواب ربات تا یک دقیقه عقب می افتد. اگر اجرای قبلی هم هنوز تمام نشده باشد، دو نسخه هم زمان getUpdates می فرستند و یکی از آن ها خطای Conflict: terminated by other getUpdates request می گیرد.
دستور کرانی که یک فایل PHP را هر ده دقیقه اجرا می کند این شکلی است:
*/10 * * * * /usr/local/bin/php /home/USERNAME/bot/cron.php >/dev/null 2>&1
در فرم Cron Jobs در cPanel، زمان بندی را در فیلدهای جداگانه وارد می کنید و بقیه دستور در فیلد Command می رود. مستندات cPanel توصیه می کند فاصله اجراها آن قدر باشد که اجرای قبلی تمام شود. ساخت کران با تصویر در راهنمای Cron Jobs در مرکز آموزش پیکوهاست آمده است. اگر نسخه PHP کران با نسخه ای که برای سایت انتخاب کرده اید فرق داشت، مسیر فایل اجرایی PHP درست را از پشتیبانی بپرسید.
حجم فایل هم روی انتخاب سرویس اثر دارد. طبق پرسش های متداول ربات های تلگرام، ربات با Bot API فایل های تا ۲۰ مگابایت را دانلود و تا ۵۰ مگابایت را آپلود می کند. برای فایل بزرگ تر یا باید سرور محلی Bot API را روی سرور مجازی اجرا کنید، یا با کتابخانه ای مثل MadelineProto از پروتکل MTProto استفاده کنید. فرق این دو مسیر را در مقایسه MadelineProto و Bot API برای ربات PHP بخوانید.
محدودیت منابع هاست اشتراکی و اثرش روی ربات
در هاست اشتراکی cPanel با CloudLinux هر حساب برای CPU، حافظه، I/O، پردازه های ورودی (Entry Processes) و تعداد کل پردازه ها سقف دارد تا یک کاربر کل سرور را اشغال نکند. درخواست های ربات در ساعت های شلوغ یک جا می رسند و هر درخواست هم زمان وبهوک یک Entry Process از سهم حساب می گیرد.
| محدودیت | در ربات چه چیزی مصرفش می کند | نشانه پر شدن |
|---|---|---|
| CPU | پردازش هر آپدیت، ساخت تصویر، کوئری سنگین | کندی جواب و Read timeout expired در getWebhookInfo |
| RAM (PMEM) | لود کردن فایل بزرگ در حافظه، کتابخانه های حجیم پایتون | بسته شدن پردازه، خطای 500 یا 503 |
| I/O | نوشتن لاگ، ذخیره فایل، دیتابیس | کند شدن خواندن و نوشتن |
| Entry Processes (EP) | هر درخواست هم زمان وبهوک | خطای 508 Resource Limit Is Reached |
| تعداد پردازه (NPROC) | پردازه های PHP، کران جاب، نشست SSH، پردازه پایتون | اجرا نشدن کران یا اسکریپت تازه، خطای 500 یا 503 |
پارامتر max_connections در setWebhook سقف اتصال هم زمان تلگرام به وبهوک است. مقدارش بین ۱ و ۱۰۰ و پیش فرضش ۴۰ است. اگر روی ۴۰ بماند و سقف EP حساب کمتر باشد، در ساعت شلوغ بخشی از درخواست ها خطای 508 می گیرند. تلگرام همین درخواست ها را دوباره می فرستد و فشار روی حساب بیشتر می شود. max_connections را کمتر از سقف EP بگذارید تا درخواست های اضافه سمت تلگرام در صف بمانند.
ارسال همگانی را داخل درخواست وبهوک انجام ندهید. طبق همان صفحه پرسش های متداول، بهتر است به هر چت بیشتر از یک پیام در ثانیه نفرستید. ربات در گروه نمی تواند بیشتر از ۲۰ پیام در دقیقه بفرستد و سقف ارسال همگانی حدود ۳۰ پیام در ثانیه است. حلقه ای که به هزاران کاربر پیام می دهد، زمان پاسخ وبهوک را از حد می گذراند. پیام ها را در یک جدول دیتابیس صف کنید و با کران در دسته های کوچک بفرستید.
صفحه پلن ها فضای NVMe، مقدار RAM و I/O هر پلن را نشان می دهد و برای پلن های میدلاین تعداد کانکشن و پردازه هم زمان را هم نوشته است. این عددها را با تعداد درخواست هم زمانی که از ربات انتظار دارید مقایسه کنید.
کدام لوکیشن برای هاست ربات تلگرام بهتر است؟
برای بیشتر ربات ها سرور بیرون از ایران راحت تر است، چون بدون واسطه به api.telegram.org وصل می شود. هاست ایران وقتی به کار می آید که ربات باید به سرویسی وصل شود که فقط IP ایران را قبول می کند.
لوکیشن هاست روی سرعتی که کاربر می بیند اثر مستقیمی ندارد، چون کاربر به هاست شما وصل نمی شود. پیام کاربر به سرورهای تلگرام می رود و تلگرام آن را به هاست ربات تحویل می دهد. لوکیشن روی دو مسیر اثر دارد: مسیر هاست تا تلگرام (رسیدن وبهوک و فراخوانی متدهای API) و مسیر هاست تا سرویس هایی که ربات به آن ها وصل می شود، مثل درگاه پرداخت، پنل پیامک یا API سایت خودتان.
هاست ربات در آلمان، هلند، فرانسه یا انگلیس
فیلتر تلگرام در ایران روی سروری که بیرون از ایران است اثری ندارد. هاست ربات در این لوکیشن ها مستقیم به api.telegram.org وصل می شود و تلگرام هم مستقیم به وبهوکش دسترسی دارد. سرورهای هاست میدلاین آلمان پیکوهاست در دیتاسنتر هتزنر و سرورهای میدلاین هلند در آمستردام هستند.
ثبت وبهوک هم از این لوکیشن ها ساده تر است. برای اجرای setWebhook از مرورگری در ایران فیلترشکن لازم دارید، ولی روی هاست اروپایی می توانید همان درخواست را از خود هاست بفرستید، با curl در Terminal یا با یک فایل PHP.
ضعف این لوکیشن ها در اتصال به سرویس های داخلی است. بعضی سرویس های ایرانی درخواست از IP خارجی را نمی پذیرند، و در دوره های اختلال اینترنت بین الملل ممکن است اتصال سرور خارجی به آن ها کند یا قطع شود.
هاست ربات در ایران
هاست داخل ایران به سرویس های داخلی نزدیک است و مشکل IP خارجی ندارد. ولی چون تلگرام فیلتر است، اتصال سرور به Bot API و رسیدن وبهوک از تلگرام به مسیری بستگی دارد که هاستینگ فراهم کرده است. در صفحه محصول، هاست ربات تلگرام ایران با «مسیر مستقیم داخل کشور» معرفی شده است. پیش از خرید در تیکت بپرسید اتصال به api.telegram.org چطور برقرار می شود و بعد از راه اندازی خروجی getWebhookInfo را چک کنید. اگر اینترنت بین الملل کامل قطع شود، سرور داخل ایران به تلگرام دسترسی ندارد.
| لوکیشن | ارتباط با تلگرام | ارتباط با سرویس های ایرانی | مناسب برای |
|---|---|---|---|
| آلمان، هلند، فرانسه، انگلیس | مستقیم | در زمان اختلال ممکن است محدود شود | بیشتر ربات ها، ربات های MadelineProto |
| ایران | وابسته به مسیری که هاستینگ فراهم کرده | مستقیم | رباتی که باید به سرویسی وصل شود که فقط IP ایران را می پذیرد |
اگر ربات به هر دو نیاز دارد، ربات را روی هاست اروپایی نگه دارید و فقط بخش پرداخت را روی هاست ایران اجرا کنید تا دو بخش از طریق یک API ساده با هم کار کنند. در این حالت به جای یک سرویس، دو سرویس را نگهداری می کنید.
هاست اشتراکی، هاست میدلاین یا سرور مجازی
هاست اشتراکی cPanel برای سورس های PHP با وبهوک و ربات های پایتونی که به وبهوک تبدیل شده اند کافی است. سورس های MadelineProto هاست میدلاین می خواهند، و ربات polling که نمی خواهید بازنویسی اش کنید سرور مجازی. روی هاست اشتراکی مدیریت با cPanel است و نگهداری سیستم عامل و وب سرور با هاستینگ.
MadelineProto یک کتابخانه PHP برای پروتکل MTProto است. با آن می توانید با حساب کاربری کار کنید و به امکاناتی برسید که Bot API ندارد. این سورس ها پردازه طولانی تر و اتصال هم زمان بیشتری از یک ربات وبهوک معمولی می خواهند. پیکوهاست هاست میدلاین را با کانفیگ مخصوص همین سورس ها در دو لوکیشن آلمان و هلند ارائه می کند. نصب قدم به قدم آن را در راهنمای نصب MadelineProto روی cPanel ببینید.
سرور مجازی وقتی لازم می شود که دسترسی root می خواهید: ربات پایتون با polling که نمی خواهید تغییرش بدهید، چند ربات روی یک سرور، Redis یا صف پیام، یا سرور محلی Bot API. سرور مجازی هلند پیکوهاست با مجازی سازی KVM، هارد NVMe و رم DDR4 در آمستردام است. روی سرور مجازی، ربات polling را به شکل یک سرویس systemd اجرا کنید تا بعد از ریستارت سرور یا از کار افتادن برنامه دوباره روشن شود:
[Unit]
Description=Telegram bot
Wants=network-online.target
After=network-online.target
[Service]
User=bot
WorkingDirectory=/home/bot/app
ExecStart=/home/bot/app/venv/bin/python bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
فایل را در /etc/systemd/system/mybot.service ذخیره کنید، با systemctl daemon-reload به systemd معرفی اش کنید و با systemctl enable --now mybot روشنش کنید. خروجی برنامه را با journalctl -u mybot -f می بینید.
| وضعیت ربات | سرویس مناسب |
|---|---|
| سورس PHP تک فایلی با وبهوک | هاست ربات تلگرام cPanel |
| ربات پایتون که می شود آن را به وبهوک داخل Flask یا جنگو منتقل کرد | هاست پایتون |
| سورس MadelineProto یا ربات با حساب کاربری | هاست میدلاین |
| ربات پایتون با polling بدون امکان تغییر | سرور مجازی |
| چند ربات، صف پیام، Redis یا سرور محلی Bot API | سرور مجازی |
| خطای 508 مکرر حتی بعد از بهینه کردن کد | پلن بالاتر یا سرور مجازی |
چک لیست پیش از خرید هاست ربات تلگرام
- در کد سورس دنبال
setWebhook،getUpdates،run_pollingیاstart_pollingبگردید تا روش دریافت آپدیت معلوم شود. - نسخه PHP یا پایتون و پکیج های لازم را از راهنمای سورس،
composer.jsonیاrequirements.txtپیدا کنید. - برای وبهوک یک دامنه یا ساب دامین با SSL معتبر لازم دارید. در هاست ربات تلگرام پیکوهاست ساب دامین و SSL رایگان خودکار فعال می شوند.
- ببینید سورس با MySQL کار می کند یا PostgreSQL.
- کارهای زمان بندی شده ربات را فهرست کنید تا معلوم شود کران جاب لازم دارید یا نه.
- اگر ربات فایل بزرگ تر از ۲۰ مگابایت دانلود یا بزرگ تر از ۵۰ مگابایت آپلود می کند، Bot API معمولی جواب نمی دهد و سرور محلی Bot API یا MadelineProto لازم دارید.
- سرویس های بیرونی مثل درگاه پرداخت یا پنل پیامک را فهرست کنید و از هر کدام بپرسید درخواست از IP خارج از ایران را می پذیرد یا نه.
- اگر ربات ارسال همگانی دارد، تعداد کاربران را با سقف ارسال تلگرام بسنجید و برای صف ارسال برنامه داشته باشید.
- پلن های هاست ربات تلگرام پیکوهاست بک آپ روزانه رایگان دارند، ولی هر چند وقت یک خروجی از دیتابیس ربات را روی سیستم خودتان هم نگه دارید.
مشکلات رایج بعد از راه اندازی ربات
ربات به پیام ها جواب نمی دهد
اول آدرس https://api.telegram.org/bot<TOKEN>/getWebhookInfo را باز کنید. اگر فیلد url خالی است، وبهوکی ثبت نشده است. اگر last_error_message پر است، متن آن علت را می گوید، مثلاً خطای SSL، ریدایرکت، 404 یا تمام شدن مهلت پاسخ. معنی هر پیام و راه حلش را در جدول خطاهای وبهوک و getWebhookInfo پیدا می کنید.
یک پیام چند بار پردازش می شود
وقتی اسکریپت دیر جواب بدهد یا کدی غیر از 2xx برگرداند، تلگرام همان آپدیت را دوباره می فرستد. اگر ربات در این فاصله کاری مثل ثبت سفارش یا کم کردن موجودی انجام داده باشد، آن کار دو بار ثبت می شود. update_id هر آپدیت را در دیتابیس ذخیره کنید و آپدیت تکراری را نادیده بگیرید.
خطای Conflict در getUpdates
پیام Conflict: can't use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first یعنی روی ربات وبهوک فعال است و هم زمان برنامه ای با polling اجرا کرده اید. یکی از دو روش را کنار بگذارید. برای برگشت به polling، متد deleteWebhook را صدا بزنید.
خطای 508 در ساعت های شلوغ
سقف Entry Processes حساب پر شده است. max_connections را پایین بیاورید، کارهای طولانی را از وبهوک به کران منتقل کنید و کوئری های کند را بررسی کنید. اگر بعد از این تغییرها خطا ادامه داشت، منابع بیشتری لازم دارید.
ربات پایتون بعد از مدتی خاموش می شود
این اتفاق معمولاً یعنی ربات با polling روی هاست اشتراکی اجرا شده است. پردازه ای که از SSH یا Terminal روشن کرده اید، با بسته شدن نشست یا رسیدن به سقف منابع متوقف می شود. ربات را به وبهوک منتقل کنید یا به سرور مجازی بروید.
قدم های اول بعد از خرید هاست
- سورس را از File Manager در cPanel آپلود کنید. آموزش تصویری آپلود سورس در cPanel مراحل را نشان می دهد.
- نسخه PHP یا پایتون را مطابق نیاز سورس تنظیم کنید و فایل تنظیمات را با توکن ربات پر کنید.
- وبهوک را ثبت کنید. نسخه کوتاه این کار در آموزش setWebhook در مرکز آموزش پیکوهاست آمده است.
- به ربات
/startبفرستید و در getWebhookInfo مطمئن شویدpending_update_countصفر است و خطای تازه ای ثبت نشده است. - اگر ربات کار زمان بندی شده دارد، کران جاب را بسازید و یک بار اجرای آن را در لاگ ببینید.