برای رباتهایی که روی سرور یا هاست پایدار بالا هستند، استفاده از Webhook بهجای long polling هم مصرف منابع را کم میکند هم تاخیر پیامها را پایین میآورد 🚀
با Webhook، Telegram هر آپدیت را مستقیم به URL ربات میفرستد و دیگه لازم نیست سرور مدام
📌 نکته مهم: آدرس Webhook حتماً باید HTTPS باشد و روی پورتی که فایروال اجازه میدهد در دسترس باشد.
نمونه ساده با python-telegram-bot (ورژن v20+):
چند نکته عملی 🛠️
- برای ترافیک زیاد، Webhook بهتر از polling جواب میدهد و scale کردن پشت Nginx یا Load Balancer راحتتر میشود.
- روی endpoint مربوط به Webhook هیچ لاگ حساس (مثل توکن) چاپ نشود و timeout پاسخدهی خیلی بالا نرود.
- روی سرور، health-check سبک برای اطمینان از زنده بودن ربات نگهداری شود.
برای جزئیات بیشتر و پارامترهای دقیق Webhook:
مستندات رسمی Telegram Bot API - setWebhook
امتحان Webhook روی یک ربات واقعی، خیلی خوب تفاوت سرعت و پایداری را نشان میدهد؛ مخصوصاً وقتی تعداد چتها بالا میرود ⚙️
🔖 #TelegramBot #ربات #تلگرام #telegram_bot #webhook #python #performance #security
👤 Developix
💎 Channel: @DevelopixRobot
با Webhook، Telegram هر آپدیت را مستقیم به URL ربات میفرستد و دیگه لازم نیست سرور مدام
getUpdates صدا بزند.📌 نکته مهم: آدرس Webhook حتماً باید HTTPS باشد و روی پورتی که فایروال اجازه میدهد در دسترس باشد.
نمونه ساده با python-telegram-bot (ورژن v20+):
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
TOKEN = "YOUR_BOT_TOKEN"
WEBHOOK_URL = "https://example.com/bot/webhook" # URL عمومی
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("ربات با Webhook فعاله ✅")
app = ApplicationBuilder().token(TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.run_webhook(
listen="0.0.0.0",
port=8443,
url_path="bot/webhook",
webhook_url=WEBHOOK_URL,
)
چند نکته عملی 🛠️
- برای ترافیک زیاد، Webhook بهتر از polling جواب میدهد و scale کردن پشت Nginx یا Load Balancer راحتتر میشود.
- روی endpoint مربوط به Webhook هیچ لاگ حساس (مثل توکن) چاپ نشود و timeout پاسخدهی خیلی بالا نرود.
- روی سرور، health-check سبک برای اطمینان از زنده بودن ربات نگهداری شود.
برای جزئیات بیشتر و پارامترهای دقیق Webhook:
مستندات رسمی Telegram Bot API - setWebhook
امتحان Webhook روی یک ربات واقعی، خیلی خوب تفاوت سرعت و پایداری را نشان میدهد؛ مخصوصاً وقتی تعداد چتها بالا میرود ⚙️
🔖 #TelegramBot #ربات #تلگرام #telegram_bot #webhook #python #performance #security
👤 Developix
💎 Channel: @DevelopixRobot
👍1
Clean Architecture در ربات تلگرام چطور کمک میکند؟ 🧱🤖
وقتی ربات پیچیده میشود (مثلاً پرداخت، مدیریت کاربر، پنل ادمین)، اگر همهچیز را توی یک فایل bot.py بنویسیم، بعد از مدتی هیچکس حتی خودِ ما هم نمیفهمیم چی به چیه 😅
اینجاست که ایدهٔ Clean Architecture وارد میشود: جدا کردن لایهها تا Telegram فقط «درگاه ورودی» باشد، نه قلب منطق برنامه.
بهصورت ساده، میتوانیم چند لایهٔ مهم در ربات در نظر بگیریم:
• Domain (Business Logic): قوانین اصلی ربات (مثلاً: کاربر عادی حق دسترسی به فلان فرمان را ندارد).
• Application / Use Cases: سناریوها (مثلاً: "ثبت سفارش"، "ثبت کاربر جدید").
• Infrastructure: چیزهای وابسته به دنیا بیرون: Telegram Bot API، Database، Redis، HTTP و ...
• Interface / Delivery: هندلرهای پیام، Webhook، CLI و غیره.
نکتهٔ مهم این است که داخلیها بیرونیها را نمیشناسند. یعنی منطق اصلی ربات، نباید مستقیم به
مثال ساده با Python (الگو، نه کد نهایی پروداکشن):
اینجا Use Case هیچ وابستگی مستقیمی به
• راحتتر تست واحد (Unit Test) مینویسیم ✅
• اگر روزی از
• ساختن چند نوع ورودی (Webhook، Polling، حتی CLI) سادهتر میشود ✅
برای درک عمیقتر ایده، نگاه به مقالهٔ اصلی Uncle Bob بسیار کمک میکند:
لینک مقاله Clean Architecture
استفاده از این رویکرد در رباتهای تلگرام، مخصوصاً وقتی پروژه تیمی و بلندمدت است، جلوی خیلی از دردسرهای ریفکتور و باگهای عجیبی که از بههمریختگی کد میآیند را میگیرد. از پروژهٔ فعلیتان شروع کنید و حتی شده یک لایهٔ کوچک را جدا کنید؛ تاثیرش را در خوانایی و تستپذیری سریع میبینید 🔧🚀
🔖 #TelegramBot #ربات #تلگرام #Clean_Architecture #Telegram_Bot #Python #aiogram #Design_Pattern #Architecture
👤 Developix
💎 Channel: @DevelopixRobot
وقتی ربات پیچیده میشود (مثلاً پرداخت، مدیریت کاربر، پنل ادمین)، اگر همهچیز را توی یک فایل bot.py بنویسیم، بعد از مدتی هیچکس حتی خودِ ما هم نمیفهمیم چی به چیه 😅
اینجاست که ایدهٔ Clean Architecture وارد میشود: جدا کردن لایهها تا Telegram فقط «درگاه ورودی» باشد، نه قلب منطق برنامه.
بهصورت ساده، میتوانیم چند لایهٔ مهم در ربات در نظر بگیریم:
• Domain (Business Logic): قوانین اصلی ربات (مثلاً: کاربر عادی حق دسترسی به فلان فرمان را ندارد).
• Application / Use Cases: سناریوها (مثلاً: "ثبت سفارش"، "ثبت کاربر جدید").
• Infrastructure: چیزهای وابسته به دنیا بیرون: Telegram Bot API، Database، Redis، HTTP و ...
• Interface / Delivery: هندلرهای پیام، Webhook، CLI و غیره.
نکتهٔ مهم این است که داخلیها بیرونیها را نمیشناسند. یعنی منطق اصلی ربات، نباید مستقیم به
python-telegram-bot یا aiogram وابسته باشد.مثال ساده با Python (الگو، نه کد نهایی پروداکشن):
"""domain/entities.py"""
from dataclasses import dataclass
@dataclass
class User:
id: int
username: str | None
is_admin: bool = False
"""domain/services.py"""
from .entities import User
class AccessService:
def can_use_admin_panel(self, user: User) -> bool:
return user.is_admin
"""application/use_cases.py"""
from .dto import MessageDTO
from domain.services import AccessService
class HandleAdminCommand:
def __init__(self, access_service: AccessService):
self._access = access_service
def execute(self, msg: MessageDTO) -> str:
if not self._access.can_use_admin_panel(msg.user):
return "دسترسی غیرمجاز ❌"
return "خوش اومدی ادمین 👋"
"""infrastructure/telegram_handlers.py"""
from aiogram import Router, types
from application.use_cases import HandleAdminCommand
from application.dto import MessageDTO
router = Router()
handle_admin = HandleAdminCommand(access_service=...)
@router.message(commands=["admin"])
async def admin_handler(message: types.Message):
dto = MessageDTO(
user_id=message.from_user.id,
username=message.from_user.username,
text=message.text,
)
reply_text = handle_admin.execute(dto)
await message.answer(reply_text)
اینجا Use Case هیچ وابستگی مستقیمی به
aiogram ندارد و فقط با یک MessageDTO کار میکند. این یعنی:• راحتتر تست واحد (Unit Test) مینویسیم ✅
• اگر روزی از
aiogram به کتابخانهٔ دیگری مهاجرت کنیم، منطق اصلی ربات تقریباً دستنخورده میماند ✅• ساختن چند نوع ورودی (Webhook، Polling، حتی CLI) سادهتر میشود ✅
برای درک عمیقتر ایده، نگاه به مقالهٔ اصلی Uncle Bob بسیار کمک میکند:
لینک مقاله Clean Architecture
استفاده از این رویکرد در رباتهای تلگرام، مخصوصاً وقتی پروژه تیمی و بلندمدت است، جلوی خیلی از دردسرهای ریفکتور و باگهای عجیبی که از بههمریختگی کد میآیند را میگیرد. از پروژهٔ فعلیتان شروع کنید و حتی شده یک لایهٔ کوچک را جدا کنید؛ تاثیرش را در خوانایی و تستپذیری سریع میبینید 🔧🚀
🔖 #TelegramBot #ربات #تلگرام #Clean_Architecture #Telegram_Bot #Python #aiogram #Design_Pattern #Architecture
👤 Developix
💎 Channel: @DevelopixRobot
🔥3❤1
🤖 ساخت ربات تلگرام دکمهدار با Python (pyTelegramBotAPI)
خیلی وقتها یه ربات ساده
تو این پست، خیلی جمع و جور، یه ربات Python میسازیم که:
• با
• یه دکمه «دیدن زمان الان ⏰» نشون میده
• با زدن دکمه، ساعت فعلی رو برمیگردونه
پایهی کارمون روی کتابخونهی معروف pyTelegramBotAPI هست که دقیقا روی Telegram Bot API پیادهسازی شده و مستنداتش اینجاست:
github.com/eternnoir/pyTelegramBotAPI
نصب و راهاندازی سریع ⚙️
۱️⃣ با BotFather یه Bot جدید بساز و
۲️⃣ روی سرور یا سیستم خودت Python 3 داشته باش.
۳️⃣ این پکیج رو نصب کن:
نمونه کد ربات دکمهدار 🧩
کد زیر یه ربات کامل و قابل اجراست (با
چند نکتهی ریز ولی مهم 🛠
•
• همیشه بعد از هندل کردن دکمه، یه
• برای رباتهای جدی، بهجای
این اسکلت ساده، همون چیزیه که بعداً میتونه تبدیل بشه به رباتهای منویی، سیستم تیکت، فرم ثبتنام، یا حتی پنل مدیریت داخل خود تلگرام.
امتحانش کن و اگر برات مفید بود، با بقیهی دولوپرهای ربات تلگرام هم شیرش کن 🌱
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #Python #pyTelegramBotAPI #Inline_Keyboard #Webhook #Polling #Bot_Development #Persian
👤 Developix
💎 Channel: @DevelopixRobot
خیلی وقتها یه ربات ساده
/start داریم که فقط جواب متن میده. ولی رباتهای کاربردی معمولاً با Inline Keyboard کار میکنن: دکمههای زیر پیام که با لمس کردنشون، ربات یه اکشن مشخص انجام میده (مثلاً «دیدن منو»، «گرفتن لینک»، «ثبتنام» و ...).تو این پست، خیلی جمع و جور، یه ربات Python میسازیم که:
• با
/start خوشآمد میگه 😄• یه دکمه «دیدن زمان الان ⏰» نشون میده
• با زدن دکمه، ساعت فعلی رو برمیگردونه
پایهی کارمون روی کتابخونهی معروف pyTelegramBotAPI هست که دقیقا روی Telegram Bot API پیادهسازی شده و مستنداتش اینجاست:
github.com/eternnoir/pyTelegramBotAPI
نصب و راهاندازی سریع ⚙️
۱️⃣ با BotFather یه Bot جدید بساز و
TOKEN رو بگیر.۲️⃣ روی سرور یا سیستم خودت Python 3 داشته باش.
۳️⃣ این پکیج رو نصب کن:
pip install pyTelegramBotAPI
نمونه کد ربات دکمهدار 🧩
کد زیر یه ربات کامل و قابل اجراست (با
polling):import telebot
from telebot import types
from datetime import datetime
API_TOKEN = "YOUR_BOT_TOKEN_HERE"
bot = telebot.TeleBot(API_TOKEN)
@bot.message_handler(commands=["start"])
def send_welcome(message):
keyboard = types.InlineKeyboardMarkup()
btn_time = types.InlineKeyboardButton(
text="⏰ دیدن زمان الان",
callback_data="show_time"
)
keyboard.add(btn_time)
bot.send_message(
message.chat.id,
"سلام! 👋\nبا دکمه زیر میتونی زمان فعلی سرور رو ببینی.",
reply_markup=keyboard
)
@bot.callback_query_handler(func=lambda c: c.data == "show_time")
def process_callback_show_time(callback_query):
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
bot.answer_callback_query(callback_query.id)
bot.send_message(
callback_query.message.chat.id,
f"⏰ زمان فعلی: {now}"
)
if __name__ == "__main__":
print("Bot is running...")
bot.infinity_polling()
چند نکتهی ریز ولی مهم 🛠
•
callback_data حداکثر ۶۴ بایت میتونه باشه؛ برای اطلاعات پیچیدهتر بهتره یه ID بفرستی و دیتای اصلی رو تو Database نگه داری.• همیشه بعد از هندل کردن دکمه، یه
answer_callback_query صدا بزن (مثل کد بالا) تا خطای query is too old نگیری و UX بهتر بشه.• برای رباتهای جدی، بهجای
polling بهتره از webhook استفاده بشه (مثلاً پشت Nginx یا روی Cloudflare Tunnel).این اسکلت ساده، همون چیزیه که بعداً میتونه تبدیل بشه به رباتهای منویی، سیستم تیکت، فرم ثبتنام، یا حتی پنل مدیریت داخل خود تلگرام.
امتحانش کن و اگر برات مفید بود، با بقیهی دولوپرهای ربات تلگرام هم شیرش کن 🌱
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #Python #pyTelegramBotAPI #Inline_Keyboard #Webhook #Polling #Bot_Development #Persian
👤 Developix
💎 Channel: @DevelopixRobot
👍2
الگوی Strategy در مدیریت Command های ربات تلگرام 🧩
یکی از تمیزترین راهها برای مدیریت منطق پیچیده در ربات تلگرام، استفاده از Strategy Pattern است. مخصوصاً وقتی ربات شما چندین دستور مثل
با الگوی Strategy میتوانیم منطق هر Command را در یک کلاس جدا نگه داریم و یک Command Dispatcher تمیز داشته باشیم.
ایدهی اصلی Strategy:
- برای هر رفتار (مثلاً هر Command)، یک Strategy جدا تعریف میشود.
- یک کانتکست (اینجا: Message Handler) فقط تصمیم میگیرد کدام Strategy را صدا بزند.
- اضافه کردن Command جدید، بدون تغییر کدهای قبلی انجام میشود (Open/Closed Principle ✅).
نمونه با Python و کتابخانه python-telegram-bot:
در Handler اصلی فقط کافیه Dispatcher را صدا بزنید و بقیهی منطق از هم جدا و تمیز میماند ✨
مزایا برای ربات تلگرام:
- افزودن Command جدید فقط با ساختن یک کلاس جدید (بدون دستزدن به بقیه کدها).
- تستنویسی راحتتر؛ هر Strategy مستقل تست میشود.
- جداسازی واضح بین لایهی Routing و لایهی Business Logic.
نکتههای عملی 🛠
- نام کلاسها را بر اساس Command شفاف انتخاب کنید (مثل
- برای Commandهای پیچیده، آنها را به چند Service کوچکتر بشکنید تا Strategy هم بیش از حد چاق نشود.
- اگر تعداد Commandها زیاد شد، میتوانید Strategyها را در ماژولهای جدا (folders) سازماندهی کنید.
برای مطالعهی بیشتر دربارهی Strategy Pattern:
refactoring.guru/design-patterns/strategy
این الگو مخصوصاً در رباتهایی که بهمرور بزرگ میشوند کمک میکند ساختار کد تمیز، قابلگسترش و قابلنگهداری باقی بماند. از قدمهای کوچک شروع کنید و کمکم Commandهای فعلی را به Strategy تبدیل کنید 🚀
🔖 #TelegramBot #ربات #تلگرام #Strategy_Pattern #Clean_Code #Telegram_Bot #Python #Design_Patterns
👤 Developix
💎 Channel: @DevelopixRobot
یکی از تمیزترین راهها برای مدیریت منطق پیچیده در ربات تلگرام، استفاده از Strategy Pattern است. مخصوصاً وقتی ربات شما چندین دستور مثل
/start، /help، /settings و… دارد، اگر همهچیز را در یک فایل بزرگ بنویسید، بهسرعت تبدیل به Spaghetti Code میشود 🤯با الگوی Strategy میتوانیم منطق هر Command را در یک کلاس جدا نگه داریم و یک Command Dispatcher تمیز داشته باشیم.
ایدهی اصلی Strategy:
- برای هر رفتار (مثلاً هر Command)، یک Strategy جدا تعریف میشود.
- یک کانتکست (اینجا: Message Handler) فقط تصمیم میگیرد کدام Strategy را صدا بزند.
- اضافه کردن Command جدید، بدون تغییر کدهای قبلی انجام میشود (Open/Closed Principle ✅).
نمونه با Python و کتابخانه python-telegram-bot:
from abc import ABC, abstractmethod
# Strategy interface
class CommandStrategy(ABC):
@abstractmethod
def handle(self, update, context):
pass
# Concrete strategies
class StartCommand(CommandStrategy):
def handle(self, update, context):
update.message.reply_text("سلام 👋 خوش اومدی!")
class HelpCommand(CommandStrategy):
def handle(self, update, context):
update.message.reply_text("/start - شروع
/help - راهنما")
class UnknownCommand(CommandStrategy):
def handle(self, update, context):
update.message.reply_text("این دستور رو نمیشناسم 😅")
# Context / Dispatcher
class CommandDispatcher:
def __init__(self):
self._strategies = {
"start": StartCommand(),
"help": HelpCommand(),
}
self._fallback = UnknownCommand()
def dispatch(self, update, context):
cmd = update.message.text.split()[0].replace("/", "")
strategy = self._strategies.get(cmd, self._fallback)
strategy.handle(update, context)
در Handler اصلی فقط کافیه Dispatcher را صدا بزنید و بقیهی منطق از هم جدا و تمیز میماند ✨
مزایا برای ربات تلگرام:
- افزودن Command جدید فقط با ساختن یک کلاس جدید (بدون دستزدن به بقیه کدها).
- تستنویسی راحتتر؛ هر Strategy مستقل تست میشود.
- جداسازی واضح بین لایهی Routing و لایهی Business Logic.
نکتههای عملی 🛠
- نام کلاسها را بر اساس Command شفاف انتخاب کنید (مثل
BanUserCommand، BroadcastCommand).- برای Commandهای پیچیده، آنها را به چند Service کوچکتر بشکنید تا Strategy هم بیش از حد چاق نشود.
- اگر تعداد Commandها زیاد شد، میتوانید Strategyها را در ماژولهای جدا (folders) سازماندهی کنید.
برای مطالعهی بیشتر دربارهی Strategy Pattern:
refactoring.guru/design-patterns/strategy
این الگو مخصوصاً در رباتهایی که بهمرور بزرگ میشوند کمک میکند ساختار کد تمیز، قابلگسترش و قابلنگهداری باقی بماند. از قدمهای کوچک شروع کنید و کمکم Commandهای فعلی را به Strategy تبدیل کنید 🚀
🔖 #TelegramBot #ربات #تلگرام #Strategy_Pattern #Clean_Code #Telegram_Bot #Python #Design_Patterns
👤 Developix
💎 Channel: @DevelopixRobot
❤1
اگر با Python ربات تلگرام میسازی، python-telegram-bot از راحتترین و پرکاربردترین کتابخونههاست 🤖
این لایبرری تقریباً کل Telegram Bot API رو پوشش میده و هم برای رباتهای ساده (reply معمولی) و هم رباتهای پیچیده (callback query، inline keyboard، webhook و …) جواب میده.
چیزهایی که جذابش میکنه:
• ساخت handler برای هر نوع آپدیت (message, command, callback)
• پشتیبانی خوب از async
• مدیریت راحت inline keyboard و custom keyboard
• مستندات قوی و community فعال
نصب و یک نمونه خیلی مینیمال با polling:
برای پروژههای جدیتر میشه از webhook و ساختار چندماژوله استفاده کرد تا کد تمیز و قابل نگهداری بمونه.
مستندات و سورس:
docs.python-telegram-bot.org
github.com/python-telegram-bot/python-telegram-bot
امتحانش کن روی یک ربات کوچک و بعد کمکم ساختار رو حرفهایتر کن 🚀
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #python_telegram_bot #Python #ربات_تلگرام #Webhook #Inline_Keyboard
👤 Developix
💎 Channel: @DevelopixRobot
این لایبرری تقریباً کل Telegram Bot API رو پوشش میده و هم برای رباتهای ساده (reply معمولی) و هم رباتهای پیچیده (callback query، inline keyboard، webhook و …) جواب میده.
چیزهایی که جذابش میکنه:
• ساخت handler برای هر نوع آپدیت (message, command, callback)
• پشتیبانی خوب از async
• مدیریت راحت inline keyboard و custom keyboard
• مستندات قوی و community فعال
نصب و یک نمونه خیلی مینیمال با polling:
pip install python-telegram-bot --upgrade
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
TOKEN = "YOUR_BOT_TOKEN"
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("سلام! 👋 ربات فعاله.")
app = ApplicationBuilder().token(TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.run_polling()
برای پروژههای جدیتر میشه از webhook و ساختار چندماژوله استفاده کرد تا کد تمیز و قابل نگهداری بمونه.
مستندات و سورس:
docs.python-telegram-bot.org
github.com/python-telegram-bot/python-telegram-bot
امتحانش کن روی یک ربات کوچک و بعد کمکم ساختار رو حرفهایتر کن 🚀
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #python_telegram_bot #Python #ربات_تلگرام #Webhook #Inline_Keyboard
👤 Developix
💎 Channel: @DevelopixRobot
👍4
🚀 ساخت ربات تلگرام با دکمههای شیشهای (Inline Keyboard) با Python
یه قابلیت خیلی کاربردی تو Telegram Bot اینه که کاربر لازم نیست چیزی تایپ کنه؛ فقط با زدن دکمه کار انجام میشه. دقیقاً همون inline keyboardهایی که زیر پیام ظاهر میشن ✅
توی این پست، با هم یه ربات ساده میسازیم که:
• با دستور
• زیرش دو تا دکمه شیشهای نشون میده
• روی هر دکمه کلیک بشه، جواب جداگانه برمیگردونه
این مثال بر اساس کتابخونهی رسمی و محبوب python-telegram-bot نسخه ۲۰ به بالاست و میتونی داک رسمیش رو اینجا ببینی:
docs.python-telegram-bot.org
اول کتابخونه رو نصب کن:
تو کد پایین فقط کافیه
چند نکته ریز ولی مهم 👇
• حتماً تو نسخههای جدید باید از
•
• به جای
این ساختار پایه بعداً راحت به Database، سیستم تیکت، فرم ثبت سفارش یا پنل ادمین در خود تلگرام وصل میشه 🙌
امتحانش کن، یه ربات بساز و به یه دوست برنامهنویس هم بفرست تا با هم توسعهش بدین 🤝
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #Python #Inline_Keyboard #Long_Polling #python_telegram_bot
👤 Developix
💎 Channel: @DevelopixRobot
یه قابلیت خیلی کاربردی تو Telegram Bot اینه که کاربر لازم نیست چیزی تایپ کنه؛ فقط با زدن دکمه کار انجام میشه. دقیقاً همون inline keyboardهایی که زیر پیام ظاهر میشن ✅
توی این پست، با هم یه ربات ساده میسازیم که:
• با دستور
/start یه پیام میفرسته• زیرش دو تا دکمه شیشهای نشون میده
• روی هر دکمه کلیک بشه، جواب جداگانه برمیگردونه
این مثال بر اساس کتابخونهی رسمی و محبوب python-telegram-bot نسخه ۲۰ به بالاست و میتونی داک رسمیش رو اینجا ببینی:
docs.python-telegram-bot.org
اول کتابخونه رو نصب کن:
pip install python-telegram-bot --upgrade
تو کد پایین فقط کافیه
BOT_TOKEN خودت رو از @BotFather بذاری و اجرا کنی. ربات روی long polling کار میکنه و نیاز به سرور https یا webhook نداره، برای شروع فوقالعادهست 👇from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import (
ApplicationBuilder,
CommandHandler,
CallbackQueryHandler,
ContextTypes,
)
BOT_TOKEN = "YOUR_BOT_TOKEN_HERE"
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
keyboard = [
[
InlineKeyboardButton("📊 وضعیت سرور", callback_data="status"),
InlineKeyboardButton("ℹ️ درباره ربات", callback_data="about"),
]
]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text(
"سلام 👋\nیکی از گزینههای زیر رو انتخاب کن:",
reply_markup=reply_markup,
)
async def button_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
query = update.callback_query
await query.answer()
if query.data == "status":
text = "سرور الان آنلاینه ✅\nCPU: 23% | RAM: 58%"
elif query.data == "about":
text = "این یه ربات نمونه با inline keyboard هست 🤖"
else:
text = "گزینه نامعتبر" # حالت پیشفرض
await query.edit_message_text(text)
if __name__ == "__main__":
app = ApplicationBuilder().token(BOT_TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CallbackQueryHandler(button_handler))
app.run_polling()
چند نکته ریز ولی مهم 👇
• حتماً تو نسخههای جدید باید از
async/await استفاده کنی، مثل کد بالا.•
callback_data بهتره کوتاه، بدون space و قابل پارس کردن باشه (مثلاً user:123 یا cmd:stats).• به جای
reply_text میتونی بعداً از edit_message_text تو خود دستور /start هم استفاده کنی تا ربات شبیه منوهای چند مرحلهای بشه.این ساختار پایه بعداً راحت به Database، سیستم تیکت، فرم ثبت سفارش یا پنل ادمین در خود تلگرام وصل میشه 🙌
امتحانش کن، یه ربات بساز و به یه دوست برنامهنویس هم بفرست تا با هم توسعهش بدین 🤝
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #Python #Inline_Keyboard #Long_Polling #python_telegram_bot
👤 Developix
💎 Channel: @DevelopixRobot
👍3
🎯 مدیریت آپدیتها با webhook بهجای long polling
وقتی ربات ترافیک بیشتری میگیرد، long polling میتواند هم کند شود هم مصرف منابع سرور را بالا ببرد. استفاده از webhook باعث میشود Telegram خودش آپدیتها را به آدرس سرور بفرستد؛ یعنی latency کمتر، مصرف CPU پایینتر و کنترل بهتر روی ترافیک 🚀
ایده ساده است: یک endpoint مثل
نمونه مینیمال با python-telegram-bot (نسخه 20+):
نکتههای مهم 🧩
• حتماً از HTTPS واقعی استفاده شود؛ Telegram روی http ساده به webhook وصل نمیشود.
• سایز پاسخها را کوچک نگه دار تا timeout نخوری.
• روی endpoint حتماً rate limit و لاگ مناسب داشته باش تا در برابر flood و خطاها مقاومت بهتری داشته باشی.
با همین تغییر ساده، ربات روی سرورهای سبک هم زیر فشار ترافیک پایدارتر میماند و هم پاسخها سریعتر به کاربر میرسد ⚡
مرجع رسمی Bot API:
https://core.telegram.org/bots/api#setwebhook
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #webhook #python_telegram_bot #performance #api
👤 Developix
💎 Channel: @DevelopixRobot
وقتی ربات ترافیک بیشتری میگیرد، long polling میتواند هم کند شود هم مصرف منابع سرور را بالا ببرد. استفاده از webhook باعث میشود Telegram خودش آپدیتها را به آدرس سرور بفرستد؛ یعنی latency کمتر، مصرف CPU پایینتر و کنترل بهتر روی ترافیک 🚀
ایده ساده است: یک endpoint مثل
/webhook روی سرور (مثلاً با Flask) میسازی، بعد با setWebhook به Telegram میگویی هر آپدیت جدید را POST کند به این URL.نمونه مینیمال با python-telegram-bot (نسخه 20+):
from flask import Flask, request
from telegram import Update
from telegram.ext import (
Application,
CommandHandler,
)
TOKEN = "YOUR_BOT_TOKEN"
app = Flask(__name__)
application = Application.builder().token(TOKEN).build()
async def start(update: Update, context):
await update.message.reply_text("سلام 👋")
application.add_handler(CommandHandler("start", start))
@app.post("/webhook")
def webhook():
update = Update.de_json(request.get_json(force=True), application.bot)
application.update_queue.put_nowait(update)
return "ok"
if __name__ == "__main__":
# فقط یک بار اجرا کن (یا با curl) برای ست کردن webhook
import requests
url = "https://your-domain.com/webhook"
requests.get(
f"https://api.telegram.org/bot{TOKEN}/setWebhook",
params={"url": url},
)
app.run(port=8443)
نکتههای مهم 🧩
• حتماً از HTTPS واقعی استفاده شود؛ Telegram روی http ساده به webhook وصل نمیشود.
• سایز پاسخها را کوچک نگه دار تا timeout نخوری.
• روی endpoint حتماً rate limit و لاگ مناسب داشته باش تا در برابر flood و خطاها مقاومت بهتری داشته باشی.
با همین تغییر ساده، ربات روی سرورهای سبک هم زیر فشار ترافیک پایدارتر میماند و هم پاسخها سریعتر به کاربر میرسد ⚡
مرجع رسمی Bot API:
https://core.telegram.org/bots/api#setwebhook
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #webhook #python_telegram_bot #performance #api
👤 Developix
💎 Channel: @DevelopixRobot
👍1
🧵 مدیریت آپدیتها با webhook بهجای long polling برای ربات شلوغ
وقتی ربات کاربران زیادی دارد، استفاده از getUpdates (همون long polling) میتونه هم کند بشه، هم منابع سرور رو الکی درگیر کنه. تو این شرایط، webhook انتخاب خیلی تمیزتر و پایدارتره. 🔧
ایده سادهست: بهجای اینکه ربات هر چند لحظه بره سراغ Telegram و بگه «آپدیت جدید داری؟»، خود Telegram هر آپدیت رو push میکنه به یک URL روی سرور شما.
✅ مزایا تو رباتهای تلگرام:
• مصرف کمتر CPU و پهنایباند روی سرور
• تاخیر کمتر در دریافت پیامها
• مدیریت راحتتر scale وقتی تعداد چتها زیاد میشه
یک نمونه خیلی مینیمال با python-telegram-bot (ورژن جدید async) و Flask:
نکات مهم امنیتی و عملی 🛡️
• حتما از HTTPS استفاده بشه (LetsEncrypt کافیه).
• URL وبهوک رو حدسزدنی انتخاب نشه (مثلاً یک path تصادفی طولانی).
• لاگ خطاها و timeoutهای وبهوک رو حتما چک بشه؛ اگر endpoint زیاد خطا بده، Telegram موقتاً ارسال آپدیتها رو کند میکنه.
برای جزییات کاملتر و پارامترهای
https://core.telegram.org/bots/api#setwebhook
امتحان این معماری روی رباتهای نسبتا شلوغ، تفاوت سرعت و مصرف منابع رو کاملا نشون میده 🚀
🔖 #TelegramBot #ربات #تلگرام #telegram_bot #webhook #python #performance #security
👤 Developix
💎 Channel: @DevelopixRobot
وقتی ربات کاربران زیادی دارد، استفاده از getUpdates (همون long polling) میتونه هم کند بشه، هم منابع سرور رو الکی درگیر کنه. تو این شرایط، webhook انتخاب خیلی تمیزتر و پایدارتره. 🔧
ایده سادهست: بهجای اینکه ربات هر چند لحظه بره سراغ Telegram و بگه «آپدیت جدید داری؟»، خود Telegram هر آپدیت رو push میکنه به یک URL روی سرور شما.
✅ مزایا تو رباتهای تلگرام:
• مصرف کمتر CPU و پهنایباند روی سرور
• تاخیر کمتر در دریافت پیامها
• مدیریت راحتتر scale وقتی تعداد چتها زیاد میشه
یک نمونه خیلی مینیمال با python-telegram-bot (ورژن جدید async) و Flask:
from flask import Flask, request
from telegram import Update
from telegram.ext import (
Application,
CommandHandler,
)
TOKEN = "YOUR_BOT_TOKEN"
WEBHOOK_URL = "https://example.com/telegram-webhook"
app = Flask(__name__)
application = Application.builder().token(TOKEN).build()
async def start(update: Update, context):
await update.message.reply_text("سلام 👋")
application.add_handler(CommandHandler("start", start))
@app.post("/telegram-webhook")
def webhook():
update = Update.de_json(request.get_json(force=True),
application.bot)
application.update_queue.put_nowait(update)
return "ok"
if __name__ == "__main__":
import asyncio
async def main():
await application.bot.set_webhook(WEBHOOK_URL)
app.run(host="0.0.0.0", port=8000)
asyncio.run(main())
نکات مهم امنیتی و عملی 🛡️
• حتما از HTTPS استفاده بشه (LetsEncrypt کافیه).
• URL وبهوک رو حدسزدنی انتخاب نشه (مثلاً یک path تصادفی طولانی).
• لاگ خطاها و timeoutهای وبهوک رو حتما چک بشه؛ اگر endpoint زیاد خطا بده، Telegram موقتاً ارسال آپدیتها رو کند میکنه.
برای جزییات کاملتر و پارامترهای
setWebhook، داک رسمی Bot API بهترین مرجعه:https://core.telegram.org/bots/api#setwebhook
امتحان این معماری روی رباتهای نسبتا شلوغ، تفاوت سرعت و مصرف منابع رو کاملا نشون میده 🚀
🔖 #TelegramBot #ربات #تلگرام #telegram_bot #webhook #python #performance #security
👤 Developix
💎 Channel: @DevelopixRobot
👍2
Anti-Corruption Layer در معماری ربات تلگرام 🧱
یکی از دردسرهای رباتهای جدی تلگرام این است که باید با سیستمهای قدیمی (Legacy) مثل CRM، ERP یا درگاههای قدیمی صحبت کنند. این سیستمها معمولاً API شلخته، نامگذاری بد یا ساختارهای عجیب دارند.
اینجاست که مفهوم واقعی و مهم Anti-Corruption Layer (ACL) از دنیای Domain-Driven Design وارد میشود. ACL یک لایه میانی است که اجازه نمیدهد شلختگی دنیای بیرون وارد مدل تمیز ربات شما شود. 🤝
به جای اینکه همه جای کد ربات پر از type و fieldهای سیستمهای بیرونی شود، فقط یک نقطه با آنها حرف میزند و آن نقطه مسئول تبدیل (Mapping) دادههاست.
ایدهٔ اصلی:
• ربات شما یک Domain Model تمیز دارد (User, Order, Subscription و ...)
• سیستم بیرونی ساختار خودش را دارد
• ACL دادهها را بین این دو دنیا تبدیل و ایزوله میکند
این کار:
• وابستگی به سیستمهای بیرونی را متمرکز میکند
• تغییر API بیرونی را کمهزینهتر میکند
• تستنویسی برای منطق ربات را سادهتر میکند ✅
مثال ساده با Python برای ربات تلگرام:
چند نکتهٔ عملی در رباتهای تلگرام:
• برای هر سیستم بیرونی (درگاه پرداخت، CRM، سرویس ارسال SMS) یک ACL جدا بسازید، نه اینکه همهچیز در Handlerها قاطی شود.
• mappingها را در یکجا نگه دارید؛ مثلاً تبدیل statusهای پرداخت خارجی به enumهای داخلی.
• هر وقت API بیرونی عوض شد، فقط ACL را دستکاری کنید، نه تمام منطق ربات را.
منبع برای مطالعه بیشتر:
Martin Fowler - Anti-Corruption Layer
این الگو کمک میکند حتی اگر دنیای بیرون نامرتب است، معماری ربات شما تمیز، قابلتست و قابلگسترش بماند. 🌱
🔖 #TelegramBot #ربات #تلگرام #Anti_Corruption_Layer #Architecture #Telegram_Bot #Python #DDD #Clean_Code
👤 Developix
💎 Channel: @DevelopixRobot
یکی از دردسرهای رباتهای جدی تلگرام این است که باید با سیستمهای قدیمی (Legacy) مثل CRM، ERP یا درگاههای قدیمی صحبت کنند. این سیستمها معمولاً API شلخته، نامگذاری بد یا ساختارهای عجیب دارند.
اینجاست که مفهوم واقعی و مهم Anti-Corruption Layer (ACL) از دنیای Domain-Driven Design وارد میشود. ACL یک لایه میانی است که اجازه نمیدهد شلختگی دنیای بیرون وارد مدل تمیز ربات شما شود. 🤝
به جای اینکه همه جای کد ربات پر از type و fieldهای سیستمهای بیرونی شود، فقط یک نقطه با آنها حرف میزند و آن نقطه مسئول تبدیل (Mapping) دادههاست.
ایدهٔ اصلی:
• ربات شما یک Domain Model تمیز دارد (User, Order, Subscription و ...)
• سیستم بیرونی ساختار خودش را دارد
• ACL دادهها را بین این دو دنیا تبدیل و ایزوله میکند
این کار:
• وابستگی به سیستمهای بیرونی را متمرکز میکند
• تغییر API بیرونی را کمهزینهتر میکند
• تستنویسی برای منطق ربات را سادهتر میکند ✅
مثال ساده با Python برای ربات تلگرام:
class DomainUser:
def __init__(self, id, full_name, is_vip):
self.id = id
self.full_name = full_name
self.is_vip = is_vip
# Gateway سیستم قدیمی (مثال REST خام)
class LegacyCrmClient:
def get_user(self, chat_id: int) -> dict:
# در عمل اینجا requests.get و ... دارید
return {
"contact_id": chat_id,
"fname": "Ali",
"lname": "Ahmadi",
"segment": "gold", # یا basic, silver
}
# Anti-Corruption Layer
class CrmAcl:
def __init__(self, client: LegacyCrmClient):
self._client = client
def get_domain_user(self, chat_id: int) -> DomainUser:
raw = self._client.get_user(chat_id)
full_name = f"{raw['fname']} {raw['lname']}"
is_vip = raw["segment"] in ["gold", "platinum"]
return DomainUser(
id=raw["contact_id"],
full_name=full_name,
is_vip=is_vip,
)
# استفاده در Handler ربات
crm_acl = CrmAcl(LegacyCrmClient())
def handle_start(update, context):
user = crm_acl.get_domain_user(update.effective_chat.id)
if user.is_vip:
context.bot.send_message(
chat_id=user.id,
text=f"خوش اومدی {user.full_name} 🌟"
)
else:
context.bot.send_message(
chat_id=user.id,
text=f"سلام {user.full_name}!"
)
چند نکتهٔ عملی در رباتهای تلگرام:
• برای هر سیستم بیرونی (درگاه پرداخت، CRM، سرویس ارسال SMS) یک ACL جدا بسازید، نه اینکه همهچیز در Handlerها قاطی شود.
• mappingها را در یکجا نگه دارید؛ مثلاً تبدیل statusهای پرداخت خارجی به enumهای داخلی.
• هر وقت API بیرونی عوض شد، فقط ACL را دستکاری کنید، نه تمام منطق ربات را.
منبع برای مطالعه بیشتر:
Martin Fowler - Anti-Corruption Layer
این الگو کمک میکند حتی اگر دنیای بیرون نامرتب است، معماری ربات شما تمیز، قابلتست و قابلگسترش بماند. 🌱
🔖 #TelegramBot #ربات #تلگرام #Anti_Corruption_Layer #Architecture #Telegram_Bot #Python #DDD #Clean_Code
👤 Developix
💎 Channel: @DevelopixRobot
کتابخونهٔ python-telegram-bot یکی از محبوبترین ابزارها برای ساخت ربات تلگرام با Python هست. اگر حوصلهٔ کار مستقیم با HTTP و API خام تلگرام رو نداری، این لایبرری خیلی از دردسرها رو جمع میکنه 🧩
چند تا مزیت مهم:
• پشتیبانی کامل از Bot API
• پشتیبانی هم از polling هم webhook
• ساخت راحت inline keyboard و reply keyboard
• سیستم handler ها برای مرتب نگه داشتن کد
نمونهٔ سادهٔ ربات
برای پروژههای جدی هم ساختن ساختار تمیز با handler ها و استفاده از webhook روی سرور خیلی راحت میشه. پیشنهاد میشه مستنداتش رو یک بار کامل اسکن کنی و با مثالهاش جلو بری 🚀
Docs | GitHub
🔖 #TelegramBot #ربات #تلگرام #python_telegram_bot #Python #Telegram_Bot #ربات_تلگرام #Webhook #Inline_Keyboard
👤 Developix
💎 Channel: @DevelopixRobot
چند تا مزیت مهم:
• پشتیبانی کامل از Bot API
• پشتیبانی هم از polling هم webhook
• ساخت راحت inline keyboard و reply keyboard
• سیستم handler ها برای مرتب نگه داشتن کد
نمونهٔ سادهٔ ربات
/start:pip install python-telegram-bot==21.6
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("سلام، ربات آنلاینه ✌️")
app = ApplicationBuilder().token("BOT_TOKEN").build()
app.add_handler(CommandHandler("start", start))
app.run_polling()
برای پروژههای جدی هم ساختن ساختار تمیز با handler ها و استفاده از webhook روی سرور خیلی راحت میشه. پیشنهاد میشه مستنداتش رو یک بار کامل اسکن کنی و با مثالهاش جلو بری 🚀
Docs | GitHub
🔖 #TelegramBot #ربات #تلگرام #python_telegram_bot #Python #Telegram_Bot #ربات_تلگرام #Webhook #Inline_Keyboard
👤 Developix
💎 Channel: @DevelopixRobot
👍1
Circuit Breaker در رباتهای تلگرام ⚡️🛡
خیلی وقتها ربات تلگرام ما به یک سرویس خارجی (مثلاً پرداخت، هوش مصنوعی، یا API داخلی شرکت) وابسته است. وقتی آن سرویس کند یا داون میشود، ربات هم کند میشود، Timeout میدهد و تجربه کاربر نابود میشود.
یکی از الگوهای معماری که اینجا واقعاً نجاتدهنده است، Circuit Breaker Pattern است.
ایدهٔ اصلی:
مثل فیوز برق عمل میکند؛ اگر درخواستهای پشتسرهم به سرویس خراب شوند، «مدار» را قطع میکند و موقتاً دیگر درخواست به آن سرویس نمیفرستد. بهجایش:
• سریع جواب fallback میدهد ⚙️
• از شلوغتر شدن سرویس خراب جلوگیری میکند 🚫
• ربات شما Responsive باقی میماند ✅
سه حالت اصلی:
• Closed: همهچیز اوکی است، درخواستها مستقیم میروند.
• Open: خطای زیاد؛ مدار قطع میشود، دیگر درخواست مستقیم نمیرود.
• Half-Open: هر چند ثانیه چند درخواست تستی میفرستد؛ اگر موفق شد، برمیگردد به Closed.
نمونه ساده در Python برای ربات تلگرام:
استفاده در هندلر پیام:
نکات کاربردی برای رباتهای تلگرام:
• برای هر سرویس حساس (پرداخت، AI، CRM) یک Circuit Breaker جدا نگهدارید.
• لاگ بگیرید تا بدانید کی مدار Open شده است.
• همراه Circuit Breaker، از Retry با Backoff هم استفاده کنید.
بهکمک Circuit Breaker رباتتان حتی وقتی سرویسهای بیرونی مشکل دارند، همچنان پایدار و قابلاعتماد میماند 💪
🔖 #TelegramBot #ربات #تلگرام #Circuit_Breaker #Resilience #Telegram_Bot #Python #Architecture #Pattern
👤 Developix
💎 Channel: @DevelopixRobot
خیلی وقتها ربات تلگرام ما به یک سرویس خارجی (مثلاً پرداخت، هوش مصنوعی، یا API داخلی شرکت) وابسته است. وقتی آن سرویس کند یا داون میشود، ربات هم کند میشود، Timeout میدهد و تجربه کاربر نابود میشود.
یکی از الگوهای معماری که اینجا واقعاً نجاتدهنده است، Circuit Breaker Pattern است.
ایدهٔ اصلی:
مثل فیوز برق عمل میکند؛ اگر درخواستهای پشتسرهم به سرویس خراب شوند، «مدار» را قطع میکند و موقتاً دیگر درخواست به آن سرویس نمیفرستد. بهجایش:
• سریع جواب fallback میدهد ⚙️
• از شلوغتر شدن سرویس خراب جلوگیری میکند 🚫
• ربات شما Responsive باقی میماند ✅
سه حالت اصلی:
• Closed: همهچیز اوکی است، درخواستها مستقیم میروند.
• Open: خطای زیاد؛ مدار قطع میشود، دیگر درخواست مستقیم نمیرود.
• Half-Open: هر چند ثانیه چند درخواست تستی میفرستد؛ اگر موفق شد، برمیگردد به Closed.
نمونه ساده در Python برای ربات تلگرام:
import time
import requests
class CircuitBreaker:
def __init__(self, failure_threshold=3, reset_timeout=10):
self.failure_threshold = failure_threshold
self.reset_timeout = reset_timeout
self.failures = 0
self.state = 'CLOSED'
self.last_failure_time = 0
def call(self, func, fallback, *args, **kwargs):
if self.state == 'OPEN':
if time.time() - self.last_failure_time > self.reset_timeout:
self.state = 'HALF_OPEN'
else:
return fallback()
try:
result = func(*args, **kwargs)
self.failures = 0
self.state = 'CLOSED'
return result
except Exception:
self.failures += 1
self.last_failure_time = time.time()
if self.failures >= self.failure_threshold:
self.state = 'OPEN'
return fallback()
cb = CircuitBreaker()
استفاده در هندلر پیام:
def call_ai_service(text):
return requests.post('https://api.example.com/ai', json={'q': text}).json()
def ai_fallback():
return {'answer': 'سرویس هوش مصنوعی موقتاً در دسترس نیست 😔'}
# داخل هندلر ربات
response = cb.call(call_ai_service, ai_fallback, message.text)
bot.send_message(chat_id, response['answer'])
نکات کاربردی برای رباتهای تلگرام:
• برای هر سرویس حساس (پرداخت، AI، CRM) یک Circuit Breaker جدا نگهدارید.
• لاگ بگیرید تا بدانید کی مدار Open شده است.
• همراه Circuit Breaker، از Retry با Backoff هم استفاده کنید.
بهکمک Circuit Breaker رباتتان حتی وقتی سرویسهای بیرونی مشکل دارند، همچنان پایدار و قابلاعتماد میماند 💪
🔖 #TelegramBot #ربات #تلگرام #Circuit_Breaker #Resilience #Telegram_Bot #Python #Architecture #Pattern
👤 Developix
💎 Channel: @DevelopixRobot
👍5
🤖 ساخت ربات آزمون چهارگزینهای در تلگرام با Python
تو خیلی از کانالها و گروهها، رباتهایی میبینی که آزمون چهارگزینهای (Quiz) برگزار میکنن، امتیاز میدن و حتی جواب درست رو هم نشون میدن. امروز با هم یک نسخه ساده و عملی از همین ایده رو با Python و کتابخونهٔ pyTelegramBotAPI میسازیم 😎
ایده اینه:
• کاربر /quiz رو میفرسته.
• ربات یک سوال چهارگزینهای با دکمههای Inline میفرسته.
• با کلیک روی گزینه، ربات میگه درست بود یا غلط.
این مدل ربات برای کوییزهای آموزشی، آزمون زبان، تمرین الگوریتم و حتی سرگرمی توی گروهها عالیه.
این کد رو براساس داکیومنت رسمی Bot API و کتابخونهٔ pyTelegramBotAPI نوشتیم و روی BotFather معمولی کاملاً جواب میده ✅
اول با pip نصب کن:
سپس یک فایل مثل
چند نکتهٔ ریز ولی مهم 👇
• حتماً توکن واقعی ربات رو جایگزین
• اگر روی سرور با محدودیت Network هستی، ممکنه نیاز بشه بجای
• میتونی لیست
امتحانش کن، روی چندتا دوستت تست بگیر و بعد کمکم امکاناتی مثل نمرهدهی، رتبهبندی و زمانبندی آزمون رو بهش اضافه کن 🚀
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #Python #pyTelegramBotAPI #Quiz_Bot #InlineKeyboard
👤 Developix
💎 Channel: @DevelopixRobot
تو خیلی از کانالها و گروهها، رباتهایی میبینی که آزمون چهارگزینهای (Quiz) برگزار میکنن، امتیاز میدن و حتی جواب درست رو هم نشون میدن. امروز با هم یک نسخه ساده و عملی از همین ایده رو با Python و کتابخونهٔ pyTelegramBotAPI میسازیم 😎
ایده اینه:
• کاربر /quiz رو میفرسته.
• ربات یک سوال چهارگزینهای با دکمههای Inline میفرسته.
• با کلیک روی گزینه، ربات میگه درست بود یا غلط.
این مدل ربات برای کوییزهای آموزشی، آزمون زبان، تمرین الگوریتم و حتی سرگرمی توی گروهها عالیه.
این کد رو براساس داکیومنت رسمی Bot API و کتابخونهٔ pyTelegramBotAPI نوشتیم و روی BotFather معمولی کاملاً جواب میده ✅
اول با pip نصب کن:
pip install pyTelegramBotAPI
سپس یک فایل مثل
quiz_bot.py بساز و این کد رو داخلش بذار (توکن رو از BotFather بردار و جایگزین کن):import telebot
from telebot import types
API_TOKEN = "YOUR_BOT_TOKEN_HERE"
bot = telebot.TeleBot(API_TOKEN)
# یک سوال نمونه
QUESTION = "کدام زبان برای توسعه ربات تلگرام در این مثال استفاده شده است؟"
OPTIONS = ["Java", "Python", "PHP", "Go"]
CORRECT_INDEX = 1 # Python
@bot.message_handler(commands=["start"])
def send_welcome(message):
bot.reply_to(message, "سلام! برای شروع آزمون دستور /quiz رو بفرست ✅")
@bot.message_handler(commands=["quiz"])
def send_quiz(message):
keyboard = types.InlineKeyboardMarkup()
for i, option in enumerate(OPTIONS):
btn = types.InlineKeyboardButton(
text=option,
callback_data=f"quiz_{i}"
)
keyboard.add(btn)
bot.send_message(
message.chat.id,
QUESTION,
reply_markup=keyboard
)
@bot.callback_query_handler(func=lambda call: call.data.startswith("quiz_"))
def handle_quiz_answer(call):
index = int(call.data.split("_")[1])
if index == CORRECT_INDEX:
text = "آفرین 🎉 جواب درست بود (Python)."
else:
correct_option = OPTIONS[CORRECT_INDEX]
text = f"❌ نه! جواب درست: {correct_option}"
# پاسخ به همون پیام
bot.answer_callback_query(call.id, text, show_alert=True)
if __name__ == "__main__":
print("Quiz bot is running...")
bot.infinity_polling()
چند نکتهٔ ریز ولی مهم 👇
• حتماً توکن واقعی ربات رو جایگزین
YOUR_BOT_TOKEN_HERE کن.• اگر روی سرور با محدودیت Network هستی، ممکنه نیاز بشه بجای
infinity_polling() از webhook استفاده کنی (طبق داک رسمی: setWebhook).• میتونی لیست
OPTIONS و متن QUESTION رو از یک فایل JSON یا دیتابیس بخونی تا رباتت چندین سوال پشتسرهم بپرسه.امتحانش کن، روی چندتا دوستت تست بگیر و بعد کمکم امکاناتی مثل نمرهدهی، رتبهبندی و زمانبندی آزمون رو بهش اضافه کن 🚀
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #Python #pyTelegramBotAPI #Quiz_Bot #InlineKeyboard
👤 Developix
💎 Channel: @DevelopixRobot
👍3👎1
Idempotency در Webhook ربات تلگرام چیه؟ 🔁
یکی از مشکلهای رایج تو رباتهای تلگرام اینه که یه آپدیت چند بار پردازش میشه؛ مخصوصاً وقتی:
• سرور delay داره ⏳
• ngrok / proxy قطع و وصل میشه
• خودت retry برای requestهات گذاشتی
اینجاست که مفهوم Idempotency نجاتت میده؛ یعنی اجرای چندبارهٔ یه عملیات، اثر اضافهای نسبت به بار اول نداشته باشه. ✅
در ربات تلگرام، بهترین candidate برای Idempotency همون update_id هر پیام یا callback هست.
ایدهٔ اصلی:
1️⃣ هر
2️⃣ اگر دوباره همون
یه پیادهسازی ساده با Python + Redis 🐍
نکات مهم در عمل 🚀
• TTL مناسب بذار؛ معمولاً چند دقیقه برای
• تو عملیات حساس مثل پرداخت، حتماً Idempotency رو تا لایهٔ دیتابیس ادامه بده (مثلاً با unique index روی
• اگر از getUpdates هم استفاده میکنی، باز همین منطق برای safety بیشتر مفیده.
• تو jobهای async یا queueهات (مثل Celery, RQ) هم
پیادهسازی درست Idempotency تو Webhook جلوی کلی باگ عجیبی مثل برداشت دوباره، ثبت تکراری سفارش و ارسال چندبارهٔ پیام رو میگیره و رباتت رو حسابی قابلاعتمادتر میکنه ✨
از همین امروز تو لایهٔ Webhook رباتت این الگو رو اضافه کن و ذهنت رو از ترس retryها خلاص کن. 😄
🔖 #TelegramBot #ربات #تلگرام #Idempotency #Telegram_Bot #Webhook #Python #Redis #Clean_Code #Robustness
👤 Developix
💎 Channel: @DevelopixRobot
یکی از مشکلهای رایج تو رباتهای تلگرام اینه که یه آپدیت چند بار پردازش میشه؛ مخصوصاً وقتی:
• سرور delay داره ⏳
• ngrok / proxy قطع و وصل میشه
• خودت retry برای requestهات گذاشتی
اینجاست که مفهوم Idempotency نجاتت میده؛ یعنی اجرای چندبارهٔ یه عملیات، اثر اضافهای نسبت به بار اول نداشته باشه. ✅
در ربات تلگرام، بهترین candidate برای Idempotency همون update_id هر پیام یا callback هست.
ایدهٔ اصلی:
1️⃣ هر
update_id رو فقط یه بار قبول کن.2️⃣ اگر دوباره همون
update_id رسید، بهجای دوباره انجام دادن کار (مثلاً برداشت از کیف پول کاربر)، فقط نتیجهٔ قبلی رو برگردون یا بیصدا ignore کن.یه پیادهسازی ساده با Python + Redis 🐍
import time
import redis
from flask import Flask, request
r = redis.Redis(host="localhost", port=6379, db=0)
app = Flask(__name__)
IDEMPOTENCY_TTL = 60 * 5 # 5 دقیقه
@app.post("/webhook")
def telegram_webhook():
update = request.get_json(force=True)
update_id = update.get("update_id")
if update_id is None:
return "ok" # ورودی نامعتبر، بیصدا رد میکنیم
cache_key = f"tg:update:{update_id}"
# اگر قبلاً پردازش شده، دوباره انجام نده
if r.exists(cache_key):
return "ok" # idempotent پاسخ
# قفل سبک برای این update
with r.lock(f"lock:{cache_key}", timeout=5):
if r.exists(cache_key):
return "ok"
handle_update(update)
# علامتگذاری بهعنوان پردازششده
r.setex(cache_key, IDEMPOTENCY_TTL, int(time.time()))
return "ok"
def handle_update(update: dict) -> None:
message = update.get("message", {})
text = message.get("text", "")
chat_id = message.get("chat", {}).get("id")
if text == "/start":
send_welcome(chat_id)
def send_welcome(chat_id: int) -> None:
# اینجا فراخوانی sendMessage به Bot API رو انجام بده
...
نکات مهم در عمل 🚀
• TTL مناسب بذار؛ معمولاً چند دقیقه برای
update_id ها کافیه.• تو عملیات حساس مثل پرداخت، حتماً Idempotency رو تا لایهٔ دیتابیس ادامه بده (مثلاً با unique index روی
update_id یا invoice_id).• اگر از getUpdates هم استفاده میکنی، باز همین منطق برای safety بیشتر مفیده.
• تو jobهای async یا queueهات (مثل Celery, RQ) هم
update_id یا یه idempotency key اختصاصی حمل کن.پیادهسازی درست Idempotency تو Webhook جلوی کلی باگ عجیبی مثل برداشت دوباره، ثبت تکراری سفارش و ارسال چندبارهٔ پیام رو میگیره و رباتت رو حسابی قابلاعتمادتر میکنه ✨
از همین امروز تو لایهٔ Webhook رباتت این الگو رو اضافه کن و ذهنت رو از ترس retryها خلاص کن. 😄
🔖 #TelegramBot #ربات #تلگرام #Idempotency #Telegram_Bot #Webhook #Python #Redis #Clean_Code #Robustness
👤 Developix
💎 Channel: @DevelopixRobot
👍3
🎯 ریپلای تمیز توی ربات: همیشه از
وقتی ربات توی گروهها شلوغ میشود، مهم است جواب هر کاربر دقیقاً زیر پیام خودش بیاید؛ مخصوصاً وقتی چند نفر همزمان از ربات استفاده میکنند. بهجای اینکه فقط به chat تکیه شود، بهتر است همیشه از فیلد
نمونه با Python و
این کار توی گروهها و سوپرگروهها:
• 📌 جریان گفتگو را واضح نگه میدارد.
• 🚫 احتمال اشتباه یا سوتفاهم را کم میکند.
• 💬 مخصوصاً برای رباتهای پشتیبانی، Quiz یا Ticket خیلی حیاتی است.
موقع ارسال پیام با
🔗 مستند رسمی: Telegram Bot API – sendMessage
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #reply_to_message_id #python_telegram_bot #group_bots #conversation
👤 Developix
💎 Channel: @DevelopixRobot
reply_to_message_id استفاده کنوقتی ربات توی گروهها شلوغ میشود، مهم است جواب هر کاربر دقیقاً زیر پیام خودش بیاید؛ مخصوصاً وقتی چند نفر همزمان از ربات استفاده میکنند. بهجای اینکه فقط به chat تکیه شود، بهتر است همیشه از فیلد
reply_to_message_id استفاده شود تا رشتهٔ گفتگو مرتب بماند. 😉نمونه با Python و
python-telegram-bot (v20+):from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
msg = update.effective_message
await msg.reply_text(
"سلام 👋\nدر چه کاری کمک میکنم؟",
reply_to_message_id=msg.message_id
)
app = ApplicationBuilder().token("YOUR_TOKEN").build()
app.add_handler(CommandHandler("start", start))
app.run_polling()
این کار توی گروهها و سوپرگروهها:
• 📌 جریان گفتگو را واضح نگه میدارد.
• 🚫 احتمال اشتباه یا سوتفاهم را کم میکند.
• 💬 مخصوصاً برای رباتهای پشتیبانی، Quiz یا Ticket خیلی حیاتی است.
موقع ارسال پیام با
sendMessage در Bot API خام هم کافی است همیشه reply_to_message_id را با message_id پیام کاربر ست کنی.🔗 مستند رسمی: Telegram Bot API – sendMessage
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #reply_to_message_id #python_telegram_bot #group_bots #conversation
👤 Developix
💎 Channel: @DevelopixRobot
👍1👎1
Command Pattern در معماری ربات تلگرام 🚀
یکی از الگوهای خیلی کاربردی برای تمیز نگه داشتن کد ربات، مخصوصاً وقتی تعداد دستورات زیاد میشود، Command Pattern است.
بهجای اینکه داخل یک فایل بزرگ با کلی
✅ کد را خواناتر و قابل نگهداریتر میکند
✅ اضافه کردن دستور جدید را ساده و بدون دستکاری منطق قبلی میکند
✅ تستنویسی برای هر دستور را راحتتر میکند
ایدهٔ اصلی Command Pattern 🧠
هر دستور (مثلاً
یک «Command Bus» یا «Dispatcher» فقط تشخیص میدهد کاربر چه دستوری داده و Command مناسب را صدا میزند؛ خودش منطق دستور را بلد نیست.
نمونهٔ ساده در ربات تلگرام (python-telegram-bot) 🐍
چند نکتهٔ عملی برای رباتهای واقعی 🛠
• برای هر Command میتوان وابستگیها را تزریق کرد (Repository، Service، Logger) تا کلاسها تمیز و تستپذیر بمانند.
• وقتی تعداد Command ها زیاد شد، میتوان ثبت آنها را بهصورت داینامیک (مثلاً با اسکن ماژولها) انجام داد تا دیگر یک دیکشنری بزرگ دستی نگه نداریم.
• در کنار Command Pattern، استفاده از Single Responsibility Principle کمک میکند منطق ربات از منطق زیرساخت (HTTP, DB, Cache) جدا بماند.
برای مطالعهٔ بیشتر دربارهٔ این الگو:
refactoring.guru/design-patterns/command
قدمبهقدم که رباتتان بزرگتر میشود، استفاده از Command Pattern کمک میکند معماری کد تمیز بماند و با خیال راحت فیچرهای جدید اضافه کنید ✨
🔖 #TelegramBot #ربات #تلگرام #Command_Pattern #Telegram_Bot #Clean_Code #Python #Design_Patterns #Software_Architecture
👤 Developix
💎 Channel: @DevelopixRobot
یکی از الگوهای خیلی کاربردی برای تمیز نگه داشتن کد ربات، مخصوصاً وقتی تعداد دستورات زیاد میشود، Command Pattern است.
بهجای اینکه داخل یک فایل بزرگ با کلی
if/elif همهٔ دستورها را هندل کنیم، هر دستور را بهصورت یک «Command» جداگانه پیادهسازی میکنیم. این کار:✅ کد را خواناتر و قابل نگهداریتر میکند
✅ اضافه کردن دستور جدید را ساده و بدون دستکاری منطق قبلی میکند
✅ تستنویسی برای هر دستور را راحتتر میکند
ایدهٔ اصلی Command Pattern 🧠
هر دستور (مثلاً
/start، /help، /stats) تبدیل میشود به یک کلاس با یک متد ثابت، مثلاً execute().یک «Command Bus» یا «Dispatcher» فقط تشخیص میدهد کاربر چه دستوری داده و Command مناسب را صدا میزند؛ خودش منطق دستور را بلد نیست.
نمونهٔ ساده در ربات تلگرام (python-telegram-bot) 🐍
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
class BaseCommand:
async def execute(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
raise NotImplementedError
class StartCommand(BaseCommand):
async def execute(self, update, context):
await update.message.reply_text("سلام 👋 خوش اومدی!")
class HelpCommand(BaseCommand):
async def execute(self, update, context):
await update.message.reply_text("لیست دستورات: /start, /help")
class CommandDispatcher:
def __init__(self):
self._commands = {
"start": StartCommand(),
"help": HelpCommand(),
}
async def handle(self, update, context):
name = update.message.text.lstrip("/").split()[0]
cmd = self._commands.get(name)
if cmd:
await cmd.execute(update, context)
dispatcher = CommandDispatcher()
async def entrypoint(update: Update, context: ContextTypes.DEFAULT_TYPE):
await dispatcher.handle(update, context)
app = ApplicationBuilder().token("TOKEN").build()
app.add_handler(CommandHandler(["start", "help"], entrypoint))
app.run_polling()
چند نکتهٔ عملی برای رباتهای واقعی 🛠
• برای هر Command میتوان وابستگیها را تزریق کرد (Repository، Service، Logger) تا کلاسها تمیز و تستپذیر بمانند.
• وقتی تعداد Command ها زیاد شد، میتوان ثبت آنها را بهصورت داینامیک (مثلاً با اسکن ماژولها) انجام داد تا دیگر یک دیکشنری بزرگ دستی نگه نداریم.
• در کنار Command Pattern، استفاده از Single Responsibility Principle کمک میکند منطق ربات از منطق زیرساخت (HTTP, DB, Cache) جدا بماند.
برای مطالعهٔ بیشتر دربارهٔ این الگو:
refactoring.guru/design-patterns/command
قدمبهقدم که رباتتان بزرگتر میشود، استفاده از Command Pattern کمک میکند معماری کد تمیز بماند و با خیال راحت فیچرهای جدید اضافه کنید ✨
🔖 #TelegramBot #ربات #تلگرام #Command_Pattern #Telegram_Bot #Clean_Code #Python #Design_Patterns #Software_Architecture
👤 Developix
💎 Channel: @DevelopixRobot
❤5👎1
💠 نسخه جدید کتابخانه آیوگرام (Aiogram) منتشر شده است
🔸 ارتقا از نسخه 3.29.1 به 3.30.0
🔖 #aiogram, #bot, #python, #release
💎 @DevelopixRobot
🔸 ارتقا از نسخه 3.29.1 به 3.30.0
🔖 #aiogram, #bot, #python, #release
💎 @DevelopixRobot
👍1
🚀 ربات سریعتر با استفاده از Webhook بهجای getUpdates
خیلی از رباتها هنوز با Polling و متد
راه بهتر توی Production استفاده از Webhook است؛ Telegram هر آپدیت را مستقیم به آدرس HTTPS سرور میفرستد، بدون Loop و Delay اضافه 👍
نمونه تنظیم Webhook با
نکته مهم 🔐: حتما از HTTPS معتبر استفاده شود و
مرجع رسمی: Telegram Bot API – setWebhook
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #Webhook #Performance #python_telegram_bot #Security
👤 Developix
💎 Channel: @DevelopixRobot
خیلی از رباتها هنوز با Polling و متد
getUpdates کار میکنند و هر چند صد میلیثانیه یکبار سر میزنند ببینند پیام جدیدی آمده یا نه. این کار هم تاخیر را بالا میبرد، هم روی سرور و هم روی Telegram بار اضافه میاندازد.راه بهتر توی Production استفاده از Webhook است؛ Telegram هر آپدیت را مستقیم به آدرس HTTPS سرور میفرستد، بدون Loop و Delay اضافه 👍
نمونه تنظیم Webhook با
python-telegram-bot:from telegram.ext import Application, CommandHandler
TOKEN = "YOUR_BOT_TOKEN"
app = Application.builder().token(TOKEN).build()
async def start(update, context):
await update.message.reply_text("سلام 👋")
app.add_handler(CommandHandler("start", start))
app.run_webhook(
listen="0.0.0.0",
port=8443,
url_path=TOKEN,
webhook_url=f"https://example.com/{TOKEN}"
)
نکته مهم 🔐: حتما از HTTPS معتبر استفاده شود و
url_path را تصادفی و غیرقابل حدس انتخاب کن تا اسکنهای ساده به ربات نرسند.مرجع رسمی: Telegram Bot API – setWebhook
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #Webhook #Performance #python_telegram_bot #Security
👤 Developix
💎 Channel: @DevelopixRobot
👍1
✏️ ویرایش پیام ربات بهجای ارسال پیامهای تکراری
خیلی وقتها ربات برای «وضعیت پردازش»، «نتایج جستجو» یا «پیغام لودینگ» پشت سر هم پیام جدید میفرستد و چت را شلوغ میکند. یک ترفند ساده این است که بهجای پیامهای جدید، همان پیام قبلی را با
✅ مزیتها:
• چت تمیزتر و حرفهایتر ✨
• مصرف کمتر quota و ترافیک
• تجربه کاربری خیلی روانتر
مثال با Python و python-telegram-bot:
نکته 👇
برای ویرایش، باید
📚 داک رسمی:
EditMessageText - Telegram Bot API
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #editMessageText #Python #UX #Chat_Cleanliness #Performance
👤 Developix
💎 Channel: @DevelopixRobot
خیلی وقتها ربات برای «وضعیت پردازش»، «نتایج جستجو» یا «پیغام لودینگ» پشت سر هم پیام جدید میفرستد و چت را شلوغ میکند. یک ترفند ساده این است که بهجای پیامهای جدید، همان پیام قبلی را با
editMessageText آپدیت کنی. 😉✅ مزیتها:
• چت تمیزتر و حرفهایتر ✨
• مصرف کمتر quota و ترافیک
• تجربه کاربری خیلی روانتر
مثال با Python و python-telegram-bot:
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
msg = await update.message.reply_text("در حال پردازش...")
# ... کد پردازش ...
await msg.edit_text("✅ نتیجه آماده شد!")
app = ApplicationBuilder().token("YOUR_TOKEN").build()
app.add_handler(CommandHandler("start", start))
app.run_polling()
نکته 👇
برای ویرایش، باید
message_id همان پیام قبلی را داشته باشی (در مثال بالا همون msg). اگر پیام قدیمی خیلی وقت پیش ارسال شده باشد یا کاربر آن را حذف کرده باشد، API خطا برمیگرداند؛ بهتر است خطا را لاگ و هندل کنی.📚 داک رسمی:
EditMessageText - Telegram Bot API
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #editMessageText #Python #UX #Chat_Cleanliness #Performance
👤 Developix
💎 Channel: @DevelopixRobot
💠 نسخه جدید کتابخانه آیوگرام (Aiogram) منتشر شده است
🔸 ارتقا از نسخه 3.30.0 به 3.31.0
🔖 #aiogram, #bot, #python, #release
💎 @DevelopixRobot
🔸 ارتقا از نسخه 3.30.0 به 3.31.0
🔖 #aiogram, #bot, #python, #release
💎 @DevelopixRobot
👍1
خیلی وقتها ربات لینک میفرستد، اما پیشنمایش بزرگ صفحه کل کل چت را شلوغ میکند 😅 مخصوصاً برای پیامهای سیستمی یا دکمهدار.
با استفاده از پارامتر
مثال با Bot API مستقیم:
مثال با کتابخانه
نکتهها ✨
• برای پیامهای اطلاعرسانی، دکمهای و لاگها، تقریباً همیشه گزینه بهتری است.
• برای لینکهای محتوایی (مقاله، ویدئو) فقط در صورت نیاز خاموش شود تا کاربر پیشنمایش را از دست ندهد.
بار بعد که ربات لینک فرستاد و چت شلوغ شد، یک بار این گزینه را تست کن 😉
منبع رسمی: Telegram Bot API - sendMessage
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #disable_web_page_preview #sendMessage #python_telegram_bot #UX
👤 Developix
💎 Channel: @DevelopixRobot
با استفاده از پارامتر
disable_web_page_preview در متد sendMessage میتوان پیشنمایش را خاموش کرد تا چت تمیز و فشرده بماند ✅مثال با Bot API مستقیم:
<code class="language-python">https://api.telegram.org/botTOKEN/sendMessage\
?chat_id=123456\
&text=Check%20this%20link:%20https://example.com\
&disable_web_page_preview=true</code>
مثال با کتابخانه
python-telegram-bot:<code class="language-python">await context.bot.send_message(
chat_id=update.effective_chat.id,
text="لینک مستندات: https://core.telegram.org/bots/api",
disable_web_page_preview=True,
)</code>
نکتهها ✨
• برای پیامهای اطلاعرسانی، دکمهای و لاگها، تقریباً همیشه گزینه بهتری است.
• برای لینکهای محتوایی (مقاله، ویدئو) فقط در صورت نیاز خاموش شود تا کاربر پیشنمایش را از دست ندهد.
بار بعد که ربات لینک فرستاد و چت شلوغ شد، یک بار این گزینه را تست کن 😉
منبع رسمی: Telegram Bot API - sendMessage
🔖 #TelegramBot #ربات #تلگرام #Telegram_Bot #disable_web_page_preview #sendMessage #python_telegram_bot #UX
👤 Developix
💎 Channel: @DevelopixRobot