شروع کار با Telebot: راهنمای جامع ساخت اولین ربات تلگرام

فهرست مطالب

شروع کار با Telebot: راهنمای جامع ساخت اولین ربات تلگرام

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

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

مقدمه: چرا تلگرام و چرا Telebot؟

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

مزایای ربات‌های تلگرام

  • اتوماسیون: ربات‌ها می‌توانند وظایف تکراری را به صورت خودکار انجام دهند و زمان زیادی را برای کاربران و مدیران صرفه‌جویی کنند.
  • مقیاس‌پذیری: یک ربات می‌تواند همزمان با هزاران کاربر تعامل داشته باشد، بدون اینکه نیاز به مداخله انسانی زیادی باشد.
  • یکپارچگی: ربات‌ها می‌توانند با سرویس‌های خارجی مختلفی یکپارچه شوند و امکانات جدیدی را به تلگرام اضافه کنند (مانند نمایش آب‌وهوا، نرخ ارز، یا جستجو در ویکی‌پدیا).
  • ۲۴/۷: ربات‌ها ۲۴ ساعت شبانه‌روز و ۷ روز هفته در دسترس هستند.

چرا پایتون برای توسعه ربات؟

پایتون به دلیل مزایای زیر، انتخابی عالی برای توسعه ربات‌های تلگرام است:

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

معرفی Telebot (pyTelegramBotAPI)

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

  • سادگی در استفاده: Telebot یک API بسیار ساده و شهودی را فراهم می‌کند که حتی برای برنامه‌نویسان مبتدی نیز قابل درک است. تعریف هندلرها (handler) برای پیام‌ها و دستورات مختلف با استفاده از دکوراتورها (decorators) بسیار آسان است.
  • جامعیت: این کتابخانه تقریباً تمام قابلیت‌های API رسمی تلگرام را پوشش می‌دهد، از ارسال انواع پیام‌ها (متن، عکس، ویدئو، داکیومنت) گرفته تا کار با کیبوردهای سفارشی، پیام‌های درون‌خطی (inline queries) و Callback Queryها.
  • مستندات قوی: Telebot دارای مستندات بسیار خوبی است که به شما در یادگیری و رفع مشکلات کمک می‌کند.
  • فعالیت و به‌روزرسانی: این کتابخانه به طور فعال نگهداری و به‌روزرسانی می‌شود، به این معنی که با آخرین تغییرات API تلگرام سازگار است و مشکلات احتمالی به سرعت برطرف می‌شوند.

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

پیش‌نیازها و آماده‌سازی محیط توسعه

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

۱. نصب پایتون

Telebot با پایتون 3 کار می‌کند. توصیه می‌شود از آخرین نسخه پایدار پایتون 3 (مثلاً 3.8 به بالا) استفاده کنید. اگر پایتون از قبل روی سیستم شما نصب نیست، می‌توانید آن را از وب‌سایت رسمی پایتون دانلود و نصب کنید:

  • به آدرس https://www.python.org/downloads/ مراجعه کنید.
  • نسخه مناسب سیستم‌عامل خود (ویندوز، مک، لینوکس) را دانلود کنید.
  • در هنگام نصب در ویندوز، حتماً تیک گزینه “Add Python to PATH” را بزنید. این کار به شما امکان می‌دهد تا پایتون را از طریق خط فرمان (Command Prompt یا PowerShell) به راحتی اجرا کنید.

برای بررسی نصب صحیح پایتون و اطمینان از اینکه به PATH اضافه شده است، ترمینال یا Command Prompt را باز کرده و دستورات زیر را اجرا کنید:


python --version
pip --version

باید نسخه‌های نصب شده پایتون و pip (مدیریت بسته پایتون) را مشاهده کنید. اگر خطایی دریافت کردید، به احتمال زیاد پایتون به درستی نصب نشده یا به PATH اضافه نشده است.

۲. انتخاب ویرایشگر کد یا IDE

برای نوشتن کدهای پایتون، به یک ویرایشگر کد یا محیط توسعه یکپارچه (IDE) نیاز دارید. برخی از گزینه‌های محبوب عبارتند از:

  • VS Code (Visual Studio Code): یک ویرایشگر کد سبک و قدرتمند از مایکروسافت با پشتیبانی عالی از پایتون از طریق افزونه‌ها.
  • PyCharm: یک IDE کامل و بسیار قدرتمند برای توسعه پایتون از JetBrains. نسخه‌ی Community آن رایگان است و برای پروژه‌های کوچک و متوسط بسیار مناسب است.
  • Sublime Text: یک ویرایشگر کد سریع و با قابلیت سفارشی‌سازی بالا.
  • Atom: یک ویرایشگر کد مدرن و قابل هک از GitHub.

انتخاب ویرایشگر بستگی به سلیقه و نیازهای شما دارد. برای شروع، VS Code یا PyCharm Community Edition گزینه‌های بسیار خوبی هستند.

۳. ایجاد محیط مجازی (Virtual Environment)

استفاده از محیط مجازی یک بهترین شیوه (best practice) در توسعه پایتون است. محیط مجازی یک پوشه ایزوله ایجاد می‌کند که در آن می‌توانید کتابخانه‌های مورد نیاز پروژه خود را نصب کنید، بدون اینکه با کتابخانه‌های جهانی سیستم یا پروژه‌های دیگر تداخل پیدا کند. این کار به مدیریت وابستگی‌ها کمک کرده و از بروز مشکلات در آینده جلوگیری می‌کند.

برای ایجاد یک محیط مجازی با venv (که همراه با پایتون نصب می‌شود)، مراحل زیر را دنبال کنید:

  1. یک پوشه برای پروژه ربات خود ایجاد کنید. مثلاً my_telegram_bot.
  2. ترمینال یا Command Prompt را باز کرده و به داخل این پوشه بروید:
  3. 
        cd my_telegram_bot
        
  4. یک محیط مجازی با نام دلخواه (مثلاً venv) ایجاد کنید:
  5. 
        python -m venv venv
        
  6. محیط مجازی را فعال کنید:
    • ویندوز:
    • 
              .\venv\Scripts\activate
              
    • مک/لینوکس:
    • 
              source venv/bin/activate
              

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

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

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

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

گام به گام دریافت توکن:

  1. جستجو و شروع مکالمه با BotFather:
    • تلگرام را باز کنید و در قسمت جستجو، @BotFather را تایپ کنید.
    • BotFather را که دارای تیک آبی تأیید شده است، انتخاب کنید.
    • روی دکمه “Start” یا “شروع” کلیک کنید تا مکالمه با BotFather آغاز شود.
  2. ایجاد یک ربات جدید:
    • پس از شروع مکالمه، BotFather لیستی از دستورات را به شما نمایش می‌دهد. برای ایجاد یک ربات جدید، دستور /newbot را تایپ کرده و ارسال کنید.
  3. انتخاب نام برای ربات:
    • BotFather از شما می‌خواهد که یک نام (Name) برای ربات خود انتخاب کنید. این نام چیزی است که کاربران در لیست مخاطبین خود یا در بالای چت با ربات شما خواهند دید (مثلاً: “ربات من”). می‌توانید هر نامی را انتخاب کنید.
    • پس از وارد کردن نام، آن را ارسال کنید.
  4. انتخاب نام کاربری (Username) برای ربات:
    • حالا باید یک نام کاربری (Username) منحصر به فرد برای ربات خود انتخاب کنید. این نام کاربری باید حداقل ۵ کاراکتر باشد، فقط شامل حروف لاتین، اعداد و زیرخط _ باشد و حتماً با bot یا _bot به پایان برسد (مثلاً: my_first_telebot یا MyFirstTelebotBot).
    • این نام کاربری همان چیزی است که کاربران برای پیدا کردن ربات شما از آن استفاده می‌کنند (مانند @MyFirstTelebotBot).
    • پس از وارد کردن نام کاربری، آن را ارسال کنید.
  5. دریافت توکن API:
    • اگر نام کاربری شما معتبر و منحصر به فرد باشد، BotFather با پیامی حاوی تبریک، نام ربات و مهم‌تر از همه، توکن API آن (یک رشته بلند از حروف و اعداد) به شما پاسخ خواهد داد.
    • این توکن چیزی شبیه به 123456789:AAH-g3u3o3j3-j3e3r3o3k3l3 خواهد بود.
  6. ذخیره و محافظت از توکن:
    • این توکن را با دقت کپی کنید و در مکانی امن نگه دارید. توکن ربات شما مانند رمز عبور آن است. اگر توکن شما به دست افراد ناشناس بیفتد، آنها می‌توانند کنترل ربات شما را به دست بگیرند و از آن سوءاستفاده کنند.
    • هرگز توکن خود را در کدهای عمومی (مانند GitHub) قرار ندهید یا آن را با کسی به اشتراک نگذارید. بهترین روش این است که توکن را به عنوان یک متغیر محیطی (environment variable) یا در یک فایل پیکربندی جداگانه (که در کنترل نسخه قرار نمی‌گیرد) ذخیره کنید.

