Milad Mobaseri
دیورامای ایزومتریک یک سرور کوچک که ربات تلگرام از تونلی به بیرون وصل می‌شود
پایتون

ربات تلگرام روی سرور ایران: اتصال پایدار با پروکسی و systemd

سرور ایران به تلگرام وصل نمی‌شه؟ یه تونل SSH پایدار با autossh، اتصال aiogram 3 به پروکسی، اجرای ربات با systemd و اینکه کِی وب‌هوک می‌ارزه.

جواب کوتاه: برای اجرای ربات تلگرام روی سرور ایران یه مشکل اصلی داری: سرور ایران مستقیم به api.telegram.org وصل نمی‌شه، پس ربات باید درخواست‌هاش رو از یه پروکسی رد کنه. ساده‌ترین راه پایدار اینه: یه تونل SSH به یه سرور خارجی کوچیک، که با autossh همیشه بازه؛ ربات با long polling از همون تونل کار می‌کنه؛ و هر دو با systemd اجرا می‌شن تا اگه افتادن، خودشون دوباره بالا بیان. وب‌هوک فقط وقتی به‌درد می‌خوره که تلگرام بتونه از بیرون به دامنه‌ت برسه.

یه سرور مینیاتوری که ربات تلگرام از یه تونل به بیرون وصل می‌شه

چرا اصلاً ربات تلگرام روی سرور ایران؟

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

قدم ۱: یه تونل پایدار بساز

یه VPS خارجی کوچیک کافیه (کم‌ترین پلن هم جواب می‌ده). روی سرور ایران:

sudo apt install autossh
ssh-keygen -t ed25519 -f ~/.ssh/tunnel -N ""
ssh-copy-id -i ~/.ssh/tunnel.pub user@FOREIGN_IP

حالا تونل رو به‌صورت سرویس تعریف کن. فایل /etc/systemd/system/tg-tunnel.service:

[Unit]
Description=SOCKS tunnel for Telegram
After=network-online.target

[Service]
User=botuser
Environment=AUTOSSH_GATETIME=0
ExecStart=/usr/bin/autossh -M 0 -N -D 127.0.0.1:1080 \
  -o ServerAliveInterval=20 -o ServerAliveCountMax=3 \
  -o ExitOnForwardFailure=yes -i /home/botuser/.ssh/tunnel user@FOREIGN_IP
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl enable --now tg-tunnel
curl -s --socks5-hostname 127.0.0.1:1080 https://api.telegram.org | head -c 100

اگه دستور آخر جواب داد، تونل کار می‌کنه. ServerAliveInterval باعث می‌شه اتصال مرده زود تشخیص داده بشه، و Restart=always هم یعنی اگه افتاد، خودش دوباره وصل می‌شه.

نکته: پورت 1080 رو فقط روی 127.0.0.1 باز کن، نه 0.0.0.0. وگرنه هر کسی می‌تونه از پروکسیت استفاده کنه.

قدم ۲: ربات رو به پروکسی وصل کن (aiogram 3)

pip install aiogram aiohttp-socks
import asyncio, os
from aiogram import Bot, Dispatcher
from aiogram.client.session.aiohttp import AiohttpSession

session = AiohttpSession(proxy="socks5://127.0.0.1:1080")
bot = Bot(os.environ["BOT_TOKEN"], session=session)
dp = Dispatcher()

# handlerهات اینجا

async def main():
    await bot.delete_webhook(drop_pending_updates=False)
    await dp.start_polling(bot, polling_timeout=30)

asyncio.run(main())

دو نکته‌ی مهم:

  • فقط ربات از پروکسی رد می‌شه. درخواست‌های دیگه (درگاه پرداخت، API‌های داخلی) مستقیم می‌رن، که دقیقاً همونیه که می‌خوای.
  • delete_webhook رو اول کار صدا بزن. اگه قبلاً وب‌هوک تنظیم کرده باشی، polling هیچ پیامی نمی‌گیره و تا مدت‌ها نمی‌فهمی چرا.

