ارسال و دریافت پیام در Telebot: کدنویسی پیام‌رسان ساده

فهرست مطالب

ارسال و دریافت پیام در Telebot: کدنویسی پیام‌رسان ساده

در دنیای امروز که ارتباطات دیجیتال نقش حیاتی در زندگی روزمره و کسب‌وکارها ایفا می‌کند، ربات‌های پیام‌رسان به ابزاری قدرتمند برای تعامل خودکار و ارائه خدمات تبدیل شده‌اند. تلگرام، به عنوان یکی از محبوب‌ترین پلتفرم‌های پیام‌رسان در ایران و جهان، بستر فوق‌العاده‌ای را برای توسعه این ربات‌ها فراهم آورده است. کتابخانه pyTelegramBotAPI، که با نام مستعار Telebot شناخته می‌شود، راهکاری سریع، قابل اعتماد و بسیار کارآمد برای کدنویسی ربات‌های تلگرام با زبان پایتون است. این کتابخانه با فراهم آوردن یک رابط کاربری ساده و در عین حال جامع، امکان ارسال و دریافت انواع پیام‌ها، مدیریت رویدادها، و ساخت تعاملات پیچیده را به آسانی برای توسعه‌دهندگان فراهم می‌آورد. هدف این مقاله، ارائه یک راهنمای جامع و فنی برای شروع کار با Telebot، از راه‌اندازی اولیه گرفته تا پیاده‌سازی قابلیت‌های پیشرفته‌تر، با تمرکز بر ارسال و دریافت پیام‌ها و ساخت یک پیام‌رسان ساده اما قدرتمند است.

ما در این پست وبلاگ، ابتدا به بررسی معماری و مزایای استفاده از Telebot خواهیم پرداخت و سپس گام به گام شما را در فرآیند نصب، پیکربندی و کدنویسی ربات همراهی خواهیم کرد. از نحوه دریافت توکن API از BotFather گرفته تا نوشتن هندلرهای پیچیده برای مدیریت انواع پیام‌ها، ارسال رسانه‌ها، و پیاده‌سازی کیبوردهای تعاملی، تمام جنبه‌های لازم برای ساخت یک ربات کارآمد پوشش داده خواهد شد. این محتوا برای توسعه‌دهندگانی که با پایتون آشنایی دارند و به دنبال ساخت ربات‌های تلگرام با قابلیت‌های متنوع هستند، مناسب است.

مقدمه‌ای بر Telebot و جایگاه آن در اکوسیستم پیام‌رسان‌ها

در عصر دیجیتال، ربات‌های پیام‌رسان به عنوان ابزاری قدرتمند برای اتوماسیون وظایف، بهبود تجربه کاربری و ایجاد کانال‌های ارتباطی جدید برای کسب‌وکارها و توسعه‌دهندگان شناخته می‌شوند. تلگرام، با API غنی و ویژگی‌های منحصربه‌فرد خود، به یکی از پلتفرم‌های پیشرو برای میزبانی این ربات‌ها تبدیل شده است. در میان کتابخانه‌های متعددی که برای توسعه ربات‌های تلگرام در زبان پایتون وجود دارد، pyTelegramBotAPI یا به اختصار Telebot، به دلیل سادگی، مستندات قوی و جامعه فعال خود، جایگاه ویژه‌ای پیدا کرده است. این کتابخانه به توسعه‌دهندگان اجازه می‌دهد تا با حداقل کدنویسی، ربات‌هایی با قابلیت‌های گسترده ایجاد کنند.

Telebot یک Wrapper (پوشش) سبک و شی‌گرا بر روی API رسمی تلگرام است که تمام متدها و انواع داده‌های موجود در API را به صورت توابع و کلاس‌های پایتون در دسترس قرار می‌دهد. این ویژگی باعث می‌شود که توسعه‌دهندگان بتوانند به جای سروکله زدن با درخواست‌های HTTP خام و تجزیه و تحلیل JSON، مستقیماً با اشیاء و توابع پایتون کار کنند که این امر سرعت توسعه و خوانایی کد را به شدت افزایش می‌دهد. از ربات‌های ساده‌ی پاسخگو تا سیستم‌های پیچیده‌ی مبتنی بر هوش مصنوعی، Telebot ابزاری انعطاف‌پذیر برای ساخت طیف وسیعی از کاربردهاست.

اهمیت Telebot در اکوسیستم پیام‌رسان‌ها به چند دلیل عمده است:

  • سادگی و سرعت توسعه: ساخت یک ربات پایه با قابلیت ارسال و دریافت پیام در Telebot تنها به چند خط کد نیاز دارد. این سادگی به توسعه‌دهندگان اجازه می‌دهد تا ایده‌های خود را به سرعت پیاده‌سازی و تست کنند.
  • پشتیبانی کامل از Telegram Bot API: Telebot تقریباً تمام قابلیت‌های ارائه شده توسط API تلگرام را پوشش می‌دهد، از ارسال متن و رسانه گرفته تا کیبوردهای سفارشی، وب‌هوک‌ها، و پرداخت‌های درون‌برنامه‌ای.
  • مدیریت رویدادهای انعطاف‌پذیر: با استفاده از سیستم هندلرها (@bot.message_handler، @bot.callback_query_handler و غیره)، می‌توان به راحتی انواع مختلف پیام‌ها و تعاملات کاربر را شناسایی و به آن‌ها پاسخ داد.
  • جامعه فعال و مستندات غنی: وجود یک جامعه توسعه‌دهنده فعال و مستندات به‌روز و کامل، حل مشکلات و یادگیری قابلیت‌های جدید را بسیار آسان می‌کند.
  • مدیریت خطا: Telebot ابزارهایی برای مدیریت خطاهای API فراهم می‌آورد که به ساخت ربات‌های پایدارتر کمک می‌کند.

در ادامه این راهنما، ما به صورت عملی با این قابلیت‌ها آشنا شده و یک پیام‌رسان ساده اما کاربردی را با Telebot کدنویسی خواهیم کرد.

راه‌اندازی اولیه و دریافت توکن ربات

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

نصب کتابخانه Telebot

اولین گام، نصب کتابخانه pyTelegramBotAPI در محیط پایتون شماست. توصیه اکید می‌شود که برای جلوگیری از تداخل وابستگی‌ها (dependencies) و مدیریت بهتر پروژه‌ها، از محیط‌های مجازی (Virtual Environments) استفاده کنید. محیط مجازی به شما اجازه می‌دهد تا مجموعه‌ای از کتابخانه‌های پایتون را به صورت ایزوله برای هر پروژه نصب کنید، بدون اینکه بر روی سایر پروژه‌ها یا نصب سراسری پایتون تأثیری بگذارد.

برای ایجاد و فعال‌سازی یک محیط مجازی، مراحل زیر را دنبال کنید:

  1. ایجاد محیط مجازی: در ترمینال یا Command Prompt، به پوشه پروژه خود بروید و دستور زیر را اجرا کنید (venv نام دلخواه برای پوشه محیط مجازی است):
    python -m venv venv

    این دستور یک پوشه به نام venv (یا هر نام دیگری که انتخاب کردید) در دایرکتوری جاری ایجاد می‌کند که حاوی یک کپی ایزوله از پایتون و ابزارهای مرتبط است.

  2. فعال‌سازی محیط مجازی:
    • برای سیستم‌عامل‌های Linux و macOS:
      source venv/bin/activate
    • برای سیستم‌عامل Windows (با Command Prompt):
      venv\Scripts\activate.bat
    • برای سیستم‌عامل Windows (با PowerShell):
      venv\Scripts\Activate.ps1

    پس از فعال‌سازی، نام محیط مجازی (معمولاً (venv)) در ابتدای خط فرمان شما نمایش داده می‌شود که نشان‌دهنده فعال بودن محیط مجازی است.

  3. نصب Telebot: حالا که محیط مجازی فعال شده است، می‌توانید کتابخانه Telebot را با استفاده از pip نصب کنید:
    pip install pyTelegramBotAPI

    pip پکیج pyTelegramBotAPI و تمام وابستگی‌های آن را در محیط مجازی شما نصب خواهد کرد.

با انجام این مراحل، محیط توسعه شما برای شروع کدنویسی ربات آماده است.

دریافت توکن از BotFather

هر ربات تلگرام برای اینکه بتواند از طریق API با سرورهای تلگرام ارتباط برقرار کند، نیاز به یک توکن API منحصر به فرد دارد. این توکن مانند یک کلید شناسایی عمل می‌کند و تمام درخواست‌های ربات شما به سرور تلگرام با استفاده از آن احراز هویت می‌شوند. توکن‌ها توسط یک ربات خاص در تلگرام به نام BotFather صادر می‌شوند.

