Telegram Bot. Как запомнить выбранную категорию

Сперва весь код простенького бота:

# Библиотеки
import logging
import telegram
from telegram import (ReplyKeyboardMarkup, ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton)
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, ConversationHandler)

# --------------------  НАСТРОЙКИ  ---------------------
Token = '************************'
DataDir = 'data/' 
WelcomeSpeach = "Здравствуйте! \nЯ помогу вам ориентироваться в мире насекомых. \nВыберите, что вас интересует:"
# ------------------------------------------------------

# Логирование
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)

# Авторизация
updater = Updater(token=Token, use_context=True) 
dispatcher = updater.dispatcher
logger.info('Bot service authorized('+Token+')')

# Обработка команд
def startCommand(update, context):
    context.bot.send_photo(chat_id=update.effective_chat.id, photo=open(DataDir+'WelcomePage/WelcomeLogo.jpg', 'rb'), caption='')
    
    inline_keyboard = [
        [InlineKeyboardButton('Что это за насекомое?', callback_data='1')], 
        [InlineKeyboardButton('Какое насекомое съело растение?', callback_data='2')], 
        [InlineKeyboardButton('Кто меня укусил?', callback_data='3')], 
        [InlineKeyboardButton('Техподдержка', callback_data='4')]]

    markup = InlineKeyboardMarkup(inline_keyboard, resize_keyboard=True, one_time_keyboard=True)
    context.bot.send_message(chat_id=update.effective_chat.id, text=WelcomeSpeach, reply_markup=markup)

# Хендлеры
start_command_handler = CommandHandler('start', startCommand)

# Добавляем хендлеры в диспетчер
dispatcher.add_handler(start_command_handler)

# Начинаем поиск обновлений
updater.start_polling(clean=True)
# Останавливаем бота, если были нажаты Ctrl + C
updater.idle()

Далее, получаем:

Мне нужно, чтобы после нажатия на "Что это за насекомое?", бот попросил "Пришлите фото" и фото обрабатывалось именно как определение насекомого.

Также для "Кто меня укусил?", НО! фото должно обрабатываться уже в другой функции.

Как это можно сделать?

Спасибо!


Ответы (2 шт):

Автор решения: D. Violet
@bot.callback_query_handler(func=lambda call: True)  # отловим все callback
def callback_inline(call):
    if call.data == '1':  # если callback_data = 1
         print('Что это за насекомое')
         send = bot.send_message(call.message.chat.id, 'жду фото')  # сообщение которое отправим пользователю
         bot.register_next_step_handler(send, what_bug)  # регистрируем следующий шаг(отправим сообщение, перейдём к функции)

    elif call.data == '2':
         print('Какое насекомое съело растение')
    elif call.data == '3':
         print('Кто меня укусил')

def what_bug(message):
    print(message)
    if message.content_type == 'photo':  # если присланный message photo
       print('это фото')
       # вытягивайте из `message` `file_id`, сохраняйте если требуется и делайте что Вам угодно
    
→ Ссылка
Автор решения: Alrott SlimRG

Короче, у telegram.ext немного отличается архитектура от telebot

В итоге, гуглите ConversationHandler

Вот мой код, как пример

# Библиотеки
import logging
import os
import smtplib
import sys
import telegram
import time

from configparser import ConfigParser
from telegram import (ReplyKeyboardMarkup, ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton)
from telegram.ext import (Updater, CallbackQueryHandler, CommandHandler, ConversationHandler, MessageHandler, Filters, ConversationHandler, CallbackQueryHandler)
from datetime import datetime
from threading import Thread

# --------------------  НАСТРОЙКИ  ---------------------
# -- Telegram  
Token = '**************'

# -- Programm
DataDir = 'data/' 
WelcomeSpeach = "Здравствуйте! \nЯ помогу вам ориентироваться в мире насекомых. \nВыберите, что вас интересует:"

# -- SMTP
HostSMTP = 'smtp.yandex.ru'
EmailSMTP = '[email protected]'
LoginSMTP = 'bbccaa'
PasswordSMTP = '*********'
ToEmailsSMTP = ['[email protected]', '[email protected]']

# -- Логирование
LogFilePath = 'AIBugLogger.txt'
# ------------------------------------------------------

# Логирование

class LogThread(Thread):
    def __init__(self):
            Thread.__init__(self)
            self.name = 'LogT'
    
    def run(self):
        while True:
                with open(LogFilePath, 'r') as file:
                    read_file = file.read()
                    os.system('cls||clear')
                    print(read_file)
                    time.sleep(60)

logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO, filename=LogFilePath)
logger = logging.getLogger(__name__)
LogThread = LogThread()
LogThread.start()

# Авторизация
updater = Updater(token=Token, use_context=True) 
dispatcher = updater.dispatcher
logger.info('Bot service authorized('+Token+')')