سایر دستورات مفید BotFather:

  • /mybots: لیستی از تمام ربات‌های شما را نمایش می‌دهد.
  • /setname: نام نمایش ربات را تغییر می‌دهد.
  • /setdescription: توضیحاتی را برای ربات شما تنظیم می‌کند که در صفحه اطلاعات ربات نمایش داده می‌شود.
  • /setabouttext: متنی را برای بخش “About” ربات تنظیم می‌کند.
  • /setuserpic: عکس پروفایل ربات را تغییر می‌دهد.
  • /setcommands: لیست دستورات (مانند /start، /help) ربات را برای نمایش در رابط کاربری تلگرام تنظیم می‌کند. این کار به کاربران کمک می‌کند تا از دستورات ربات شما مطلع شوند.
  • /token: توکن API ربات موجود را به شما می‌دهد.
  • /revoke: توکن API یک ربات را باطل کرده و یک توکن جدید صادر می‌کند. از این دستور در صورتی استفاده کنید که فکر می‌کنید توکن شما به خطر افتاده است.

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

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

پس از آماده‌سازی محیط توسعه و دریافت توکن ربات از BotFather، گام بعدی نصب کتابخانه pyTelegramBotAPI (Telebot) در محیط مجازی پروژه شما است. این کار بسیار ساده است و فقط با یک دستور pip انجام می‌شود.

مراحل نصب:

  1. اطمینان از فعال بودن محیط مجازی:

    قبل از نصب، مطمئن شوید که محیط مجازی خود را فعال کرده‌اید. اگر محیط مجازی venv را در پوشه پروژه my_telegram_bot ایجاد کرده‌اید، ترمینال یا Command Prompt را باز کرده، به آن پوشه بروید و دستور فعال‌سازی را اجرا کنید:

    • ویندوز:
    • 
                  cd my_telegram_bot
                  .\venv\Scripts\activate
                  
    • مک/لینوکس:
    • 
                  cd my_telegram_bot
                  source venv/bin/activate
                  

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

  2. نصب Telebot با pip:

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

    
            pip install pyTelegramBotAPI
            

    pip به صورت خودکار آخرین نسخه پایدار Telebot را دانلود و نصب خواهد کرد. خروجی ترمینال شما باید نشان‌دهنده موفقیت‌آمیز بودن نصب باشد.

  3. بررسی نصب (اختیاری):

    برای اطمینان از اینکه Telebot به درستی نصب شده است، می‌توانید یک جلسه پایتون (Python shell) را در ترمینال خود آغاز کرده و سعی کنید کتابخانه را import کنید:

    
            python
            >>> import telebot
            >>>
            

    اگر هیچ خطایی نمایش داده نشد و علامت >>> دوباره ظاهر شد، به این معنی است که Telebot با موفقیت نصب شده است و آماده استفاده است. برای خروج از Python shell، دستور exit() را وارد کرده و Enter را بزنید.

  4. ذخیره وابستگی‌ها (Dependencies):

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

    
            pip freeze > requirements.txt
            

    این دستور یک فایل به نام requirements.txt در پوشه پروژه شما ایجاد می‌کند که حاوی نام و نسخه Telebot (و هر کتابخانه دیگری که نصب کرده‌اید) خواهد بود.

تبریک! اکنون Telebot با موفقیت در محیط توسعه شما نصب شده است. در بخش بعدی، شروع به نوشتن کد برای ساخت اولین ربات “Hello World” خود خواهیم کرد و مفاهیم اولیه را پوشش می‌دهیم.

ساخت اولین ربات: Hello World با Telebot

حالا که تمام پیش‌نیازها آماده شده و Telebot نیز نصب شده است، زمان آن رسیده که دست به کار شویم و اولین ربات تلگرام خود را بسازیم. این ربات ساده تنها به پیام /start و سایر پیام‌های متنی پاسخ خواهد داد. این بخش به شما اصول اولیه ساخت ربات با Telebot را آموزش می‌دهد.

ساختار پایه کد ربات:

  1. ایجاد فایل کد:

    در پوشه پروژه خود (my_telegram_bot)، یک فایل پایتون جدید ایجاد کنید. مثلاً bot.py.

  2. وارد کردن کتابخانه و تعریف توکن:

    ابتدا باید کتابخانه telebot را وارد (import) کنید و توکن ربات خود را تعریف کنید. هرگز توکن خود را مستقیماً در کد قرار ندهید. بهترین روش این است که آن را از یک متغیر محیطی یا یک فایل پیکربندی جداگانه (مثلاً config.py که در .gitignore اضافه شده است) بخوانید. برای سادگی در این آموزش، آن را از یک فایل config.py فرضی می‌خوانیم. پس یک فایل config.py در کنار bot.py بسازید و توکن را در آن قرار دهید:

    
    # config.py
    API_TOKEN = 'YOUR_BOT_TOKEN_HERE' # توکن واقعی خود را اینجا قرار دهید
            

    سپس در bot.py:

    
    # bot.py
    import telebot
    from config import API_TOKEN
    
    # ایجاد نمونه ربات
    bot = telebot.TeleBot(API_TOKEN)
            

    telebot.TeleBot(API_TOKEN) نمونه‌ای از ربات شما را ایجاد می‌کند که از این به بعد برای ارسال و دریافت پیام‌ها از آن استفاده خواهیم کرد.

  3. تعریف Message Handler‌ها:

    Message Handlerها توابعی هستند که Telebot آن‌ها را فراخوانی می‌کند هرگاه ربات شما پیامی را دریافت کند که با معیارهای خاصی مطابقت داشته باشد. برای تعریف یک هندلر، از دکوراتور @bot.message_handler() استفاده می‌کنیم.

    • هندلر دستور /start:

      این هندلر به پیامی که شامل دستور /start باشد، پاسخ می‌دهد. این اولین دستوری است که کاربران معمولاً با ربات شما تعامل می‌کنند.

      
      # bot.py ادامه...
      
      @bot.message_handler(commands=['start'])
      def send_welcome(message):
          bot.reply_to(message, "سلام! به ربات تلگرام من خوش آمدید. چگونه می‌توانم کمک کنم؟")
                      

      در اینجا:

      • @bot.message_handler(commands=['start']): این خط یک دکوراتور است که تابع send_welcome را به عنوان یک هندلر برای دستور /start ثبت می‌کند.
      • def send_welcome(message):: این تابع پیام ورودی را به عنوان یک آرگومان (message) دریافت می‌کند.
      • bot.reply_to(message, "..."): این متد پیامی را به کاربر پاسخ می‌دهد. message آرگومان اول است تا ربات بداند به کدام پیام پاسخ دهد، و آرگومان دوم متن پاسخ است.
    • هندلر پیام‌های متنی عمومی:

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

      
      # bot.py ادامه...
      
      @bot.message_handler(func=lambda message: True) # این هندلر به هر پیام متنی پاسخ می‌دهد
      def echo_all(message):
          bot.reply_to(message, message.text)
                      

      در اینجا:

      • @bot.message_handler(func=lambda message: True): این دکوراتور هر پیامی را که تابع lambda message: True برای آن True برگرداند، مدیریت می‌کند. این یک فیلتر عمومی است که به تمام پیام‌ها اجازه عبور می‌دهد (البته بعد از هندلرهای دیگر با فیلترهای خاص‌تر).
      • echo_all(message):: این تابع پیام را به همان شکلی که دریافت کرده است، به کاربر بازمی‌گرداند (echo).
      • message.text: این ویژگی حاوی متن پیام ارسال شده توسط کاربر است.
  4. شروع Polling:

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

    
    # bot.py ادامه...
    
    if __name__ == '__main__':
        print("ربات در حال اجرا است...")
        bot.polling(none_stop=True)
            

    در اینجا:

    • if __name__ == '__main__':: این یک استاندارد پایتون است که اطمینان حاصل می‌کند کد داخل بلوک فقط زمانی اجرا می‌شود که اسکریپت به صورت مستقیم اجرا شود، نه زمانی که به عنوان ماژول وارد شود.
    • bot.polling(none_stop=True): این خط ربات را به حالت polling می‌برد.
      • none_stop=True: این پارامتر تضمین می‌کند که ربات حتی در صورت بروز خطا، به polling ادامه دهد.
      • همچنین می‌توانید interval را برای تنظیم فاصله زمانی بین درخواست‌های polling (به ثانیه) و timeout را برای حداکثر زمان انتظار برای پاسخ از سرور تلگرام تنظیم کنید.

کد کامل bot.py (با فرض وجود config.py):


import telebot
from config import API_TOKEN # توکن ربات از فایل config.py خوانده می‌شود

# ایجاد نمونه ربات
bot = telebot.TeleBot(API_TOKEN)