برای دریافت توکن ربات خود، مراحل زیر را دنبال کنید:

  1. باز کردن BotFather:

    برنامه تلگرام را باز کنید و در قسمت جستجو، @BotFather را جستجو کنید. به دنبال رباتی با نام BotFather و یک تیک آبی (verified) باشید. روی آن کلیک کنید تا چت با BotFather باز شود.

  2. شروع مکالمه و ایجاد ربات جدید:

    روی دکمه Start یا دستور /start را ارسال کنید. BotFather لیستی از دستورات موجود را نمایش می‌دهد. برای ایجاد یک ربات جدید، دستور /newbot را ارسال کنید.

  3. انتخاب نام و نام کاربری:

    BotFather از شما می‌خواهد که یک نام (name) برای ربات خود انتخاب کنید. این نام همان چیزی است که کاربران در چت‌ها مشاهده می‌کنند (مثلاً: “ربات پیام‌رسان ساده”). پس از انتخاب نام، از شما خواسته می‌شود تا یک نام کاربری (username) برای ربات انتخاب کنید. نام کاربری باید منحصر به فرد باشد و حتماً به bot ختم شود (مثلاً: SimpleMessengerBot یا SimpleMessenger_bot). اگر نام کاربری انتخاب شده قبلاً استفاده شده باشد، BotFather از شما می‌خواهد نام دیگری را امتحان کنید.

  4. دریافت توکن API:

    پس از انتخاب موفقیت‌آمیز نام کاربری، BotFather توکن API ربات شما را برای شما ارسال خواهد کرد. این توکن یک رشته طولانی از حروف و اعداد است که چیزی شبیه به 1234567890:ABCDEFGHIJKLMN_OPQRSTUVWXYZ-abcdefghij خواهد بود.

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

اکنون که کتابخانه Telebot نصب شده و توکن API خود را دریافت کرده‌اید، می‌توانید به مرحله بعدی یعنی کدنویسی ساختار اصلی ربات خود بپردازید.

ساختار اصلی یک ربات Telebot

پس از نصب کتابخانه و دریافت توکن، نوبت به کدنویسی ساختار اصلی ربات می‌رسد. هر ربات Telebot با ایجاد یک نمونه از کلاس TeleBot و سپس راه‌اندازی یک حلقه پولینگ (polling loop) برای گوش دادن به به‌روزرسانی‌ها از سرور تلگرام، کار می‌کند. در این بخش، ما به بررسی نحوه ایجاد این ساختار و چگونگی شروع و متوقف کردن ربات خواهیم پرداخت.

فایل main.py یا bot.py خود را ایجاد کنید و کدهای زیر را در آن قرار دهید:


import telebot
import os

# توصیه می‌شود توکن را از متغیرهای محیطی دریافت کنید تا امنیت آن حفظ شود.
# به عنوان مثال، قبل از اجرای اسکریپت:
# export TELEGRAM_BOT_TOKEN="YOUR_BOT_TOKEN_HERE"
# یا در ویندوز:
# set TELEGRAM_BOT_TOKEN="YOUR_BOT_TOKEN_HERE"
# TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")

# برای شروع سریع، می‌توانید توکن را مستقیماً اینجا قرار دهید،
# اما در محیط‌های تولیدی به هیچ وجه توصیه نمی‌شود.
TOKEN = "YOUR_BOT_TOKEN_HERE" # توکن خود را اینجا قرار دهید

if not TOKEN or TOKEN == "YOUR_BOT_TOKEN_HERE":
    print("خطا: توکن ربات تلگرام تنظیم نشده است. لطفاً توکن خود را وارد کنید.")
    exit()

# ایجاد یک نمونه از کلاس TeleBot
bot = telebot.TeleBot(TOKEN)

# یک هندلر ساده برای فرمان /start
@bot.message_handler(commands=['start'])
def send_welcome(message):
    """
    این تابع به فرمان /start پاسخ می‌دهد و یک پیام خوش‌آمدگویی ارسال می‌کند.
    :param message: شیء پیام دریافتی از تلگرام
    """
    user_name = message.from_user.first_name if message.from_user.first_name else "کاربر گرامی"
    bot.send_message(message.chat.id, f"سلام {user_name}! به ربات پیام‌رسان ساده خوش آمدید.")
    bot.send_message(message.chat.id, "من آماده‌ام تا پیام‌های شما را دریافت و به آن‌ها پاسخ دهم.")

# یک هندلر ساده برای پیام‌های متنی
@bot.message_handler(func=lambda message: True)
def echo_all(message):
    """
    این تابع به تمام پیام‌های متنی دیگر پاسخ می‌دهد و همان متن را برمی‌گرداند (echo).
    :param message: شیء پیام دریافتی از تلگرام
    """
    print(f"پیام دریافتی از {message.from_user.first_name} ({message.from_user.id}): {message.text}")
    bot.reply_to(message, message.text) # پاسخ دادن به پیام با همان متن

# شروع و متوقف کردن ربات
if __name__ == '__main__':
    print("ربات در حال اجرا است...")
    try:
        # bot.polling() به صورت نامحدود به روزرسانی ها را دریافت می کند.
        # none_stop=True: ربات حتی پس از بروز خطا نیز به تلاش برای دریافت آپدیت ادامه می‌دهد.
        # interval=0: فاصله زمانی بین هر درخواست پولینگ (به ثانیه). 0 برای تأخیر حداقلی.
        # timeout: حداکثر زمان انتظار برای دریافت یک آپدیت جدید.
        bot.polling(none_stop=True, interval=0, timeout=20)
    except Exception as e:
        print(f"خطایی رخ داد: {e}")
    finally:
        print("ربات متوقف شد.")

در کد بالا:

  • ابتدا کتابخانه telebot و os (برای خواندن متغیرهای محیطی) را import می‌کنیم.
  • توکن ربات شما باید به telebot.TeleBot() منتقل شود. تاکید می‌کنم که برای امنیت، توکن را مستقیماً در کد قرار ندهید و از متغیرهای محیطی استفاده کنید. در این مثال، یک راهنمایی برای استفاده از os.getenv() ارائه شده است.
  • @bot.message_handler(commands=['start']): این یک دکوراتور (decorator) است که تابع send_welcome را به عنوان یک هندلر (handler) برای پیام‌هایی که با فرمان /start شروع می‌شوند، ثبت می‌کند. هنگامی که کاربری /start را به ربات شما ارسال کند، این تابع فراخوانی می‌شود.
  • @bot.message_handler(func=lambda message: True): این هندلر برای هر پیامی که به هندلرهای قبلی (مثل /start) تعلق نداشته باشد، فعال می‌شود. lambda message: True به این معنی است که این هندلر تمامی پیام‌ها را بدون فیلتر خاصی (به جز فیلترهای دیگر هندلرها که اولویت بالاتری دارند) دریافت می‌کند. در این مثال، تابع echo_all پیام دریافتی را به همان کاربر بازمی‌گرداند.
  • bot.send_message(message.chat.id, "..."): این متد برای ارسال یک پیام متنی به کاربر استفاده می‌شود. message.chat.id شناسه چتی است که پیام از آنجا آمده است و ما می‌خواهیم پاسخ را به همان چت ارسال کنیم.
  • bot.reply_to(message, "..."): این متد شبیه به send_message است، اما پیام شما به عنوان پاسخی به پیام اصلی کاربر در تلگرام نمایش داده می‌شود.

شروع و متوقف کردن ربات

بخش if __name__ == '__main__': مسئول اجرای ربات است.

bot.polling(none_stop=True, interval=0, timeout=20)

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

  • none_stop=True: این پارامتر تضمین می‌کند که ربات حتی در صورت بروز خطا نیز به تلاش برای دریافت به‌روزرسانی ادامه دهد. این برای اطمینان از پایداری ربات در محیط‌های تولیدی بسیار مهم است.
  • interval=0: این پارامتر فاصله زمانی (به ثانیه) بین هر درخواست پولینگ را مشخص می‌کند. مقدار 0 به این معنی است که ربات بلافاصله پس از دریافت و پردازش هر به‌روزرسانی، درخواست بعدی را ارسال می‌کند تا تاخیر به حداقل برسد.
  • timeout=20: این پارامتر حداکثر زمانی (به ثانیه) را تعیین می‌کند که ربات برای دریافت یک به‌روزرسانی جدید از سرور تلگرام صبر می‌کند. اگر در این مدت به‌روزرسانی دریافت نشود، یک درخواست پولینگ جدید ارسال می‌شود. این کمک می‌کند تا اتصال به سرور تلگرام فعال بماند.

برای متوقف کردن ربات، معمولاً باید اسکریپت پایتون را با فشردن Ctrl+C در ترمینال متوقف کنید. استفاده از بلاک try-except-finally به ما امکان می‌دهد تا خطاهای احتمالی در حین اجرای ربات را مدیریت کرده و در نهایت یک پیام “ربات متوقف شد” را نمایش دهیم.