قدم ۳: ربات رو هم سرویس کن

فایل /etc/systemd/system/mybot.service:

[Unit]
Description=Telegram bot
After=tg-tunnel.service
Requires=tg-tunnel.service

[Service]
User=botuser
WorkingDirectory=/home/botuser/bot
EnvironmentFile=/home/botuser/bot/.env
ExecStart=/home/botuser/bot/.venv/bin/python main.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Requires یعنی ربات بدون تونل بالا نمیاد، و اگه تونل ری‌استارت بشه ربات هم باهاش ری‌استارت می‌شه. لاگ‌ها هم همیشه دم دستن:

journalctl -u mybot -f

پس وب‌هوک چی؟

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

  1. تلگرام باید بتونه از بیرون به دامنه‌ت برسه. این همیشه قابل‌اعتماد نیست، مخصوصاً وقت اختلال.
  2. خود دستور setWebhook و جواب‌دادن به کاربر هنوز به پروکسی نیاز دارن.

پس برای سرور ایران، polling از طریق تونل ساده‌تر و پایدارتره. وب‌هوک وقتی می‌ارزه که ترافیک ربات خیلی زیاده و دامنه‌ت از بیرون قابل دسترسه (مثلاً پشت Cloudflare). اون موقع حتماً secret_token بذار تا هر کسی نتونه به آدرس وب‌هوکت درخواست جعلی بفرسته.

وقتی کار نمی‌کنه، اینا رو چک کن

علامت احتمالاً
Cannot connect to host api.telegram.org تونل خوابیده: systemctl status tg-tunnel
ربات بالاست ولی پیام نمی‌گیره وب‌هوک قبلی هنوز فعاله؛ delete_webhook رو صدا بزن
TelegramConflictError یه نسخه‌ی دیگه از ربات جای دیگه داره polling می‌کنه
هر چند ساعت یه بار قطع می‌شه ServerAliveInterval نذاشتی یا سرور خارجی ناپایداره

چک‌لیست قبل از اینکه خیالت راحت بشه

  • تونل با systemctl status tg-tunnel فعاله و بعد از ری‌بوت سرور هم خودش بالا میاد.
  • پروکسی فقط روی 127.0.0.1 گوش می‌ده، نه روی همه‌ی آی‌پی‌ها.
  • ربات با Requires به تونل وابسته‌ست و با Restart=always اجرا می‌شه.
  • توکن ربات توی فایل .env هست، نه وسط کد یا توی گیت.
  • یه بار عمداً تونل رو ری‌استارت کن و ببین ربات بدون دخالت تو دوباره جواب می‌ده.

اگه این پنج تا تیک خوردن، ربات‌ت روی سرور ایران تقریباً بدون مراقبت کار می‌کنه.

سؤال‌های رایج

به‌جای تونل SSH می‌شه از V2Ray یا پروکسی آماده استفاده کرد؟
آره، هر چیزی که یه SOCKS5 یا HTTP پروکسی روی 127.0.0.1 بده با همین کد کار می‌کنه. فقط آدرس proxy رو عوض کن. تونل SSH رو پیشنهاد کردم چون ابزار اضافه نمی‌خواد و راحت سرویس می‌شه.

اگه نت ملی بشه چی؟
ارتباط سرور ایران با بیرون قطع می‌شه و این روش هم از کار میفته. اون موقع فقط ربات‌هایی کار می‌کنن که روی سرور خارجی هستن.

python-telegram-bot دارم، نه aiogram.
اونم پروکسی رو پشتیبانی می‌کنه (با نصب python-telegram-bot[socks]). موقع ساختن Application هم .proxy(...) رو بذار و هم .get_updates_proxy(...)؛ اگه دومی رو یادت بره، ربات پیام می‌فرسته ولی پیامی دریافت نمی‌کنه.

#آیوگرام#لینوکس#پروکسی#ربات تلگرام

نوشته‌های مرتبط