# هندلر برای دستور /start
@bot.message_handler(commands=['start'])
def send_welcome(message):
    """
    هنگامی که کاربر دستور /start را ارسال می‌کند، یک پیام خوش‌آمدگویی می‌فرستد.
    """
    bot.reply_to(message, "سلام! به ربات تلگرام من خوش آمدید. چگونه می‌توانم کمک کنم؟")

# هندلر برای تمام پیام‌های متنی (به جز دستورات خاصی که قبلا هندل شده‌اند)
@bot.message_handler(func=lambda message: True)
def echo_all(message):
    """
    پیام متنی کاربر را تکرار می‌کند (echo).
    این هندلر به تمام پیام‌های متنی که توسط هندلرهای دیگر مدیریت نمی‌شوند، پاسخ می‌دهد.
    """
    bot.reply_to(message, message.text)

# شروع Polling برای دریافت پیام‌ها
if __name__ == '__main__':
    print("ربات در حال اجرا است... برای توقف Ctrl+C را فشار دهید.")
    try:
        bot.polling(none_stop=True)
    except Exception as e:
        print(f"خطا در Polling: {e}")
        # می‌توانید در اینجا مکانیزمی برای راه‌اندازی مجدد یا لاگ کردن خطا اضافه کنید.

اجرای ربات:

برای اجرای ربات خود، ترمینال یا Command Prompt را باز کرده، به پوشه پروژه خود بروید و مطمئن شوید محیط مجازی فعال است. سپس دستور زیر را اجرا کنید:


python bot.py

شما باید پیام “ربات در حال اجرا است…” را مشاهده کنید. حالا تلگرام را باز کرده، ربات خود را با نام کاربری که در BotFather انتخاب کرده‌اید جستجو کنید (مثلاً @MyFirstTelebotBot) و با آن چت کنید. دستور /start را ارسال کنید و سپس پیام‌های متنی مختلف بفرستید تا پاسخ‌های ربات را مشاهده کنید.

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

آشنایی عمیق‌تر با Message Handler‌ها و فیلترها

Message Handler‌ها در Telebot نقش کلیدی در مسیریابی پیام‌های ورودی به توابع مناسب ایفا می‌کنند. هر هندلر با استفاده از دکوراتور @bot.message_handler() تعریف می‌شود و می‌تواند با استفاده از فیلترهای مختلف، نوع خاصی از پیام‌ها را هدف قرار دهد. درک صحیح این فیلترها به شما کمک می‌کند تا ربات‌هایی هوشمندتر و با واکنش‌های دقیق‌تر بسازید.

انواع فیلترها در @bot.message_handler():

۱. فیلتر commands:

این فیلتر برای مدیریت دستورات خاص (که با / شروع می‌شوند) طراحی شده است. شما می‌توانید یک یا چند دستور را در قالب یک لیست به آن بدهید.


@bot.message_handler(commands=['help', 'about'])
def send_help_about(message):
    if message.text == '/help':
        bot.send_message(message.chat.id, "این ربات به شما در کارهای مختلف کمک می‌کند.")
    elif message.text == '/about':
        bot.send_message(message.chat.id, "این ربات توسط [نام شما] ساخته شده است.")

نکات:

  • message.chat.id: شناسه عددی چت فعلی را برمی‌گرداند. این برای ارسال پیام به یک چت خاص استفاده می‌شود.
  • می‌توانید دستورات را با یا بدون / در لیست commands قرار دهید، اما بهترین عمل این است که آن‌ها را بدون / قرار دهید و Telebot خودش / را در زمان مقایسه اضافه می‌کند.
  • ترتیب هندلرها مهم است. هندلرهای خاص‌تر باید قبل از هندلرهای عمومی‌تر قرار گیرند.

۲. فیلتر content_types:

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


@bot.message_handler(content_types=['text'])
def handle_text(message):
    bot.send_message(message.chat.id, "شما یک پیام متنی ارسال کردید!")

@bot.message_handler(content_types=['photo'])
def handle_photo(message):
    bot.send_message(message.chat.id, "شما یک عکس ارسال کردید! ممنون.")
    # می‌توانید اطلاعات عکس را از message.photo دریافت کنید
    # مثلاً file_id = message.photo[-1].file_id برای بزرگترین سایز عکس

@bot.message_handler(content_types=['sticker'])
def handle_sticker(message):
    bot.send_sticker(message.chat.id, message.sticker.file_id) # استیکر را برمی‌گرداند

لیست کامل content_types:
text, photo, audio, document, sticker, video, voice, location, contact, new_chat_members, left_chat_member, new_chat_title, new_chat_photo, delete_chat_photo, group_chat_created, supergroup_chat_created, channel_chat_created, migrate_to_chat_id, migrate_from_chat_id, pinned_message, web_app_data, video_chat_scheduled, video_chat_started, video_chat_ended, video_chat_participants_invited, raw_message, message_auto_delete_timer_changed, forum_topic_created, forum_topic_edited, forum_topic_closed, forum_topic_reopened, general_forum_topic_hidden, general_forum_topic_unhidden, write_access_allowed, user_shared, chat_shared, story, giveaway_created, giveaway, giveaway_winners, giveaway_completed.

برای مدیریت همه انواع محتوا که قبلاً هندل نشده‌اند، می‌توانید از ['text', 'photo', 'video', 'sticker', 'audio', 'document', 'voice', 'location', 'contact', 'new_chat_members', 'left_chat_member'] یا به سادگی از ['all'] (که در نسخه‌های جدیدتر Telebot ممکن است به صورت خودکار تمام انواع را شامل شود) استفاده کنید، اما معمولاً بهتر است که انواع خاصی را مشخص کنید.

۳. فیلتر func:

این فیلتر بسیار قدرتمند و انعطاف‌پذیر است و به شما اجازه می‌دهد تا یک تابع سفارشی (یک تابع یا یک lambda) را برای بررسی مطابقت پیام با یک شرط خاص ارائه دهید. این تابع باید یک آرگومان (پیام) دریافت کند و True یا False برگرداند.


# هندلری که فقط به پیام‌هایی که شامل کلمه "سلام" هستند پاسخ می‌دهد
@bot.message_handler(func=lambda message: "سلام" in message.text)
def handle_salam(message):
    bot.send_message(message.chat.id, "سلام به شما دوست عزیز!")

# یا یک تابع معمولی:
def is_numeric(message):
    return message.text.isnumeric()

@bot.message_handler(func=is_numeric)
def handle_numeric(message):
    bot.send_message(message.chat.id, f"شما عدد {message.text} را ارسال کردید.")

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

۴. ترکیب فیلترها:

شما می‌توانید چندین فیلتر را در یک هندلر ترکیب کنید. Telebot به صورت منطقی AND بین آن‌ها عمل می‌کند، به این معنی که پیام باید تمام شرایط فیلترها را برآورده کند تا توسط آن هندلر پردازش شود.


# هندلری که فقط به دستور /vote پاسخ می‌دهد و فقط زمانی که پیام از یک گروه ارسال شده باشد.
@bot.message_handler(commands=['vote'], func=lambda message: message.chat.type == 'group')
def handle_group_vote(message):
    bot.send_message(message.chat.id, "دستور /vote فقط در گروه ها فعال است.")
    # منطق رأی‌گیری

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

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

  • هندلرهای خاص‌تر را در ابتدا قرار دهید: هندلرهایی که به دستورات خاص (/start، /help) یا انواع محتوای بسیار خاصی پاسخ می‌دهند، باید قبل از هندلرهای عمومی‌تر (مانند هندلر func=lambda message: True) تعریف شوند.
  • هندلر عمومی (Catch-all) را در انتها قرار دهید: هندلری که برای پاسخ به تمام پیام‌هایی که توسط هندلرهای قبلی مدیریت نشده‌اند (مانند func=lambda message: True یا content_types=['text'] به صورت تنها)، باید در انتهای لیست هندلرها باشد. این تضمین می‌کند که پیام‌های خاص ابتدا توسط هندلرهای مخصوص خود پردازش شوند و سپس پیام‌های باقیمانده به این هندلر عمومی برسند.

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

ارسال پیام‌ها و تعامل با کاربر

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

۱. ارسال پیام‌های متنی (bot.send_message):

این متد پایه برای ارسال متن است. آرگومان‌های اصلی آن chat_id (شناسه چت که پیام به آن ارسال می‌شود) و text (متن پیام) هستند.


@bot.message_handler(commands=['hello'])
def say_hello(message):
    user_name = message.from_user.first_name if message.from_user.first_name else "دوست"
    bot.send_message(message.chat.id, f"سلام، {user_name}! حالت چطوره؟")

تنظیمات پیشرفته متن: parse_mode

شما می‌توانید پیام‌های خود را با فرمت‌های مختلفی ارسال کنید. Telebot از MarkdownV2 و HTML پشتیبانی می‌کند.