با اجرای این اسکریپت (python main.py در ترمینال)، ربات شما فعال شده و آماده دریافت پیام‌ها خواهد بود. می‌توانید به تلگرام خود بروید، ربات خود را جستجو کنید (با استفاده از نام کاربری آن) و با ارسال /start یا هر پیام متنی دیگری، عملکرد آن را تست کنید.

دریافت پیام‌ها: هندلرها و فیلترها

قلب هر ربات تلگرام، توانایی آن در دریافت و پردازش انواع مختلف پیام‌ها از کاربران است. Telebot این قابلیت را از طریق هندلرها (Handlers) و فیلترها (Filters) به شیوه‌ای قدرتمند و انعطاف‌پذیر فراهم می‌آورد. هندلرها توابعی هستند که برای پاسخگویی به رویدادهای خاص (مانند دریافت پیام متنی، عکس، فرمان و …) تعریف می‌شوند، در حالی که فیلترها تعیین می‌کنند کدام پیام‌ها باید توسط یک هندلر خاص پردازش شوند.

هندلر پیام‌های متنی

رایج‌ترین نوع پیام، پیام متنی است. برای پردازش این پیام‌ها، از دکوراتور @bot.message_handler() استفاده می‌کنیم. این دکوراتور، تابع بعدی را به عنوان یک هندلر برای پیام‌های دریافتی ثبت می‌کند. شیء message که به تابع هندلر ارسال می‌شود، حاوی اطلاعات جامعی در مورد پیام دریافتی است:

  • message.text: متن پیام.
  • message.chat.id: شناسه منحصر به فرد چتی که پیام از آنجا آمده است. این شناسه برای ارسال پاسخ به همان چت استفاده می‌شود.
  • message.from_user.id: شناسه منحصر به فرد کاربری که پیام را ارسال کرده است.
  • message.from_user.first_name: نام کوچک کاربر.
  • message.from_user.last_name: نام خانوادگی کاربر (اگر تنظیم شده باشد).
  • message.from_user.username: نام کاربری کاربر (اگر تنظیم شده باشد).
  • message.date: تاریخ و زمان ارسال پیام (به صورت timestamp).
  • message.message_id: شناسه منحصر به فرد پیام.
  • message.chat.type: نوع چت (مثلاً private، group، supergroup، channel).

مثالی از یک هندلر ساده برای دریافت تمام پیام‌های متنی:


import telebot

TOKEN = "YOUR_BOT_TOKEN_HERE"
bot = telebot.TeleBot(TOKEN)

@bot.message_handler(func=lambda message: True, content_types=['text'])
def handle_text_messages(message):
    """
    هندلر برای تمام پیام‌های متنی.
    این تابع اطلاعاتی در مورد پیام دریافتی را در کنسول چاپ می‌کند
    و با اطلاعات چت و کاربر به پیام پاسخ می‌دهد.
    """
    chat_id = message.chat.id
    user_id = message.from_user.id
    user_first_name = message.from_user.first_name or "ناشناس"
    message_text = message.text

    print(f"پیام دریافتی از {user_first_name} (ID: {user_id}) در چت {chat_id}: {message_text}")
    
    response = (f"سلام {user_first_name}!\n"
                f"شما گفتید: '{message_text}'\n"
                f"شناسه چت شما: {chat_id}")
    
    bot.reply_to(message, response)

if __name__ == '__main__':
    print("ربات در حال اجرا است و منتظر پیام‌های متنی است...")
    bot.polling(none_stop=True, interval=0)

در این مثال، func=lambda message: True به این معنی است که هیچ فیلتر خاصی بر روی متن پیام اعمال نمی‌شود و هر پیام متنی توسط این هندلر پردازش خواهد شد. content_types=['text'] اطمینان می‌دهد که فقط پیام‌های از نوع “متن” به این هندلر فرستاده شوند.

فیلتر کردن انواع پیام

تلگرام انواع مختلفی از پیام‌ها را پشتیبانی می‌کند: عکس، ویدئو، سند، صوت، استیکر، لوکیشن، مخاطب، نظرسنجی و غیره. Telebot به شما اجازه می‌دهد تا هندلرهای جداگانه‌ای برای هر نوع پیام یا ترکیبی از آن‌ها تعریف کنید. این کار با استفاده از پارامتر content_types در دکوراتور @bot.message_handler() انجام می‌شود.

لیست کامل content_types شامل:

  • 'text'
  • 'photo'
  • 'video'
  • 'document'
  • 'audio'
  • 'sticker'
  • 'voice'
  • 'location'
  • 'contact'
  • 'animation'
  • 'video_note'
  • 'venue'
  • 'poll'
  • 'dice'
  • 'game'
  • 'invoice'
  • 'successful_payment'
  • 'migrate_to_chat_id'
  • 'migrate_from_chat_id'
  • 'pinned_message'
  • 'new_chat_members'
  • 'left_chat_member'
  • 'new_chat_title'
  • 'new_chat_photo'
  • 'delete_chat_photo'
  • 'group_chat_created'
  • 'supergroup_chat_created'
  • 'channel_chat_created'
  • 'message_auto_delete_timer_changed'
  • 'forum_topic_created'
  • 'forum_topic_closed'
  • 'forum_topic_reopened'
  • 'video_chat_started'
  • 'video_chat_ended'
  • 'video_chat_participants_invited'
  • 'web_app_data'
  • 'proximity_alert_triggered'
  • 'story'
  • 'unknown'

مثال‌هایی برای فیلتر کردن انواع پیام:


# ... (کدهای اولیه ربات) ...

@bot.message_handler(content_types=['photo'])
def handle_photo(message):
    """هندلر برای عکس‌ها."""
    chat_id = message.chat.id
    file_id = message.photo[-1].file_id # بزرگترین سایز عکس
    caption = message.caption if message.caption else "بدون توضیح"
    
    bot.send_message(chat_id, f"عکس شما با موفقیت دریافت شد! \nID عکس: {file_id}\nتوضیحات: {caption}", parse_mode='HTML')
    # شما می‌توانید عکس را دانلود یا با استفاده از file_id دوباره ارسال کنید.

@bot.message_handler(content_types=['document'])
def handle_document(message):
    """هندلر برای اسناد."""
    chat_id = message.chat.id
    file_id = message.document.file_id
    file_name = message.document.file_name
    file_size = message.document.file_size
    
    bot.send_message(chat_id, f"سند شما دریافت شد: {file_name} (سایز: {file_size} بایت). ID فایل: {file_id}", parse_mode='HTML')

@bot.message_handler(content_types=['sticker'])
def handle_sticker(message):
    """هندلر برای استیکرها."""
    chat_id = message.chat.id
    sticker_id = message.sticker.file_id
    bot.send_message(chat_id, f"چه استیکر جالبی! ID استیکر: {sticker_id}", parse_mode='HTML')
    bot.send_sticker(chat_id, sticker_id) # ارسال مجدد استیکر

@bot.message_handler(content_types=['location'])
def handle_location(message):
    """هندلر برای موقعیت مکانی."""
    chat_id = message.chat.id
    latitude = message.location.latitude
    longitude = message.location.longitude
    bot.send_message(chat_id, f"موقعیت مکانی شما دریافت شد: \nعرض جغرافیایی: {latitude}\nطول جغرافیایی: {longitude}")
    # می‌توانید این موقعیت را روی نقشه نمایش دهید یا از آن استفاده کنید.

# ... (ادامه کدهای ربات و bot.polling) ...

می‌توانید چند نوع محتوا را در یک هندلر مدیریت کنید:


@bot.message_handler(content_types=['photo', 'video', 'audio', 'document'])
def handle_media(message):
    """هندلر برای انواع فایل‌های رسانه‌ای."""
    chat_id = message.chat.id
    if message.photo:
        file_type = "عکس"
        file_id = message.photo[-1].file_id
    elif message.video:
        file_type = "ویدئو"
        file_id = message.video.file_id
    elif message.audio:
        file_type = "صوت"
        file_id = message.audio.file_id
    elif message.document:
        file_type = "سند"
        file_id = message.document.file_id
    else:
        file_type = "فایل نامشخص"
        file_id = "نامشخص"

    bot.send_message(chat_id, f"{file_type} شما دریافت شد. ID فایل: {file_id}", parse_mode='HTML')

هندلر فرمان‌ها (Command Handlers)

فرمان‌ها (Commands) پیام‌های متنی خاصی هستند که با کاراکتر / شروع می‌شوند (مانند /start، /help، /settings). این فرمان‌ها برای فعال کردن قابلیت‌های خاص ربات طراحی شده‌اند. برای ایجاد یک هندلر فرمان، از پارامتر commands در دکوراتور @bot.message_handler() استفاده می‌کنیم.


# ... (کدهای اولیه ربات) ...