# Обработка команд
def startCommand(update, context):
    context.bot.send_photo(chat_id=update.effective_chat.id, photo=open(DataDir+'WelcomePage/WelcomeLogo.jpg', 'rb'), caption='')
    
    inline_keyboard = [
        [InlineKeyboardButton('Что это за насекомое?', callback_data='GoBug')], 
        [InlineKeyboardButton('Какое насекомое съело растение?', callback_data='GoPlant')], 
        [InlineKeyboardButton('Кто меня укусил?', callback_data='GoBite')], 
        [InlineKeyboardButton('Техподдержка', callback_data='GoSupport')]]

    markup = InlineKeyboardMarkup(inline_keyboard, resize_keyboard=True, one_time_keyboard=True)
    context.bot.send_message(chat_id=update.effective_chat.id, text=WelcomeSpeach, reply_markup=markup)
    logger.info("User %s session started", update.message.from_user.first_name)
    return "support_msg"

def process_support(update, context):
    query = update.callback_query
    chat_id = update.effective_chat.id
    msg = context.bot.send_message(chat_id, 'Пожалуйста опишите вашу проблему')
    return "support_text"

def process_bug(update, context):
    query = update.callback_query
    chat_id = update.effective_chat.id
    context.bot.send_message(chat_id, 'Пришлите фотографию насекомого крупным планом, \nкак на рисунке ниже:')
    context.bot.send_photo(chat_id=update.effective_chat.id, photo=open(DataDir+'BugPage/ExImage.jpg', 'rb'), caption='')
    return "bug_page"

def process_plant(update, context):
    query = update.callback_query
    chat_id = update.effective_chat.id
    context.bot.send_message(chat_id, 'Пришлите фотографию поврежденного растения крупным планом, \nкак на рисунке ниже:')
    context.bot.send_photo(chat_id=update.effective_chat.id, photo=open(DataDir+'PlantPage/ExImage.jpg', 'rb'), caption='')
    return "plant_page"

def process_bite(update, context):
    query = update.callback_query
    chat_id = update.effective_chat.id
    context.bot.send_message(chat_id, 'Пришлите фотографию укуса крупным планом, \nкак на рисунке ниже:')
    context.bot.send_photo(chat_id=update.effective_chat.id, photo=open(DataDir+'BitePage/ExImage.jpg', 'rb'), caption='')
    return "bite_page"

def process_underconstruction(update, context):
    query = update.callback_query
    chat_id = update.effective_chat.id
    context.bot.send_message(chat_id, 'Данная функция временно в разработке! \nПожалуйста, воспользуйтесь предложенным списком')
    time.sleep(5)
    return startCommand(update, context)

def send_email(body_text, emails):  
    host = HostSMTP
    from_addr = EmailSMTP

    
    BODY = "\r\n".join((
        "From: %s" % from_addr,
        "To: %s" % ', '.join(emails),
        "Subject: %s" % 'AIBug Support Request' ,
        "",
        body_text
    ))
    
    server = smtplib.SMTP_SSL(host)
    server.login(LoginSMTP, PasswordSMTP)
    server.sendmail(from_addr, emails, BODY.encode("ascii","ignore"))
    server.quit()

def askSupport(update, context):
    query = update.callback_query
    chat_id = update.effective_chat.id
    Report = "User: " + update.message.from_user.name + "\nDate: "+ str(update.message.date) + "\nText: \n" + update.message.text
    send_email(Report, ToEmailsSMTP)
    msg = context.bot.send_message(chat_id, "Спасибо! \nВ ближайшее время с вами свяжется администратор!")
    startCommand(update, context)

def askBug(update, context):
    query = update.callback_query
    chat_id = update.effective_chat.id
    Report = "User: " + update.message.from_user.name + "\nDate: "+ str(update.message.date) + "\nText: \n" + update.message.text
    send_email(Report, ToEmailsSMTP)
    msg = context.bot.send_message(chat_id, "Спасибо! \nВ ближайшее время с вами свяжется администратор!")
    startCommand(update, context)

def wrongsupport(update, context):
    context.message.reply_text("Описание проблемы должно быть в текстовом виде! \nПопробуйте еще раз")
    startCommand(update, context)

# Хендлеры
start_command_handler = CommandHandler('start', startCommand)
support_callback_handler = CallbackQueryHandler(process_support, pattern='(GoSupport)')
bug_callback_handler = CallbackQueryHandler(process_bug, pattern='(GoBug)')
plant_callback_handler = CallbackQueryHandler(process_plant, pattern='(GoPlant)')
underconstruction_callback_handler = MessageHandler(Filters.all, process_underconstruction)
bite_callback_handler = CallbackQueryHandler(process_bite, pattern='(GoBite)')

support_message_handler = MessageHandler(Filters.text, askSupport)

dialog_handler = ConversationHandler(entry_points=[start_command_handler],
                                     states={
                                          "home_page"   : [start_command_handler],

                                          "support_msg" : [support_callback_handler, 
                                                           bug_callback_handler, 
                                                           plant_callback_handler, 
                                                           bite_callback_handler, 
                                                           underconstruction_callback_handler],

                                          "support_text": [support_message_handler],
                                          "support_bug"
                                     },
                                     fallbacks=[MessageHandler(Filters.video | Filters.photo | Filters.document, wrongsupport)],
                                     per_message=False
                                    )


# Добавляем хендлеры в диспетчер
dispatcher.add_handler(dialog_handler)

# Начинаем поиск обновлений
updater.start_polling(clean=True)

# Останавливаем бота, если были нажаты Ctrl + C
updater.idle()
→ Ссылка