# ارسال با MarkdownV2
@bot.message_handler(commands=['markdown'])
def send_markdown(message):
    markdown_text = "این یک پیام با فرمت *MarkdownV2* است.\n" \
                    "با استفاده از `تگ‌های Markdown` می‌توانید متن را **بولد** کنید یا _ایتالیک_.\n" \
                    "برای لینک‌ها: [گوگل](https://www.google.com)"
    bot.send_message(message.chat.id, markdown_text, parse_mode="MarkdownV2")

# ارسال با HTML
@bot.message_handler(commands=['html'])
def send_html(message):
    html_text = "این یک پیام با فرمت <b>HTML</b> است.
" \ "می‌توانید از تگ‌های HTML برای تلگرام استفاده کنید." bot.send_message(message.chat.id, html_text, parse_mode="HTML")

نکات مهم برای parse_mode:

  • برای MarkdownV2، برخی کاراکترها (مانند _, *, [, ], (, ), ~, `, >, #, +, -, =, |, {, }, ., !) نیاز به اسکیپ شدن (escape) با \ دارند مگر اینکه داخل تگ‌های فرمت‌دهی خاصی باشند.
  • برای HTML، کاراکترهای <, >, & باید به ترتیب به &lt;, &gt;, &amp; تبدیل شوند.

۲. ارسال انواع دیگر محتوا:

Telebot متدهای اختصاصی برای ارسال انواع مختلف فایل‌ها و محتوا دارد:

  • bot.send_photo(chat_id, photo, caption=None)
  • bot.send_audio(chat_id, audio, caption=None)
  • bot.send_document(chat_id, document, caption=None)
  • bot.send_video(chat_id, video, caption=None)
  • bot.send_sticker(chat_id, sticker)
  • bot.send_location(chat_id, latitude, longitude)
  • bot.send_contact(chat_id, phone_number, first_name)

برای ارسال فایل‌ها، می‌توانید file_id (اگر فایل قبلاً به تلگرام آپلود شده باشد) یا یک فایل باز شده (open('path/to/file', 'rb')) را به عنوان آرگومان photo/audio/document و … ارسال کنید.


# مثال ارسال عکس
@bot.message_handler(commands=['send_pic'])
def send_random_pic(message):
    # فرض کنید 'AgACAgIAAxkBA...' یک file_id از یک عکس آپلود شده باشد
    # یا می‌توانید از open('path/to/image.jpg', 'rb') استفاده کنید
    photo_id = 'AgACAgIAAxkBAAI...'
    bot.send_photo(message.chat.id, photo_id, caption="یک عکس زیبا!")

۳. کیبوردهای تعاملی (Reply Markups):

کیبوردها به کاربران کمک می‌کنند تا با گزینه‌های از پیش تعریف شده تعامل داشته باشند، به جای اینکه مجبور به تایپ کردن باشند. Telebot دو نوع اصلی کیبورد را پشتیبانی می‌کند:

الف) Reply Keyboard Markup (کیبورد پاسخ):

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


from telebot import types

@bot.message_handler(commands=['markup'])
def send_markup(message):
    markup = types.ReplyKeyboardMarkup(row_width=2, resize_keyboard=True, one_time_keyboard=True)
    itembtn1 = types.KeyboardButton('گزینه ۱')
    itembtn2 = types.KeyboardButton('گزینه ۲')
    itembtn3 = types.KeyboardButton('گزینه ۳')
    markup.add(itembtn1, itembtn2, itembtn3)
    bot.send_message(message.chat.id, "یکی از گزینه‌های زیر را انتخاب کنید:", reply_markup=markup)

@bot.message_handler(func=lambda message: message.text in ['گزینه ۱', 'گزینه ۲', 'گزینه ۳'])
def handle_markup_choice(message):
    if message.text == 'گزینه ۱':
        bot.send_message(message.chat.id, "شما گزینه ۱ را انتخاب کردید.")
    elif message.text == 'گزینه ۲':
        bot.send_message(message.chat.id, "شما گزینه ۲ را انتخاب کردید.")
    # می‌توانید کیبورد را حذف کنید
    # remove_markup = types.ReplyKeyboardRemove()
    # bot.send_message(message.chat.id, "کیبورد حذف شد.", reply_markup=remove_markup)

پارامترهای مهم ReplyKeyboardMarkup:

  • row_width: تعداد دکمه‌ها در هر سطر.
  • resize_keyboard=True: کیبورد را متناسب با ارتفاع صفحه کاربر تنظیم می‌کند.
  • one_time_keyboard=True: پس از کلیک کاربر بر روی یک دکمه، کیبورد پنهان می‌شود.
  • selective=True: این کیبورد فقط برای کاربرانی که ربات به آنها پاسخ داده نمایش داده می‌شود.

ب) Inline Keyboard Markup (کیبورد درون‌خطی):

این کیبورد مستقیماً زیر پیام ربات نمایش داده می‌شود و با پیام همراه است. دکمه‌های آن به جای ارسال پیام، یک Callback Query (اطلاعات کوچک) به ربات ارسال می‌کنند. این کیبورد پس از کلیک ناپدید نمی‌شود و می‌تواند برای انجام عملیات‌های پیچیده‌تر و تعاملات طولانی‌تر استفاده شود.


from telebot import types

@bot.message_handler(commands=['inline'])
def send_inline_markup(message):
    markup = types.InlineKeyboardMarkup(row_width=2)
    itembtn1 = types.InlineKeyboardButton("لینک به گوگل", url="https://www.google.com")
    itembtn2 = types.InlineKeyboardButton(" Callback 1", callback_data="cb_data1")
    itembtn3 = types.InlineKeyboardButton(" Callback 2", callback_data="cb_data2")
    markup.add(itembtn1, itembtn2, itembtn3)
    bot.send_message(message.chat.id, "یک گزینه را از کیبورد درون‌خطی انتخاب کنید:", reply_markup=markup)

# هندلر برای Callback Query ها
@bot.callback_query_handler(func=lambda call: True)
def callback_query(call):
    if call.data == "cb_data1":
        bot.answer_callback_query(call.id, "شما Callback 1 را انتخاب کردید!") # نمایش یک نوتیفیکیشن
        bot.send_message(call.message.chat.id, "این یک پاسخ به Callback 1 است.")
    elif call.data == "cb_data2":
        bot.answer_callback_query(call.id, " Callback 2 انتخاب شد.", show_alert=True) # نمایش یک پنجره پاپ‌آپ
        bot.edit_message_text(chat_id=call.message.chat.id,
                              message_id=call.message.message_id,
                              text="پیام ویرایش شد: شما Callback 2 را انتخاب کردید.",
                              reply_markup=call.message.reply_markup) # کیبورد را حفظ می‌کند

نکات مهم برای InlineKeyboardMarkup:

  • InlineKeyboardButton می‌تواند دارای url (باز کردن یک لینک)، callback_data (ارسال داده به ربات)، switch_inline_query (باز کردن جستجوی درون‌خطی) و … باشد.
  • callback_data باید یک رشته باشد و حداکثر ۶۴ بایت طول داشته باشد.
  • @bot.callback_query_handler(func=...) برای مدیریت Callback Query‌ها استفاده می‌شود.
  • bot.answer_callback_query(call.id, text, show_alert=False): ضروری است که به هر Callback Query پاسخ دهید، حتی اگر فقط یک پاسخ خالی باشد. این کار نوتیفیکیشن “در حال بارگذاری” را از روی دکمه حذف می‌کند و می‌تواند یک متن کوچک (toast) یا یک پنجره پاپ‌آپ (اگر show_alert=True باشد) نمایش دهد.
  • bot.edit_message_text یا bot.edit_message_reply_markup: می‌توانید پس از تعامل کاربر، پیام یا کیبورد درون‌خطی آن را ویرایش کنید.

۴. مدیریت ورودی مرحله‌ای (Step-by-step Input):

برای دریافت چندین ورودی از کاربر در یک فرآیند (مثلاً ثبت‌نام)، می‌توانید از bot.register_next_step_handler() استفاده کنید.


user_data = {}

@bot.message_handler(commands=['register'])
def register_step1(message):
    bot.send_message(message.chat.id, "لطفاً نام خود را وارد کنید:")
    bot.register_next_step_handler(message, register_step2)

def register_step2(message):
    user_data[message.chat.id] = {'name': message.text}
    bot.send_message(message.chat.id, "لطفاً سن خود را وارد کنید:")
    bot.register_next_step_handler(message, register_step3)

def register_step3(message):
    try:
        age = int(message.text)
        user_data[message.chat.id]['age'] = age
        bot.send_message(message.chat.id,
                         f"ثبت‌نام شما کامل شد! نام: {user_data[message.chat.id]['name']}, سن: {age}")
    except ValueError:
        bot.send_message(message.chat.id, "سن نامعتبر است. لطفاً یک عدد وارد کنید.")
        bot.register_next_step_handler(message, register_step3) # درخواست مجدد سن

نکات:

  • bot.register_next_step_handler(message, next_step_function): این متد به Telebot می‌گوید که پیام بعدی از این کاربر را به تابع next_step_function بفرستد، نه به هندلرهای عادی.
  • باید مراقب باشید که وضعیت کاربران را به درستی مدیریت کنید، به خصوص اگر ربات شما دچار خطا شود یا راه‌اندازی مجدد شود. برای مدیریت حالت‌های پیچیده‌تر، نیاز به استفاده از دیتابیس یا فریمورک‌های مدیریت وضعیت (مانند telebot.util.StateFilter یا FSM در کتابخانه‌های پیشرفته‌تر) خواهید داشت.

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

مدیریت وضعیت و داده‌ها

در ربات‌های ساده “Hello World”، هر تعامل کاربر مستقل از تعاملات قبلی او است. اما در ربات‌های پیچیده‌تر که نیاز به حفظ اطلاعات یا دنبال کردن یک جریان مکالمه دارند (مانند فرآیند ثبت‌نام، خرید، یا نظرسنجی)، لازم است وضعیت (state) کاربر و داده‌های مربوط به او را مدیریت کنیم. Telebot ابزارهایی برای این منظور ارائه می‌دهد و همچنین می‌توانید از راهکارهای سفارشی استفاده کنید.

۱. مدیریت وضعیت ساده در حافظه (In-Memory State):

برای ربات‌های کوچک و آزمایشی، می‌توانید وضعیت کاربران را در یک دیکشنری در حافظه نگهداری کنید. کلید این دیکشنری معمولاً chat_id یا user_id کاربر است و مقدار آن می‌تواند یک دیکشنری دیگر حاوی اطلاعات وضعیت فعلی کاربر باشد.


user_states = {} # {'chat_id': {'current_state': 'waiting_for_name', 'data': {}}}

@bot.message_handler(commands=['start_order'])
def start_order(message):
    user_states[message.chat.id] = {'current_state': 'waiting_for_item', 'data': {}}
    bot.send_message(message.chat.id, "سفارش جدید. چه کالایی می‌خواهید سفارش دهید؟")

@bot.message_handler(func=lambda message: user_states.get(message.chat.id, {}).get('current_state') == 'waiting_for_item')
def get_item(message):
    item = message.text
    user_states[message.chat.id]['data']['item'] = item
    user_states[message.chat.id]['current_state'] = 'waiting_for_quantity'
    bot.send_message(message.chat.id, f"شما '{item}' را انتخاب کردید. چه تعداد می‌خواهید؟")

@bot.message_handler(func=lambda message: user_states.get(message.chat.id, {}).get('current_state') == 'waiting_for_quantity')
def get_quantity(message):
    try:
        quantity = int(message.text)
        user_states[message.chat.id]['data']['quantity'] = quantity
        user_states[message.chat.id]['current_state'] = 'finished'
        
        item = user_states[message.chat.id]['data']['item']
        bot.send_message(message.chat.id,
                         f"سفارش شما: {quantity} عدد از {item} ثبت شد.")
        del user_states[message.chat.id] # پاک کردن وضعیت پس از اتمام
    except ValueError:
        bot.send_message(message.chat.id, "تعداد نامعتبر است. لطفا یک عدد وارد کنید.")

محدودیت‌های مدیریت وضعیت در حافظه:

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

۲. ذخیره‌سازی پایدار داده‌ها:

برای ربات‌های تولیدی و باثبات، نیاز به ذخیره‌سازی داده‌ها به صورت پایدار در یک دیتابیس دارید.

الف) فایل‌های JSON/CSV (برای داده‌های ساده و کم حجم):

اگر داده‌های شما ساختار ساده‌ای دارند و حجم آن‌ها زیاد نیست، می‌توانید آن‌ها را در فایل‌های JSON یا CSV ذخیره کنید. این روش ساده‌تر از دیتابیس‌های کامل است.


import json
import os

DATA_FILE = 'user_data.json'

def load_user_data():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, 'r', encoding='utf-8') as f:
            return json.load(f)
    return {}

def save_user_data(data):
    with open(DATA_FILE, 'w', encoding='utf-8') as f:
        json.dump(data, f, indent=4, ensure_ascii=False)

# هنگام شروع ربات
global_user_data = load_user_data()

# در هندلرها
@bot.message_handler(commands=['save_info'])
def save_info(message):
    chat_id = str(message.chat.id) # ذخیره به عنوان رشته برای JSON
    global_user_data[chat_id] = {'last_message': message.text, 'timestamp': message.date}
    save_user_data(global_user_data)
    bot.send_message(message.chat.id, "اطلاعات شما ذخیره شد.")

@bot.message_handler(commands=['my_info'])
def get_info(message):
    chat_id = str(message.chat.id)
    if chat_id in global_user_data:
        info = global_user_data[chat_id]
        bot.send_message(message.chat.id, f"آخرین پیام شما: {info['last_message']} در تاریخ {info['timestamp']}")
    else:
        bot.send_message(message.chat.id, "هیچ اطلاعاتی از شما یافت نشد.")

ب) دیتابیس SQLite (برای ربات‌های متوسط):

SQLite یک دیتابیس رابطه‌ای مبتنی بر فایل است که نیازی به سرور جداگانه ندارد و برای ربات‌های با مقیاس متوسط بسیار مناسب است. ماژول sqlite3 در پایتون به صورت پیش‌فرض وجود دارد.


import sqlite3

DATABASE_NAME = 'bot_data.db'

def init_db():
    conn = sqlite3.connect(DATABASE_NAME)
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            chat_id INTEGER PRIMARY KEY,
            username TEXT,
            state TEXT,
            data TEXT
        )
    ''')
    conn.commit()
    conn.close()

def set_user_state(chat_id, state, data=None):
    conn = sqlite3.connect(DATABASE_NAME)
    cursor = conn.cursor()
    cursor.execute("INSERT OR REPLACE INTO users (chat_id, state, data) VALUES (?, ?, ?)",
                   (chat_id, state, json.dumps(data) if data else None))
    conn.commit()
    conn.close()

def get_user_state(chat_id):
    conn = sqlite3.connect(DATABASE_NAME)
    cursor = conn.cursor()
    cursor.execute("SELECT state, data FROM users WHERE chat_id = ?", (chat_id,))
    result = cursor.fetchone()
    conn.close()
    if result:
        state, data = result
        return state, json.loads(data) if data else {}
    return None, {}

# فراخوانی init_db هنگام شروع ربات
init_db()

@bot.message_handler(commands=['start_sqlite_order'])
def start_sqlite_order(message):
    set_user_state(message.chat.id, 'waiting_for_item')
    bot.send_message(message.chat.id, "سفارش جدید با SQLite. چه کالایی می‌خواهید سفارش دهید؟")

@bot.message_handler(func=lambda message: get_user_state(message.chat.id)[0] == 'waiting_for_item')
def get_sqlite_item(message):
    _, user_data = get_user_state(message.chat.id)
    user_data['item'] = message.text
    set_user_state(message.chat.id, 'waiting_for_quantity', user_data)
    bot.send_message(message.chat.id, f"شما '{message.text}' را انتخاب کردید. چه تعداد می‌خواهید؟")

# ... ادامه هندلرها برای quantity و اتمام سفارش

نکات:

  • برای ربات‌های بزرگ‌تر یا توزیع‌شده، دیتابیس‌های سمت سرور مانند PostgreSQL یا MySQL، یا دیتابیس‌های NoSQL مانند MongoDB مناسب‌تر هستند.
  • همیشه هنگام کار با دیتابیس‌ها، از مدیریت خطا (try-except) و بستن کانکشن‌ها (conn.close()) اطمینان حاصل کنید.

۳. مدیریت وضعیت با استفاده از فریمورک‌های FSM (Finite State Machine):

برای سناریوهای پیچیده‌تر، الگوهای Finite State Machine (ماشین حالت متناهی) می‌توانند بسیار مفید باشند. برخی کتابخانه‌ها مانند aiogram (برای پایتون asynchronous) یا حتی ماژول‌های داخلی pyTelegramBotAPI (مانند telebot.handler_backends.StateFilter و State, StatesGroup) از این الگو پشتیبانی می‌کنند. این روش به شما اجازه می‌دهد تا مراحل مختلف یک فرآیند را به صورت دقیق و قابل مدیریت تعریف کنید و هر مرحله را به یک وضعیت (State) مشخص نگاشت کنید.

Telebot یک سیستم FSM ساده ارائه می‌دهد که می‌توانید با تعریف کلاس StatesGroup و استفاده از Stateها، آن را پیاده‌سازی کنید. این یک روش عالی برای جلوگیری از تودرتو شدن register_next_step_handler است.


from telebot.handler_backends import State, StatesGroup

# تعریف حالت‌ها
class MyStates(StatesGroup):
    name = State() # وضعیت انتظار برای نام
    age = State()  # وضعیت انتظار برای سن

@bot.message_handler(commands=['fsm_register'])
def fsm_register_step1(message):
    bot.set_state(message.from_user.id, MyStates.name, message.chat.id)
    bot.send_message(message.chat.id, "خوش آمدید! لطفا نام خود را وارد کنید.")

@bot.message_handler(state=MyStates.name)
def fsm_register_step2(message):
    with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
        data['name'] = message.text
    bot.set_state(message.from_user.id, MyStates.age, message.chat.id)
    bot.send_message(message.chat.id, "ممنون. حالا لطفا سن خود را وارد کنید.")

@bot.message_handler(state=MyStates.age)
def fsm_register_step3(message):
    with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
        try:
            data['age'] = int(message.text)
            bot.send_message(message.chat.id,
                             f"ثبت‌نام شما با FSM کامل شد! نام: {data['name']}, سن: {data['age']}")
            bot.delete_state(message.from_user.id, message.chat.id) # پاک کردن حالت
        except ValueError:
            bot.send_message(message.chat.id, "سن نامعتبر است. لطفا یک عدد وارد کنید.")

نکات FSM:

  • bot.set_state(user_id, state, chat_id): برای تنظیم وضعیت کاربر.
  • bot.retrieve_data(user_id, chat_id): برای دسترسی به داده‌های ذخیره شده در آن وضعیت.
  • bot.delete_state(user_id, chat_id): برای حذف وضعیت کاربر پس از اتمام فرآیند.
  • این سیستم FSM به طور پیش‌فرض از ذخیره‌سازی در حافظه (MemoryStorage) استفاده می‌کند، اما می‌توانید آن را با دیتابیس‌های مختلف (مانند Redis یا MongoDB) با استفاده از Storageهای سفارشی یا کتابخانه‌هایی مانند telebot.storage پیکربندی کنید.

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

پاسخ به Inline Query ها و Callback Query ها

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

۱. Callback Query ها (از Inline Keyboard ها):

در بخش ارسال پیام‌ها، با Inline Keyboard ها آشنا شدیم. وقتی کاربر روی یک دکمه Inline Keyboard کلیک می‌کند که دارای callback_data است، تلگرام یک CallbackQuery به ربات شما ارسال می‌کند. این CallbackQuery حاوی اطلاعاتی است که ربات برای پاسخگویی به آن نیاز دارد.

هندل کردن Callback Query ها:

از دکوراتور @bot.callback_query_handler() برای مدیریت این نوع درخواست‌ها استفاده می‌شود.


from telebot import types

# هندلر برای Callback Query ها
@bot.callback_query_handler(func=lambda call: True) # به همه Callback Query ها پاسخ می‌دهد
def handle_callback_query(call):
    # 'call' یک آبجکت CallbackQuery است.
    # call.data شامل مقدار 'callback_data' است که از دکمه ارسال شده.
    # call.message شامل آبجکت Message است که کیبورد Inline روی آن قرار دارد.
    # call.from_user شامل اطلاعات کاربری است که روی دکمه کلیک کرده.

    if call.data == "like":
        bot.answer_callback_query(call.id, "شما این پست را لایک کردید!")
        # می‌توانید پیام را ویرایش کنید تا لایک را نشان دهید
        current_likes = int(call.message.text.split(' ')[-2]) # فرض کنید متن پیام "پست: X لایک" باشد
        new_text = f"پست: {current_likes + 1} لایک"
        bot.edit_message_text(chat_id=call.message.chat.id,
                              message_id=call.message.message_id,
                              text=new_text,
                              reply_markup=call.message.reply_markup)
    elif call.data == "dislike":
        bot.answer_callback_query(call.id, "دیس‌لایک ثبت شد.", show_alert=True) # نمایش یک پنجره پاپ‌آپ
        bot.send_message(call.message.chat.id, "متأسفیم که دوست نداشتید.")
    
    # مثال دیگری برای یک Inline Keyboard
@bot.message_handler(commands=['post'])
def send_post_with_actions(message):
    markup = types.InlineKeyboardMarkup()
    markup.add(types.InlineKeyboardButton("لایک ❤️", callback_data="like"),
               types.InlineKeyboardButton("دیس‌لایک 💔", callback_data="dislike"))
    bot.send_message(message.chat.id, "پست: 0 لایک", reply_markup=markup)

نکات مهم برای Callback Query ها:

  • پاسخ الزامی: حتماً باید با bot.answer_callback_query(call.id, ...) به هر CallbackQuery پاسخ دهید. این کار ضروری است تا تلگرام بداند درخواست پردازش شده است و انیمیشن “در حال بارگذاری” روی دکمه ناپدید شود. می‌توانید یک متن کوتاه (toast) یا یک پنجره پاپ‌آپ (show_alert=True) را در پاسخ نشان دهید.
  • ویرایش پیام: شما می‌توانید پیام اصلی (که Inline Keyboard روی آن قرار دارد) را با bot.edit_message_text، bot.edit_message_caption، bot.edit_message_media یا bot.edit_message_reply_markup تغییر دهید. این کار تعاملات پویا را ممکن می‌سازد.

۲. Inline Query ها:

Inline Query ها به کاربران اجازه می‌دهند تا بدون نیاز به شروع چت مستقیم با ربات، با آن تعامل کنند. کاربر می‌تواند نام کاربری ربات شما را در هر چتی تایپ کند و سپس کوئری (جستجو) خود را بنویسد (مثلاً @myrobot عکس سگ). ربات سپس نتایجی را در یک لیست در همان چت (که کاربر در حال تایپ بود) پیشنهاد می‌دهد.

فعال‌سازی Inline Mode:

برای فعال کردن این قابلیت، باید به @BotFather بروید و دستور /setinline را برای ربات خود اجرا کنید.

هندل کردن Inline Query ها:

از دکوراتور @bot.inline_handler() برای مدیریت این نوع درخواست‌ها استفاده می‌شود.


from telebot import types
import uuid # برای تولید ID منحصر به فرد برای نتایج

@bot.inline_handler(func=lambda query: True)
def handle_inline_query(inline_query):
    # 'inline_query' یک آبجکت InlineQuery است.
    # inline_query.query حاوی متن جستجوی کاربر است.

    try:
        query_text = inline_query.query.lower()
        results = []

        if "عکس" in query_text:
            # مثال: فرض کنید چندین عکس با file_id های مختلف داریم
            photo_id1 = 'AgACAgIAAxkBAAI...' # ID عکس واقعی را اینجا قرار دهید
            photo_id2 = 'AgACAgIAAxkBAAI...'
            results.append(types.InlineQueryResultPhoto(
                id=str(uuid.uuid4()),
                photo_file_id=photo_id1,
                thumbnail_url="https://example.com/thumb1.jpg", # URL تصویر کوچک برای نمایش در نتایج
                caption="این یک عکس است."
            ))
            results.append(types.InlineQueryResultPhoto(
                id=str(uuid.uuid4()),
                photo_file_id=photo_id2,
                thumbnail_url="https://example.com/thumb2.jpg",
                caption="یک عکس دیگر."
            ))
        elif "سلام" in query_text:
            results.append(types.InlineQueryResultArticle(
                id=str(uuid.uuid4()),
                title="پیام سلام",
                input_message_content=types.InputTextMessageContent("سلام به شما!")
            ))
        else:
            results.append(types.InlineQueryResultArticle(
                id=str(uuid.uuid4()),
                title="هیچ نتیجه‌ای یافت نشد",
                input_message_content=types.InputTextMessageContent("متأسفم، نتایجی برای جستجوی شما پیدا نشد.")
            ))

        bot.answer_inline_query(inline_query.id, results, cache_time=1)

    except Exception as e:
        print(f"خطا در Inline Query: {e}")
        # در صورت خطا، می‌توانید یک پاسخ خالی یا یک پیام خطا ارسال کنید
        bot.answer_inline_query(inline_query.id, [])

انواع نتایج Inline Query:

Telebot از انواع مختلفی از نتایج Inline Query پشتیبانی می‌کند که هر کدام برای نمایش نوع خاصی از محتوا مناسب هستند:

  • InlineQueryResultArticle: برای نمایش پیام‌های متنی (که می‌توانید InputTextMessageContent را با parse_mode هم تنظیم کنید).
  • InlineQueryResultPhoto: برای نمایش عکس‌ها.
  • InlineQueryResultVideo: برای نمایش ویدئوها.
  • InlineQueryResultAudio: برای نمایش فایل‌های صوتی.
  • InlineQueryResultDocument: برای نمایش فایل‌های عمومی.
  • InlineQueryResultCachedPhoto، InlineQueryResultCachedVideo و غیره: برای استفاده از فایل‌هایی که قبلاً به تلگرام آپلود شده‌اند و file_id آنها را می‌دانید (کارآمدتر از آپلود مجدد).

نکات مهم برای Inline Query ها:

  • id منحصر به فرد: هر نتیجه در لیست results باید دارای یک id منحصر به فرد باشد. uuid.uuid4() یک راه عالی برای تولید IDهای منحصر به فرد است.
  • input_message_content: این پارامتر تعیین می‌کند که وقتی کاربر روی نتیجه Inline Query کلیک می‌کند، چه پیامی ارسال شود.
  • bot.answer_inline_query(inline_query.id, results, ...): این متد برای ارسال نتایج به تلگرام استفاده می‌شود.
    • cache_time: تعیین می‌کند که نتایج برای چند ثانیه کش (cache) شوند. (پیش‌فرض ۳۰۰ ثانیه)
    • is_personal: اگر True باشد، نتایج فقط برای کاربر فعلی کش می‌شوند.
  • ملاحظات عملکردی: Inline Query ها می‌توانند بسیار پرکاربرد باشند، بنابراین عملکرد ربات و سرعت پاسخ‌دهی آن به کوئری‌ها اهمیت زیادی دارد. مطمئن شوید که منطق پردازش شما بهینه است و از عملیات‌های زمان‌بر در هندلر Inline Query خودداری کنید.

با استفاده از Callback Query ها و Inline Query ها، می‌توانید ربات‌هایی بسازید که نه تنها در محیط چت خود تلگرام کار می‌کنند، بلکه در سراسر این پلتفرم، تجربه کاربری بی‌نظیری را ارائه دهند.

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

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

۱. مدیریت خطا (Error Handling):

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


import traceback

@bot.message_handler(commands=['divide'])
def handle_divide(message):
    try:
        args = message.text.split()[1:]
        num1 = float(args[0])
        num2 = float(args[1])
        result = num1 / num2
        bot.send_message(message.chat.id, f"نتیجه تقسیم: {result}")
    except IndexError:
        bot.send_message(message.chat.id, "لطفا دو عدد برای تقسیم وارد کنید. مثال: /divide 10 2")
    except ValueError:
        bot.send_message(message.chat.id, "لطفا اعداد معتبر وارد کنید.")
    except ZeroDivisionError:
        bot.send_message(message.chat.id, "تقسیم بر صفر امکان‌پذیر نیست.")
    except Exception as e:
        bot.send_message(message.chat.id, "خطایی رخ داد. لطفا دوباره تلاش کنید.")
        # برای اشکال‌زدایی، می‌توانید اطلاعات خطا را لاگ کنید.
        print(f"Error: {e}\n{traceback.format_exc()}")

همچنین، Telebot یک دکوراتور @bot.error_handler برای مدیریت خطاهای سراسری دارد:


@bot.error_handler
def handle_errors(exception):
    print(f"یک خطای کلی در ربات رخ داد: {exception}")
    print(traceback.format_exc())
    # می‌توانید اینجا به ادمین اطلاع دهید یا لاگ کنید.

۲. لاگ‌برداری (Logging):

ثبت وقایع (Logging) برای اشکال‌زدایی، نظارت بر عملکرد ربات و ردیابی فعالیت‌های کاربران بسیار مهم است. پایتون ماژول logging را ارائه می‌دهد.


import logging

# پیکربندی اولیه لاگ‌برداری
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=['log_test'])
def log_test(message):
    logger.info(f"کاربر {message.from_user.id} دستور /log_test را ارسال کرد.")
    logger.warning("این یک هشدار است.")
    try:
        1 / 0
    except ZeroDivisionError:
        logger.error("تلاش برای تقسیم بر صفر!", exc_info=True)
    bot.send_message(message.chat.id, "فعالیت شما لاگ شد.")

۳. مدیریت همزمانی (Concurrency) و تسک‌های طولانی‌مدت:

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

  • Threading: می‌توانید کارهای زمان‌بر را در یک رشته جداگانه اجرا کنید. پایتون ماژول threading را دارد.
  • Asynchronous Programming (asyncio/aiohttp): برای ربات‌های با ترافیک بالا، استفاده از فریمورک‌های غیرهمزمان (مانند aiohttp و asyncio در کنار aiogram یا نسخه‌های async Telebot) توصیه می‌شود. این روش امکان مدیریت هزاران اتصال همزمان را با کارایی بالا فراهم می‌کند.

Telebot به صورت پیش‌فرض از مدل synchronous استفاده می‌کند، اما نسخه‌های async آن نیز در حال توسعه هستند. برای تسک‌های ساده، threading می‌تواند راهگشا باشد.


import threading
import time

def long_running_task(chat_id):
    bot.send_message(chat_id, "عملیات زمان‌بر آغاز شد...")
    time.sleep(10) # شبیه‌سازی یک عملیات طولانی
    bot.send_message(chat_id, "عملیات زمان‌بر به پایان رسید!")

@bot.message_handler(commands=['long_task'])
def start_long_task(message):
    bot.send_message(message.chat.id, "در حال شروع عملیات در پس‌زمینه. لطفا منتظر بمانید.")
    thread = threading.Thread(target=long_running_task, args=(message.chat.id,))
    thread.start()

۴. وب‌هوک (Webhook) در مقابل Polling:

در حال حاضر ربات ما از Polling استفاده می‌کند. Polling ساده است اما معایبی دارد: مصرف منابع بیشتر (درخواست‌های مکرر به سرور تلگرام) و تأخیر احتمالی در دریافت پیام‌ها. برای ربات‌های تولیدی و با ترافیک بالا، استفاده از Webhook توصیه می‌شود.

  • Polling: ربات به صورت دوره‌ای به سرور تلگرام “پرس‌وجو” می‌کند که آیا پیام جدیدی وجود دارد یا خیر.
  • Webhook: شما یک URL (آدرس وب) را به تلگرام می‌دهید. هر بار که پیام جدیدی برای ربات شما می‌رسد، تلگرام آن را به صورت خودکار به آن URL “پست” می‌کند.
    • مزایا: دریافت فوری پیام‌ها، مصرف منابع کمتر در سمت ربات، مقیاس‌پذیری بهتر.
    • معایب: نیاز به یک سرور وب (مانند Flask یا Django) و یک دامنه با گواهینامه SSL معتبر برای دریافت درخواست‌ها.

برای تنظیم Webhook در Telebot، باید یک سرور وب کوچک (مثل Flask) را با آن یکپارچه کنید. مثال بسیار ساده (نیاز به تنظیمات HTTPS و Nginx/Caddy برای استفاده در محیط واقعی دارد):


# این یک مثال مفهومی است و نیاز به پیکربندی واقعی دارد.
# نیاز به نصب flask: pip install flask
from flask import Flask, request

app = Flask(__name__)

# ... (bot تعریف شده است) ...

@app.route('/' + API_TOKEN, methods=['POST'])
def get_message():
    json_string = request.get_data().decode('utf-8')
    update = telebot.types.Update.de_json(json_string)
    bot.process_new_updates([update])
    return "!", 200

@bot.message_handler(commands=['webhook_test'])
def webhook_test(message):
    bot.send_message(message.chat.id, "این ربات در حالت Webhook کار می‌کند!")

if __name__ == '__main__':
    # این خط را فقط یک بار برای تنظیم Webhook اجرا کنید
    # bot.set_webhook("https://yourdomain.com/" + API_TOKEN)
    
    # برای اجرای Flask app (برای توسعه محلی ممکن است به ngrok نیاز داشته باشید)
    app.run(host="0.0.0.0", port=8443) # معمولا پورت های 443, 80, 88, 8443 برای وب‌هوک استفاده می‌شوند.

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

۵. استقرار ربات (Deployment):

پس از توسعه، باید ربات خود را روی یک سرور زنده مستقر کنید تا به صورت ۲۴/۷ در دسترس باشد. گزینه‌های محبوب شامل:

  • VPS (Virtual Private Server): مانند DigitalOcean, Linode, Vultr. به شما کنترل کامل می‌دهد.
  • PaaS (Platform as a Service): مانند Heroku (دارای Tier رایگان محدود), PythonAnywhere. سادگی در استقرار و مدیریت.
  • Docker/Kubernetes: برای استقرار ربات در کانتینرها، به خصوص در محیط‌های ابری.

هر روش استقرار نیازمند تنظیمات خاص خود (مانند نصب وابستگی‌ها، تنظیم متغیرهای محیطی و راه‌اندازی فرآیند ربات) است.

با افزودن این امکانات، ربات شما نه تنها قابلیت‌های بیشتری پیدا می‌کند، بلکه پایدارتر، امن‌تر و مدیریت‌پذیرتر نیز خواهد بود.

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

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

۱. حفاظت از توکن ربات (Bot Token Security):

توکن ربات شما، کلید دسترسی به API تلگرام است و نباید به هیچ وجه فاش شود.

  • عدم Hardcoding: هرگز توکن خود را مستقیماً در کد پایتون (مثل API_TOKEN = 'your_token') قرار ندهید و آن را در گیت‌هاب یا هر مخزن عمومی دیگری آپلود نکنید.
  • استفاده از متغیرهای محیطی: بهترین روش، ذخیره توکن به عنوان یک متغیر محیطی (Environment Variable) است. هنگام راه‌اندازی ربات، می‌توانید آن را از محیط بخوانید:
    
    import os
    API_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN')
    if not API_TOKEN:
        raise ValueError("TELEGRAM_BOT_TOKEN environment variable not set.")
            

    در هنگام استقرار، متغیر محیطی را در تنظیمات سرور خود (مانند Heroku config vars، Docker secrets یا فایل .env در سرورهای VPS) تنظیم کنید.

  • فایل پیکربندی محلی (برای توسعه): برای توسعه محلی، می‌توانید توکن را در یک فایل config.py جداگانه قرار دهید و سپس این فایل را به .gitignore اضافه کنید تا به مخزن کد شما اضافه نشود.
  • بازگرداندن توکن (Revoke Token): اگر به هر دلیلی فکر می‌کنید توکن شما به خطر افتاده است، فوراً با BotFather دستور /revoke را برای ربات خود اجرا کنید تا یک توکن جدید صادر شود و توکن قدیمی باطل گردد.

۲. اعتبار سنجی ورودی کاربر (Input Validation):

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

  • نوع داده: اگر انتظار عدد دارید، بررسی کنید که آیا ورودی واقعاً عدد است. اگر تاریخ است، فرمت آن را چک کنید.
  • محدوده: اگر ورودی باید در یک محدوده خاص باشد (مثلاً سن بین ۱ تا ۱۰۰)، آن را بررسی کنید.
  • طول: محدودیت‌هایی برای طول متن یا سایر ورودی‌ها اعمال کنید تا از حملات denial-of-service یا سرریز جلوگیری شود.
  • کاراکترهای خاص: ورودی‌ها را از نظر کاراکترهای خاصی که می‌توانند به دیتابیس آسیب بزنند (SQL injection) یا کدهای مخرب (XSS در صورت نمایش در وب) بررسی و فیلتر کنید.

@bot.message_handler(commands=['set_age'])
def set_age(message):
    try:
        age = int(message.text.split()[1])
        if 0 < age < 120:
            # ذخیره سن
            bot.send_message(message.chat.id, f"سن شما {age} سال ثبت شد.")
        else:
            bot.send_message(message.chat.id, "سن باید بین 1 تا 119 باشد.")
    except (ValueError, IndexError):
        bot.send_message(message.chat.id, "لطفا سن خود را به صورت عدد وارد کنید. مثال: /set_age 30")

۳. مدیریت خطا (Robust Error Handling):

همانطور که قبلاً اشاره شد، مدیریت جامع خطا برای پایداری ربات بسیار مهم است. از بلوک‌های try-except در اطراف عملیات‌هایی که ممکن است با شکست مواجه شوند (مانند عملیات شبکه، خواندن/نوشتن فایل، پردازش داده‌ها) استفاده کنید. از دکوراتور @bot.error_handler برای مدیریت خطاهای پیش‌بینی نشده در سطح جهانی استفاده کنید.

۴. نرخ‌گذاری و محدودیت استفاده (Rate Limiting):

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

  • محدودیت‌های تلگرام: تلگرام خود دارای محدودیت‌هایی برای ارسال پیام (مثلاً ۳۰ پیام در ثانیه به یک چت، ۲۰ پیام در ثانیه برای ربات به طور کلی) است. اگر این محدودیت‌ها را رد کنید، ربات شما ممکن است به طور موقت مسدود شود. Telebot به طور خودکار این موارد را تا حدی مدیریت می‌کند، اما برنامه‌نویسی آگاهانه بهتر است.
  • محدودیت‌های سفارشی: می‌توانید محدودیت‌های خود را برای هر کاربر یا هر دستور اعمال کنید (مثلاً یک کاربر نتواند بیش از ۵ بار در دقیقه یک دستور خاص را اجرا کند).

۵. حفظ حریم خصوصی (Privacy):

جمع‌آوری و ذخیره‌سازی اطلاعات کاربران باید با دقت و با رعایت حریم خصوصی آن‌ها انجام شود.

  • فقط اطلاعات لازم: فقط اطلاعاتی را جمع‌آوری کنید که برای عملکرد ربات شما واقعاً ضروری هستند.
  • شفافیت: به کاربران اطلاع دهید چه اطلاعاتی جمع‌آوری می‌شود و چگونه از آن‌ها استفاده می‌کنید. (می‌توانید یک دستور /privacy برای نمایش سیاست حریم خصوصی ایجاد کنید.)
  • ذخیره‌سازی امن: اطلاعات حساس را به صورت رمزگذاری شده ذخیره کنید.

۶. سازماندهی کد و ماژولار بودن:

با رشد ربات، کد شما پیچیده‌تر می‌شود. سازماندهی مناسب کد به شما کمک می‌کند تا ربات خود را بهتر نگهداری و توسعه دهید.

  • تقسیم به ماژول‌ها: کد را به فایل‌های کوچکتر (ماژول‌ها) بر اساس عملکرد تقسیم کنید (مثلاً handlers.py، database.py، utils.py).
  • توابع مجزا: هر تابع باید یک کار مشخص و واحد را انجام دهد.
  • کلاس‌ها (OOP): برای ربات‌های پیچیده‌تر، استفاده از برنامه‌نویسی شی‌گرا (OOP) و کلاس‌ها می‌تواند به ساختاردهی کد کمک کند.

۷. به‌روزرسانی کتابخانه Telebot:

همیشه از آخرین نسخه پایدار Telebot استفاده کنید (pip install --upgrade pyTelegramBotAPI). به‌روزرسانی‌ها شامل رفع اشکالات، بهبود عملکرد و پشتیبانی از ویژگی‌های جدید API تلگرام هستند.

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

نتیجه‌گیری و گام‌های بعدی

در این راهنمای جامع، سفر خود را از اولین گام‌های آشنایی با پایتون و Telebot آغاز کردیم و تا ساخت یک ربات پایه با قابلیت‌های تعاملی پیشرفته ادامه دادیم. شما اکنون قادر هستید تا محیط توسعه خود را آماده کنید، توکن ربات خود را از BotFather دریافت کنید، Telebot را نصب کرده و اولین ربات "Hello World" خود را راه‌اندازی کنید. علاوه بر این، با مفاهیم کلیدی مانند Message Handler‌ها و فیلترهای آن‌ها، نحوه ارسال انواع پیام‌ها، ایجاد کیبوردهای تعاملی (Reply و Inline)، مدیریت وضعیت کاربران و پاسخگویی به Inline و Callback Query‌ها آشنا شده‌اید. در نهایت، با اهمیت مدیریت خطا، لاگ‌برداری، همزمانی، انتخاب روش استقرار و رعایت نکات امنیتی و بهترین شیوه‌ها در توسعه ربات آشنا شدید.

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

گام‌های بعدی برای یادگیری بیشتر:

  1. تمرین و پیاده‌سازی: بهترین راه برای یادگیری، انجام دادن است. ایده‌های کوچک خود را به ربات تبدیل کنید. یک ربات ساده برای یادآوری کارها، یک ربات برای دریافت نظرات، یا یک ربات برای جستجو در یک API عمومی (مثل آب‌وهوا یا اخبار) بسازید.
  2. مطالعه مستندات رسمی: مستندات pyTelegramBotAPI در https://pytba.readthedocs.io/ منبع اصلی و معتبری برای یادگیری تمام جزئیات و امکانات این کتابخانه است.
  3. کاوش API تلگرام: با API رسمی تلگرام در https://core.telegram.org/bots/api آشنا شوید. این به شما در درک عمیق‌تر نحوه عملکرد ربات‌ها و کشف قابلیت‌هایی که Telebot هنوز پوشش نداده است (اگرچه نادر است) کمک می‌کند.
  4. نگاهی به کتابخانه‌های دیگر: با اینکه Telebot عالی است، کتابخانه‌های دیگری مانند aiogram (برای برنامه‌نویسی غیرهمزمان) یا python-telegram-bot نیز وجود دارند که هر کدام مزایا و فلسفه طراحی خاص خود را دارند. بررسی آن‌ها می‌تواند دیدگاه شما را گسترش دهد.
  5. مشارکت در جامعه: به گروه‌ها و انجمن‌های مرتبط با توسعه ربات تلگرام یا پایتون بپیوندید. پرسش و پاسخ با دیگر توسعه‌دهندگان می‌تواند بسیار آموزنده باشد.
  6. پروژه‌های اوپن سورس: کد ربات‌های اوپن سورس در GitHub را بررسی کنید. این کار می‌تواند به شما ایده‌ها و الگوهای طراحی خوبی بدهد.

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

موفق باشید!

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

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

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

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

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

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

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

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