@bot.message_handler(commands=['help'])
def send_help(message):
    """هندلر برای فرمان /help."""
    chat_id = message.chat.id
    help_text = (
        "دستورات موجود:\n"
        "/start - شروع مکالمه با ربات\n"
        "/help - نمایش این راهنما\n"
        "/echo [متن] - تکرار متن شما\n"
        "/info - نمایش اطلاعات کاربری شما\n"
        "\nشما می‌توانید عکس، ویدئو، سند، استیکر و لوکیشن نیز برای من ارسال کنید!"
    )
    bot.send_message(chat_id, help_text)

@bot.message_handler(commands=['echo'])
def echo_command(message):
    """
    هندلر برای فرمان /echo که متن پس از فرمان را برمی‌گرداند.
    مثال: /echo سلام دنیا -> پاسخ: سلام دنیا
    """
    chat_id = message.chat.id
    # message.text شامل /echo و متن است. باید آن را جدا کنیم.
    command_parts = message.text.split(maxsplit=1) # تقسیم حداکثر 1 بار
    if len(command_parts) > 1:
        text_to_echo = command_parts[1]
        bot.send_message(chat_id, f"شما درخواست دادید که بگویم: {text_to_echo}")
    else:
        bot.send_message(chat_id, "لطفاً بعد از /echo متنی برای تکرار بنویسید. مثال: /echo سلام")

@bot.message_handler(commands=['info'])
def user_info(message):
    """نمایش اطلاعات کاربری ارسال کننده پیام."""
    user = message.from_user
    chat_id = message.chat.id
    info_text = (
        f"اطلاعات کاربری شما:\n"
        f"ID کاربر: {user.id}\n"
        f"نام: {user.first_name} {user.last_name if user.last_name else ''}\n"
        f"نام کاربری: @{user.username if user.username else 'ندارد'}\n"
        f"آیا ربات است؟: {'بله' if user.is_bot else 'خیر'}"
    )
    bot.send_message(chat_id, info_text, parse_mode='HTML')

# ... (ادامه کدهای ربات و bot.polling) ...

هندلرها بر اساس ترتیب تعریف آن‌ها بررسی می‌شوند. یعنی اگر چندین هندلر برای یک نوع پیام وجود داشته باشد، اولین هندلری که فیلترهای آن مطابقت داشته باشد، پیام را پردازش می‌کند. بنابراین، معمولاً هندلرهای عمومی‌تر (مثل func=lambda message: True) را در انتهای لیست هندلرها قرار می‌دهیم.

ارسال پیام‌ها: متدها و انواع

پس از دریافت و پردازش پیام‌ها، قابلیت ارسال پاسخ‌های متنوع و غنی به کاربران یکی از مهم‌ترین جنبه‌های یک ربات کارآمد است. Telebot متدهای مختلفی را برای ارسال انواع گوناگون پیام‌ها، از متن ساده گرفته تا تصاویر و فایل‌ها، ارائه می‌دهد. در این بخش، به بررسی این متدها و نحوه استفاده از آن‌ها می‌پردازیم.

تمام متدهای ارسال پیام در Telebot به یک chat_id نیاز دارند که شناسه چت مقصد است. معمولاً این شناسه همان message.chat.id از پیام دریافتی است.

ارسال پیام متنی ساده

ساده‌ترین و رایج‌ترین نوع پیام، پیام متنی است که با متد bot.send_message() ارسال می‌شود. این متد علاوه بر متن پیام، چندین پارامتر اختیاری برای سفارشی‌سازی بیشتر پیام دارد:


# ... (کدهای اولیه ربات) ...

@bot.message_handler(commands=['greet'])
def greet_user(message):
    chat_id = message.chat.id
    user_name = message.from_user.first_name or "کاربر"
    
    # ارسال یک پیام متنی ساده
    bot.send_message(chat_id, f"سلام {user_name}! حالت چطوره؟")

    # ارسال پیام با MarkdownV2 برای قالب‌بندی
    markdown_text = (
        "این یک پیام با قالب‌بندی غنی است.\n"
        "می‌توانید از *متن مورب*، **متن پررنگ**، "
        "لینک‌ها و "
        "کد استفاده کنید.\n"
        "یا حتی یک منشن به خودتان."
    ).format(user_id=message.from_user.id)
    
    bot.send_message(
        chat_id,
        markdown_text,
        parse_mode='HTML', # یا 'MarkdownV2'
        disable_web_page_preview=True # غیرفعال کردن پیش‌نمایش لینک‌ها
    )

    # ارسال پیام به عنوان پاسخ به یک پیام خاص
    bot.send_message(
        chat_id,
        "این پیام به عنوان پاسخ به فرمان شما ارسال شده است.",
        reply_to_message_id=message.message_id
    )

# ... (ادامه کدهای ربات) ...

پارامترهای مهم bot.send_message():

  • chat_id: شناسه چت مقصد.
  • text: متن پیام برای ارسال.
  • parse_mode: نحوه تفسیر قالب‌بندی متن. می‌تواند 'HTML' یا 'MarkdownV2' باشد.
    • برای 'HTML': از تگ‌های HTML مانند <b>، <i>، <code>، <pre>، <a href="..."> استفاده می‌شود.
    • برای 'MarkdownV2': از کاراکترهای خاص Markdown مانند *پررنگ*، _مورب_، `کد`، [لینک](URL) استفاده می‌شود. (نیاز به escape کردن کاراکترهای خاص در MarkdownV2 بسیار مهم است).
  • disable_web_page_preview: اگر True باشد، پیش‌نمایش لینک‌ها در پیام غیرفعال می‌شود.
  • reply_to_message_id: شناسه پیام اصلی که این پیام به آن پاسخ می‌دهد.
  • reply_markup: برای افزودن کیبوردهای سفارشی (در بخش‌های بعدی توضیح داده می‌شود).

ارسال تصاویر، ویدئوها و فایل‌ها

Telebot متدهای اختصاصی برای ارسال انواع فایل‌های رسانه‌ای دارد: bot.send_photo()، bot.send_video()، bot.send_audio()، bot.send_document()، bot.send_sticker() و bot.send_animation().

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

  1. از طریق file_id (شناسه فایل): اگر قبلاً یک فایل به تلگرام آپلود کرده باشید، تلگرام یک file_id به آن اختصاص می‌دهد. استفاده از file_id برای ارسال‌های بعدی بسیار سریع‌تر و کارآمدتر است زیرا فایل دوباره آپلود نمی‌شود.
  2. از طریق URL: می‌توانید URL مستقیم به یک فایل (تصویر، ویدئو و غیره) را ارسال کنید. تلگرام خودش فایل را دانلود و ارسال می‌کند.
  3. از طریق فایل محلی: می‌توانید یک شیء فایل (با استفاده از open('path/to/file', 'rb')) را ارسال کنید. Telebot فایل را آپلود می‌کند.

import telebot
from telebot import types
import os

TOKEN = "YOUR_BOT_TOKEN_HERE"
bot = telebot.TeleBot(TOKEN)

# مسیر فایل‌های نمونه (مطمئن شوید این فایل‌ها در کنار اسکریپت شما موجود باشند)
# sample_photo_path = "path/to/your/image.jpg"
# sample_video_path = "path/to/your/video.mp4"
# sample_document_path = "path/to/your/document.pdf"

# فرض می‌کنیم فایل‌ها موجود هستند یا از یک سرویس ابری دریافت می‌شوند.
# در اینجا برای سادگی، از URL یا file_id های نمونه (فرضی) استفاده می‌کنیم.
# بهتر است از فایل‌های واقعی خودتان استفاده کنید.

PHOTO_URL = "https://www.shutterstock.com/image-photo/beautiful-panoramic-view-colorful-sunrise-600nw-1052906804.jpg" # یک URL عکس واقعی
VIDEO_URL = "http://techslides.com/demos/sample-videos/small.mp4" # یک URL ویدئو واقعی
DOCUMENT_URL = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf" # یک URL سند واقعی

# اگر قبلاً عکسی را ارسال کرده باشید، می‌توانید file_id آن را اینجا قرار دهید.
# EXAMPLE_PHOTO_FILE_ID = "AgACAgIAAxkBAAI..." # ID یک عکس که قبلاً آپلود شده است.

@bot.message_handler(commands=['send_media'])
def send_media_examples(message):
    chat_id = message.chat.id

    # ارسال عکس از طریق URL
    bot.send_message(chat_id, "در حال ارسال یک عکس از طریق URL...")
    bot.send_photo(
        chat_id,
        PHOTO_URL,
        caption="یک منظره زیبا! \nاطلاعات بیشتر",
        parse_mode='HTML'
    )
    
    # ارسال ویدئو از طریق URL
    bot.send_message(chat_id, "در حال ارسال یک ویدئو از طریق URL...")
    bot.send_video(
        chat_id,
        VIDEO_URL,
        caption="یک ویدئوی کوتاه آموزشی.",
        parse_mode='HTML',
        supports_streaming=True # اجازه پخش جریانی را می‌دهد
    )

    # ارسال سند از طریق URL
    bot.send_message(chat_id, "در حال ارسال یک سند PDF از طریق URL...")
    bot.send_document(
        chat_id,
        DOCUMENT_URL,
        caption="یک فایل PDF نمونه."
    )

    # ارسال عکس از طریق فایل محلی (باید فایل "local_image.jpg" در همان دایرکتوری باشد)
    # با فرض وجود فایل "local_image.jpg"
    try:
        with open("local_image.jpg", 'rb') as photo:
            bot.send_photo(chat_id, photo, caption="عکس از فایل محلی.")
        print("عکس محلی با موفقیت ارسال شد.")
    except FileNotFoundError:
        bot.send_message(chat_id, "فایل local_image.jpg پیدا نشد.")
        print("خطا: فایل local_image.jpg پیدا نشد. لطفاً یک فایل عکس با این نام در کنار اسکریپت قرار دهید.")
    
    # ارسال صوتی از طریق URL
    bot.send_audio(
        chat_id,
        "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
        caption="یک فایل صوتی نمونه.",
        title="آهنگ نمونه",
        performer="SoundHelix"
    )

# ... (بقیه هندلرها و bot.polling) ...

نکات کلیدی برای ارسال رسانه‌ها:

  • برای فایل‌های محلی، همیشه فایل را در حالت باینری برای خواندن ('rb') باز کنید.
  • برای caption می‌توانید از parse_mode='HTML' یا 'MarkdownV2' برای قالب‌بندی متن استفاده کنید.
  • برای ویدئوها، supports_streaming=True را برای امکان پخش آنلاین اضافه کنید.
  • Telebot به صورت خودکار اندازه، طول و سایر متادیتای فایل‌های رسانه‌ای را تشخیص می‌دهد.

ارسال لینک‌های داخلی و خارجی

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

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

  1. به عنوان متن خالص (با پیش‌نمایش یا بدون آن):

    اگر صرفاً یک URL را در پیام متنی قرار دهید، تلگرام به صورت خودکار آن را به یک لینک قابل کلیک تبدیل می‌کند و در صورت امکان، یک پیش‌نمایش از محتوای لینک را نمایش می‌دهد. می‌توانید این پیش‌نمایش را با disable_web_page_preview=True غیرفعال کنید.

    
    @bot.message_handler(commands=['link_plain'])
    def send_plain_link(message):
        chat_id = message.chat.id
        bot.send_message(chat_id, "این یک لینک به گوگل است: https://www.google.com")
        bot.send_message(chat_id, "این یک لینک به ویکی پدیا بدون پیش‌نمایش است: https://fa.wikipedia.org/wiki/تلگرام", disable_web_page_preview=True)
            
  2. لینک‌های درون‌خطی (Inline Links) در متن قالب‌بندی شده:

    این روش به شما اجازه می‌دهد تا لینک را به یک کلمه یا عبارت خاص در پیام متصل کنید، که ظاهر حرفه‌ای‌تری دارد.

    • با parse_mode='HTML': از تگ <a href="URL">متن لینک</a> استفاده کنید.
    • با parse_mode='MarkdownV2': از سینتکس [متن لینک](URL) استفاده کنید. (به یاد داشته باشید که در MarkdownV2 نیاز به escape کردن کاراکترهای خاص دارید).
    
    @bot.message_handler(commands=['link_formatted'])
    def send_formatted_link(message):
        chat_id = message.chat.id
        
        # لینک خارجی با HTML
        html_link_text = "برای اطلاعات بیشتر به مستندات Telebot مراجعه کنید."
        bot.send_message(chat_id, html_link_text, parse_mode='HTML')
    
        # لینک خارجی با MarkdownV2 (نیاز به escape کردن کاراکترهای خاص)
        markdown_link_text = "برای ارتباط با BotFather، اینجا را [کلیک کنید](https://t.me/BotFather)\\."
        bot.send_message(chat_id, markdown_link_text, parse_mode='MarkdownV2')
    
        # لینک داخلی به یک کاربر خاص (Mention)
        # این لینک فقط در صورتی کار می‌کند که کاربر target_user_id (مثلاً خودتان) قبلاً با ربات شما چت کرده باشد.
        # یا می توانید از username استفاده کنید: [نام کاربری](tg://user?id=123456789)
        target_user_id = message.from_user.id # فرض کنید می‌خواهیم کاربر خودش را منشن کند
        mention_user_text = f"برای گفتگو با این کاربر، روی نامش کلیک کنید."
        bot.send_message(chat_id, mention_user_text, parse_mode='HTML')
    
        # لینک به یک کانال یا گروه (اگر public باشند)
        channel_link_text = "کانال ما را دنبال کنید: کانال رسمی تلگرام"
        bot.send_message(chat_id, channel_link_text, parse_mode='HTML')
    
        # Deep Link به خود ربات با پارامترهای خاص
        deep_link_text = "برای شروع یک فرآیند خاص، روی اینجا کلیک کنید."
        bot.send_message(chat_id, deep_link_text, parse_mode='HTML')
            

    استفاده از لینک‌های درون‌خطی به شما امکان می‌دهد تا پیام‌هایی حرفه‌ای‌تر و کاربرپسندتر ایجاد کنید. لینک‌های داخلی (tg://user?id=...) برای منشن کردن کاربران خاص یا ارجاع به چت‌ها و کانال‌های دیگر بسیار مفید هستند، اما برای اینکه منشن به کاربر کار کند، معمولاً کاربر مورد نظر باید قبلاً حداقل یک بار با ربات شما تعامل کرده باشد.

    مدیریت وضعیت و پاسخ‌های تعاملی

    یک ربات “ساده” ممکن است فقط به پیام‌های تک‌مرحله‌ای پاسخ دهد، اما یک “پیام‌رسان ساده” کاربردی، نیازمند تعاملات چند مرحله‌ای و پاسخ‌های هوشمندانه است. مدیریت وضعیت (State Management) به ربات اجازه می‌دهد تا مراحل مختلف یک گفتگو را دنبال کند و بر اساس ورودی‌های قبلی کاربر، پاسخ‌های مناسب را ارائه دهد. Telebot ابزارهایی مانند کیبوردهای پاسخ‌دهی (Reply Keyboards) و کیبوردهای Inline (Inline Keyboards) را برای ایجاد این تعاملات فراهم می‌کند.

    کیبوردهای پاسخ‌دهی (Reply Keyboards)

    کیبوردهای پاسخ‌دهی، کیبوردهایی هستند که جایگزین کیبورد پیش‌فرض کاربر در تلگرام می‌شوند. این کیبوردها مجموعه‌ای از دکمه‌های متنی را نمایش می‌دهند که با کلیک بر روی آن‌ها، یک پیام متنی به ربات ارسال می‌شود. این دکمه‌ها برای راهنمایی کاربر در انتخاب گزینه‌های محدود و مشخص (مثلاً “بله/خیر”، “منو اصلی”، “مخاطب من”، “موقعیت من”) بسیار مفید هستند.

    
    import telebot
    from telebot import types
    
    TOKEN = "YOUR_BOT_TOKEN_HERE"
    bot = telebot.TeleBot(TOKEN)
    
    # یک دیکشنری برای ذخیره وضعیت کاربران
    user_states = {} # {chat_id: state_name}
    
    @bot.message_handler(commands=['menu'])
    def show_main_menu(message):
        chat_id = message.chat.id
    
        # ایجاد یک ReplyKeyboardMarkup
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
        
        # افزودن دکمه‌ها
        itembtn1 = types.KeyboardButton('گزینه ۱')
        itembtn2 = types.KeyboardButton('گزینه ۲')
        itembtn3 = types.KeyboardButton('مخاطب من', request_contact=True) # درخواست ارسال شماره تماس
        itembtn4 = types.KeyboardButton('موقعیت من', request_location=True) # درخواست ارسال موقعیت مکانی
        itembtn5 = types.KeyboardButton('شروع نظرسنجی')
    
        # اضافه کردن دکمه‌ها به کیبورد (می‌توانید در هر سطر یک یا چند دکمه قرار دهید)
        markup.row(itembtn1, itembtn2) # دو دکمه در یک سطر
        markup.add(itembtn3) # یک دکمه در سطر جدید
        markup.add(itembtn4, itembtn5) # دو دکمه در سطر جدید
    
        bot.send_message(chat_id, "لطفاً یکی از گزینه‌های زیر را انتخاب کنید:", reply_markup=markup)
    
    @bot.message_handler(func=lambda message: message.text == 'گزینه ۱')
    def handle_option1(message):
        chat_id = message.chat.id
        bot.send_message(chat_id, "شما گزینه ۱ را انتخاب کردید.")
    
    @bot.message_handler(func=lambda message: message.text == 'گزینه ۲')
    def handle_option2(message):
        chat_id = message.chat.id
        bot.send_message(chat_id, "شما گزینه ۲ را انتخاب کردید.")
    
    @bot.message_handler(content_types=['contact'])
    def handle_contact(message):
        chat_id = message.chat.id
        contact = message.contact
        bot.send_message(chat_id, f"شماره تماس شما دریافت شد: {contact.phone_number} (نام: {contact.first_name})")
    
    @bot.message_handler(content_types=['location'])
    def handle_location_request(message):
        chat_id = message.chat.id
        location = message.location
        bot.send_message(chat_id, f"موقعیت مکانی شما دریافت شد: عرض جغرافیایی {location.latitude}, طول جغرافیایی {location.longitude}")
    
    @bot.message_handler(func=lambda message: message.text == 'شروع نظرسنجی')
    def start_poll(message):
        chat_id = message.chat.id
        user_states[chat_id] = 'awaiting_poll_question'
        bot.send_message(chat_id, "لطفاً سوال نظرسنجی را وارد کنید.")
    
    @bot.message_handler(func=lambda message: user_states.get(message.chat.id) == 'awaiting_poll_question')
    def get_poll_question(message):
        chat_id = message.chat.id
        question = message.text
        user_states[chat_id] = {'state': 'awaiting_poll_options', 'question': question}
        bot.send_message(chat_id, "سوال نظرسنجی دریافت شد. حالا گزینه‌های پاسخ را با کاما جدا شده وارد کنید (مثال: بله, خیر, شاید).")
    
    @bot.message_handler(func=lambda message: user_states.get(message.chat.id) and user_states[message.chat.id]['state'] == 'awaiting_poll_options')
    def get_poll_options(message):
        chat_id = message.chat.id
        options_text = message.text
        options = [opt.strip() for opt in options_text.split(',')]
        
        if len(options) < 2 or len(options) > 10:
            bot.send_message(chat_id, "لطفاً حداقل ۲ و حداکثر ۱۰ گزینه وارد کنید. دوباره امتحان کنید.")
            return
        
        question = user_states[chat_id]['question']
        
        bot.send_poll(
            chat_id,
            question=question,
            options=options,
            is_anonymous=False, # نظرسنجی غیرناشناس
            allows_multiple_answers=False # تنها یک انتخاب مجاز است
        )
        bot.send_message(chat_id, "نظرسنجی ایجاد شد.")
        del user_states[chat_id] # حذف وضعیت کاربر پس از اتمام نظرسنجی
    
    @bot.message_handler(commands=['remove_keyboard'])
    def remove_custom_keyboard(message):
        chat_id = message.chat.id
        remove_markup = types.ReplyKeyboardRemove(selective=False)
        bot.send_message(chat_id, "کیبورد سفارشی حذف شد.", reply_markup=remove_markup)
    
    # ... (ادامه کدهای ربات و bot.polling) ...
    

    ویژگی‌های مهم ReplyKeyboardMarkup:

    • resize_keyboard=True: کیبورد به صورت خودکار به اندازه صفحه نمایش کاربر تغییر اندازه می‌دهد.
    • one_time_keyboard=True: پس از یک بار استفاده، کیبورد پنهان می‌شود.
    • selective=True: کیبورد فقط برای کاربرانی نمایش داده می‌شود که ربات به پیام آن‌ها پاسخ داده است (در گروه‌ها مفید است).
    • KeyboardButton: کلاس برای ایجاد دکمه‌ها. می‌تواند شامل text، request_contact=True (برای درخواست شماره تماس) یا request_location=True (برای درخواست موقعیت مکانی) باشد.
    • برای حذف یک Reply Keyboard، از types.ReplyKeyboardRemove() استفاده کنید.

    در مثال بالا، از یک دیکشنری user_states برای مدیریت وضعیت کاربران در حین فرآیند ایجاد نظرسنجی استفاده شده است. این یک روش ساده برای پیاده‌سازی مدیریت وضعیت است.

    کیبوردهای Inline (Inline Keyboards)

    کیبوردهای Inline، دکمه‌هایی هستند که مستقیماً به پیام متصل می‌شوند و با پیام حرکت می‌کنند. بر خلاف Reply Keyboards که پیامی به ربات ارسال می‌کنند، Inline Keyboards یک Callback Query را به ربات ارسال می‌کنند. این callback query شامل داده‌ای است که شما برای دکمه تعیین کرده‌اید (callback_data). این کیبوردها برای منوهای تعاملی، سیستم‌های تأیید/رد، و بازی‌ها ایده‌آل هستند.

    
    # ... (کدهای اولیه ربات) ...
    
    @bot.message_handler(commands=['inline_menu'])
    def show_inline_menu(message):
        chat_id = message.chat.id
    
        markup = types.InlineKeyboardMarkup(row_width=2) # دو دکمه در هر سطر
        itembtn1 = types.InlineKeyboardButton('گزینه الف', callback_data='option_A')
        itembtn2 = types.InlineKeyboardButton('گزینه ب', callback_data='option_B')
        itembtn3 = types.InlineKeyboardButton('بازدید از سایت', url='https://www.google.com')
        itembtn4 = types.InlineKeyboardButton('اطلاعات بیشتر', callback_data='more_info')
        
        markup.add(itembtn1, itembtn2, itembtn3, itembtn4)
    
        bot.send_message(chat_id, "لطفاً یکی از گزینه‌های Inline را انتخاب کنید:", reply_markup=markup)
    
    @bot.callback_query_handler(func=lambda call: True)
    def handle_inline_buttons(call):
        """
        هندلر برای Callback Query ها از Inline Keyboards.
        """
        chat_id = call.message.chat.id
        message_id = call.message.message_id
        user_id = call.from_user.id
        callback_data = call.data
    
        print(f"Callback Query از کاربر {user_id}: {callback_data}")
    
        if callback_data == 'option_A':
            response_text = "شما گزینه الف را انتخاب کردید."
        elif callback_data == 'option_B':
            response_text = "شما گزینه ب را انتخاب کردید."
        elif callback_data == 'more_info':
            response_text = "اینجا می‌توانید اطلاعات بیشتری را مشاهده کنید. لطفاً گزینه بعدی را انتخاب کنید."
            # می‌توانیم یک کیبورد Inline جدید برای پاسخ ارسال کنیم یا پیام قبلی را ویرایش کنیم.
            new_markup = types.InlineKeyboardMarkup(row_width=1)
            new_markup.add(types.InlineKeyboardButton('بازگشت به منو اصلی', callback_data='main_menu'))
            bot.edit_message_text(
                chat_id=chat_id,
                message_id=message_id,
                text=response_text,
                reply_markup=new_markup
            )
            bot.answer_callback_query(call.id, text=response_text) # نمایش یک اعلان موقت به کاربر
            return # برای جلوگیری از ارسال پیام تکراری
        elif callback_data == 'main_menu':
            response_text = "به منو اصلی بازگشتید."
            show_inline_menu(call.message) # مجدداً منوی inline اصلی را نمایش می‌دهد.
            bot.answer_callback_query(call.id, text=response_text)
            return
        else:
            response_text = "گزینه نامشخص."
        
        # ویرایش پیام قبلی برای نشان دادن تغییر
        bot.edit_message_text(
            chat_id=chat_id,
            message_id=message_id,
            text=f"{call.message.text}\n\n**پاسخ:** {response_text}",
            parse_mode='Markdown' # یا 'HTML'
        )
        
        # ارسال یک پاسخ (Alert یا Toast) به کاربر پس از کلیک بر روی دکمه
        # این پاسخ برای کاربر به صورت موقت نمایش داده می‌شود.
        bot.answer_callback_query(call.id, text=f"شما {callback_data} را انتخاب کردید!", show_alert=False) # show_alert=True برای نمایش پاپ‌آپ
    
    # ... (ادامه کدهای ربات و bot.polling) ...
    

    ویژگی‌های مهم InlineKeyboardMarkup:

    • InlineKeyboardButton: کلاس برای ایجاد دکمه‌های Inline.
      • text: متن نمایش داده شده روی دکمه.
      • callback_data: داده‌ای که هنگام کلیک کاربر به ربات ارسال می‌شود (حداکثر 64 بایت).
      • url: یک URL که با کلیک روی دکمه باز می‌شود.
      • login_url: برای ورود به وب‌سایت‌ها از طریق تلگرام (پیشرفته‌تر).
      • switch_inline_query: برای شروع یک کوئری Inline (برای ربات‌های Inline).
    • @bot.callback_query_handler(func=lambda call: True): این هندلر تمامی CallbackQueryها را دریافت می‌کند. شیء call حاوی اطلاعاتی مانند call.data (داده‌های دکمه)، call.message (پیامی که دکمه به آن متصل است)، و call.from_user است.
    • bot.answer_callback_query(call.id, text="...", show_alert=False): بسیار مهم است که پس از دریافت هر CallbackQuery، حتماً با این متد به آن پاسخ دهید. اگر این کار را نکنید، دکمه برای کاربر همچنان در حالت “loading” باقی می‌ماند. text پیامی است که به کاربر نمایش داده می‌شود و show_alert=True آن را به صورت یک پاپ‌آپ بزرگ نشان می‌دهد.
    • bot.edit_message_text()، bot.edit_message_reply_markup(): می‌توانید پیام قبلی (که دکمه‌ها به آن متصل بودند) را ویرایش کنید تا تغییرات را به کاربر نشان دهید، به جای ارسال یک پیام جدید. این کار تجربه کاربری را بهبود می‌بخشد.

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

    بهینه‌سازی و نکات پیشرفته

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

    مدیریت خطاها و لاگ‌گیری

    هیچ نرم‌افزاری بدون خطا نیست، و ربات‌های تلگرام نیز از این قاعده مستثنی نیستند. خطاهایی مانند مشکلات شبکه، درخواست‌های API نامعتبر، یا خطاهای منطقی در کد شما می‌توانند رخ دهند. مدیریت صحیح خطاها و ثبت لاگ (Logging) مناسب به شما کمک می‌کند تا این مشکلات را شناسایی، رفع و از بروز مجدد آن‌ها جلوگیری کنید.

    مدیریت خطاها با try-except:

    هر جا که با API تلگرام تعامل دارید (مانند bot.send_message)، بهتر است آن را در بلاک try-except قرار دهید تا خطاهای احتمالی را مدیریت کنید. pyTelegramBotAPI خطاهای API را به صورت telebot.apihelper.ApiTelegramException برمی‌گرداند.

    
    import telebot
    from telebot import apihelper
    import logging
    
    TOKEN = "YOUR_BOT_TOKEN_HERE"
    bot = telebot.TeleBot(TOKEN)
    
    # پیکربندی اولیه برای لاگ‌گیری
    logging.basicConfig(
        level=logging.INFO, # سطوح: DEBUG, INFO, WARNING, ERROR, CRITICAL
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler("bot.log", encoding='utf-8'), # ذخیره لاگ در فایل
            logging.StreamHandler() # نمایش لاگ در کنسول
        ]
    )
    
    logger = logging.getLogger(__name__)
    
    @bot.message_handler(commands=['error_example'])
    def handle_error_example(message):
        chat_id = message.chat.id
        # مثال: تلاش برای ارسال پیام به یک چت نامعتبر (فقط برای تست)
        invalid_chat_id = 12345 
    
        try:
            bot.send_message(chat_id, "در حال تلاش برای انجام یک عملیات...")
            # عملیاتی که ممکن است خطا ایجاد کند
            bot.send_message(invalid_chat_id, "این پیام نباید ارسال شود!", parse_mode='InvalidParseMode') # intentional error
            logger.info(f"پیام به چت نامعتبر ارسال شد! (این نباید اتفاق بیفتد)")
    
        except apihelper.ApiTelegramException as e:
            logger.error(f"خطای API تلگرام در چت {chat_id}: {e}")
            if e.error_code == 400 and "Bad Request: message parse_mode is invalid" in e.description:
                bot.send_message(chat_id, "خطا در قالب‌بندی پیام شما رخ داد. لطفاً فرمت را بررسی کنید.")
            elif e.error_code == 400 and "chat not found" in e.description:
                bot.send_message(chat_id, "متاسفانه نمی‌توانم به آن چت پیامی ارسال کنم.")
            else:
                bot.send_message(chat_id, "متاسفانه خطایی در ارتباط با تلگرام رخ داد.")
        except Exception as e:
            logger.critical(f"خطای غیرمنتظره در چت {chat_id}: {e}", exc_info=True)
            bot.send_message(chat_id, "یک خطای داخلی در ربات رخ داد. لطفاً بعداً دوباره امتحان کنید.")
    
    @bot.message_handler(commands=['log_test'])
    def handle_log_test(message):
        logger.debug(f"یک پیام DEBUG از {message.from_user.first_name}")
        logger.info(f"یک پیام INFO از {message.from_user.first_name}")
        logger.warning(f"یک پیام WARNING از {message.from_user.first_name}")
        logger.error(f"یک پیام ERROR از {message.from_user.first_name}")
        bot.send_message(message.chat.id, "پیام‌های لاگ در کنسول/فایل ثبت شدند. سطوح مختلف را بررسی کنید.")
    
    # ... (ادامه کدهای ربات) ...
    
    if __name__ == '__main__':
        logger.info("ربات در حال راه‌اندازی است...")
        try:
            bot.polling(none_stop=True, interval=0, timeout=20)
        except Exception as e:
            logger.critical(f"ربات به دلیل خطای بحرانی متوقف شد: {e}", exc_info=True)
        finally:
            logger.info("ربات متوقف شد.")
    

    لاگ‌گیری (Logging) با ماژول logging پایتون:

    ماژول logging ابزاری استاندارد و قدرتمند برای ثبت رویدادها در برنامه‌های پایتون است. با استفاده از آن، می‌توانید اطلاعات مختلفی از جمله خطاهای سیستم، فعالیت‌های کاربر، و وضعیت ربات را ثبت کنید.

    • سطوح لاگ: DEBUG (جزئی‌ترین اطلاعات)، INFO (رویدادهای عادی)، WARNING (مشکلات احتمالی)، ERROR (خطاهای جدی)، CRITICAL (خطاهای بحرانی که باعث توقف برنامه می‌شوند).
    • در مثال بالا، logging.basicConfig برای تنظیم لاگ‌گیری به گونه‌ای استفاده شده است که هم در کنسول نمایش داده شود و هم در فایلی به نام bot.log ذخیره شود.
    • از logger.info()، logger.error() و غیره برای ثبت پیام‌ها استفاده کنید. پارامتر exc_info=True در logger.critical باعث می‌شود که Traceback کامل خطا نیز در لاگ ثبت شود.

    استفاده از وب‌هوک به جای پولینگ

    در بخش‌های قبلی، ربات ما با استفاده از متد bot.polling() کار می‌کرد. این روش برای توسعه و ربات‌های کوچک مناسب است، اما برای ربات‌های بزرگتر یا در محیط‌های تولیدی (Production)، وب‌هوک (Webhook) گزینه‌ی بهتری است.

    پولینگ (Polling):

    • نحوه کار: ربات شما به صورت دوره‌ای (مثلاً هر چند ثانیه یک بار) از سرور تلگرام می‌پرسد “آیا به‌روزرسانی جدیدی داری؟”.
    • مزایا: پیاده‌سازی ساده، عدم نیاز به سرور عمومی و SSL.
    • معایب:
      • مصرف منابع بیشتر: ربات دائماً درخواست ارسال می‌کند، حتی اگر پیامی نباشد.
      • تأخیر: بین دریافت پیام و پردازش آن ممکن است تأخیر وجود داشته باشد.
      • مقیاس‌پذیری محدود: برای ربات‌های با ترافیک بالا، می‌تواند ناکارآمد باشد.

    وب‌هوک (Webhook):

    • نحوه کار: شما یک URL به تلگرام می‌دهید. هر زمان که به‌روزرسانی جدیدی برای ربات شما وجود داشته باشد، تلگرام آن به‌روزرسانی را به URL شما ارسال می‌کند. این روش “Push” نام دارد.
    • مزایا:
      • کارایی بالاتر: ربات فقط زمانی فعال می‌شود که پیامی دریافت کند.
      • پاسخ‌دهی سریع‌تر: بدون تأخیر ناشی از پولینگ.
      • مقیاس‌پذیری بهتر: مناسب برای ربات‌های با ترافیک بالا.
      • قابلیت ادغام با فریم‌ورک‌های وب مانند Flask یا Django.
    • معایب:
      • نیاز به یک سرور با آدرس IP عمومی (Public IP) و دامنه.
      • نیاز به گواهینامه SSL معتبر برای HTTPS.
      • پیچیدگی بیشتر در راه‌اندازی.

    تنظیم وب‌هوک با Telebot:

    برای استفاده از وب‌هوک، شما به یک سرور وب (مثلاً با Flask یا Django) نیاز دارید که بتواند درخواست‌های HTTP POST از تلگرام را دریافت کند. در اینجا یک مثال بسیار ساده با Flask ارائه می‌شود:

    
    from flask import Flask, request
    import telebot
    import logging
    import os
    
    TOKEN = "YOUR_BOT_TOKEN_HERE"
    WEBHOOK_HOST = 'YOUR_PUBLIC_IP_OR_DOMAIN' # آدرس IP یا دامنه عمومی سرور شما
    WEBHOOK_PORT = 8443 # پورت (تلگرام فقط پورت‌های 443, 80, 88, 8443 را پشتیبانی می‌کند)
    WEBHOOK_URL_BASE = f"https://{WEBHOOK_HOST}:{WEBHOOK_PORT}"
    WEBHOOK_URL_PATH = f"/{TOKEN}/" # مسیر وب‌هوک، می‌توان از توکن استفاده کرد تا منحصر به فرد باشد
    
    # پیکربندی لاگ‌گیری (مانند قبل)
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    logger = logging.getLogger(__name__)
    
    bot = telebot.TeleBot(TOKEN)
    app = Flask(__name__)
    
    @app.route(WEBHOOK_URL_PATH, methods=['POST'])
    def webhook():
        if request.headers.get('content-type') == 'application/json':
            json_string = request.get_data().decode('utf-8')
            update = telebot.types.Update.de_json(json_string)
            bot.process_new_updates([update])
            return '', 200
        else:
            logger.warning(f"درخواست وب‌هوک با نوع محتوای نامعتبر: {request.headers.get('content-type')}")
            return '', 403
    
    @bot.message_handler(commands=['start'])
    def send_welcome(message):
        bot.reply_to(message, "سلام! ربات شما در حالت وب‌هوک فعال است.")
    
    @bot.message_handler(func=lambda message: True)
    def echo_all(message):
        bot.reply_to(message, message.text)
    
    if __name__ == '__main__':
        # قبل از راه‌اندازی وب‌هوک، هر وب‌هوک قبلی را پاک کنید.
        bot.remove_webhook()
        logger.info("وب‌هوک‌های قبلی پاک شدند.")
    
        # تنظیم وب‌هوک جدید
        bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH)
        logger.info(f"وب‌هوک تنظیم شد: {WEBHOOK_URL_BASE + WEBHOOK_URL_PATH}")
    
        # برای HTTPS، شما نیاز به گواهینامه SSL دارید (مثلاً با Certbot یا گواهینامه‌های خودامضا برای توسعه)
        # در محیط Production، حتماً از گواهینامه معتبر استفاده کنید.
        # به عنوان مثال برای توسعه می‌توانید از گواهینامه‌های خودامضا استفاده کنید:
        # openssl req -newkey rsa:2048 -nodes -keyout webhook_pkey.pem -x509 -days 365 -out webhook_cert.pem
        # سپس Flask را با ssl_context اجرا کنید.
        # app.run(host='0.0.0.0', port=WEBHOOK_PORT, ssl_context=('webhook_cert.pem', 'webhook_pkey.pem'))
    
        # برای سادگی در این مثال، Flask بدون SSL اجرا می‌شود.
        # برای محیط Production باید حتما از SSL استفاده کنید (مثلاً با Nginx به عنوان Reverse Proxy)
        logger.info(f"سرور Flask در حال اجرا بر روی پورت {WEBHOOK_PORT} است...")
        app.run(host='0.0.0.0', port=WEBHOOK_PORT)
    

    نکات مهم برای وب‌هوک:

    • شما نیاز به یک دامنه یا آدرس IP عمومی و یک گواهینامه SSL معتبر (برای HTTPS) دارید.
    • تلگرام فقط به پورت‌های 443، 80، 88، 8443 درخواست ارسال می‌کند.
    • تابع webhook() مسئول دریافت درخواست‌های POST از تلگرام است و آن‌ها را به bot.process_new_updates() می‌فرستد.
    • پاک کردن وب‌هوک‌های قبلی با bot.remove_webhook() و تنظیم وب‌هوک جدید با bot.set_webhook() ضروری است.
    • در محیط تولیدی، معمولاً Flask/Django را مستقیماً اجرا نمی‌کنند، بلکه از یک وب‌سرور مانند Nginx به عنوان Reverse Proxy استفاده کرده و درخواست‌ها را به برنامه پایتون (که با Gunicorn یا uWSGI اجرا می‌شود) منتقل می‌کنند.

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

    نتیجه‌گیری و چشم‌انداز آینده

    در این راهنمای جامع، ما به تفصیل به بررسی چگونگی ساخت یک ربات پیام‌رسان ساده با استفاده از کتابخانه Telebot (pyTelegramBotAPI) پرداختیم. از مراحل اولیه راه‌اندازی و نصب کتابخانه گرفته تا دریافت توکن از BotFather، ساختاردهی اصلی ربات، و پیاده‌سازی هندلرهای پیچیده برای انواع مختلف پیام‌ها، هر گام به صورت عملی و با مثال‌های کد پایتون تشریح شد. ما همچنین روش‌های متنوع ارسال پیام، از متن ساده تا رسانه‌ها و لینک‌های تعاملی، و همچنین اهمیت مدیریت وضعیت و پاسخ‌های هوشمندانه با استفاده از Reply Keyboards و Inline Keyboards را پوشش دادیم. در نهایت، با بحث در مورد مدیریت خطا، لاگ‌گیری و تفاوت‌های پولینگ و وب‌هوک، مسیر بهینه‌سازی و آماده‌سازی ربات برای محیط‌های تولیدی را نیز روشن ساختیم.

    Telebot با طراحی ساده و قدرت بالای خود، ابزاری بی‌نظیر برای توسعه‌دهندگانی است که می‌خواهند به سرعت و به آسانی ربات‌های تلگرام را با پایتون ایجاد کنند. این کتابخانه به شما اجازه می‌دهد تا بدون درگیر شدن با جزئیات سطح پایین API تلگرام، بر روی منطق کسب‌وکار و تجربه کاربری ربات خود تمرکز کنید.

    چشم‌انداز آینده:

    مفاهیم و تکنیک‌هایی که در این مقاله آموختید، تنها آغاز راه برای ساخت ربات‌های بسیار قدرتمندتر و پیچیده‌تر هستند. شما می‌توانید با ادغام Telebot با فناوری‌های دیگر، قابلیت‌های ربات خود را به شکل چشمگیری گسترش دهید:

    • پایگاه داده‌ها: برای ذخیره اطلاعات کاربر، تنظیمات، تاریخچه چت، و سایر داده‌های ربات (مانند SQLite، PostgreSQL، MongoDB) استفاده کنید تا ربات بتواند اطلاعات را به صورت مداوم ذخیره و بازیابی کند.
    • APIهای خارجی: ربات خود را به APIهای خارجی متصل کنید تا قابلیت‌هایی مانند نمایش آب و هوا، نرخ ارز، اخبار، جستجو در وب، یا حتی پرداخت‌های آنلاین را ارائه دهد.
    • پردازش زبان طبیعی (NLP) و هوش مصنوعی: با ادغام کتابخانه‌هایی مانند spaCy، NLTK، یا سرویس‌هایی مانند Google Dialogflow، می‌توانید ربات‌هایی بسازید که پیام‌های کاربران را درک کرده و پاسخ‌های هوشمندانه‌تری ارائه دهند.
    • زمان‌بندی وظایف: برای ارسال پیام‌های زمان‌بندی شده، یادآوری‌ها یا گزارش‌های دوره‌ای، از ماژول‌هایی مانند APScheduler استفاده کنید.
    • استقرار (Deployment): ربات خود را بر روی سرورهای ابری (مانند Heroku, AWS, Google Cloud, DigitalOcean) مستقر کنید تا به صورت ۲۴/۷ در دسترس باشد.
    • کانال‌ها و گروه‌ها: از قابلیت‌های پیشرفته تلگرام برای مدیریت ربات‌ها در کانال‌ها و گروه‌ها، از جمله مدیریت اعضا، ارسال پیام‌های مدیریتی، و استفاده از قابلیت‌های مدیریتی ربات (Admin Bots) بهره ببرید.

    با تسلط بر اصول ارائه شده در این مقاله و کنجکاوی برای یادگیری بیشتر، می‌توانید به یک توسعه‌دهنده ربات تلگرام ماهر تبدیل شوید و ابزارهایی خلاقانه و کاربردی را برای خود، کسب‌وکارتان یا جامعه به ارمغان بیاورید. کدنویسی را آغاز کنید و از اکتشاف دنیای بی‌کران ربات‌های تلگرام لذت ببرید!

“تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT”

قیمت اصلی 2.290.000 ریال بود.قیمت فعلی 1.590.000 ریال است.

"تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT"

"با شرکت در این دوره جامع و کاربردی، به راحتی مهارت‌های برنامه‌نویسی پایتون را از سطح مبتدی تا پیشرفته با کمک هوش مصنوعی ChatGPT بیاموزید. این دوره، با بیش از 6 ساعت محتوای آموزشی، شما را قادر می‌سازد تا به سرعت الگوریتم‌های پیچیده را درک کرده و اپلیکیشن‌های هوشمند ایجاد کنید. مناسب برای تمامی سطوح با زیرنویس فارسی حرفه‌ای و امکان دانلود و تماشای آنلاین."

ویژگی‌های کلیدی:

بدون نیاز به تجربه قبلی برنامه‌نویسی

زیرنویس فارسی با ترجمه حرفه‌ای

۳۰ ٪ تخفیف ویژه برای دانشجویان و دانش آموزان