TELEBOT Как обработать запрос 2-й клавиатуры

@bot.message_handler(content_types='text')
def hear_menu(message):
    inline_markup = types.InlineKeyboardMarkup()
    inline_markup.add(types.InlineKeyboardButton(text='CAR', callback_data='1'))
    inline_markup.add(types.InlineKeyboardButton(text='BAR', callback_data='2'))
    inline_markup.add(types.InlineKeyboardButton(text='SAR', callback_data='3'))
    inline_markup.add(types.InlineKeyboardButton(text='TAR', callback_data='4'))
    inline_markup.add(types.InlineKeyboardButton(text='FAR', callback_data='5'))
    inline_markup.add(types.InlineKeyboardButton(text='JAR', callback_data='6'))



    bot.send_message(message.chat.id, 'CHOOSE ONE', reply_markup=inline_markup)



@bot.callback_query_handler(func=lambda call: True)
def query_handler(call):
    bot.answer_callback_query(callback_query_id=call.id)
    inline_markup = types.InlineKeyboardMarkup()
    if call.data == '1':
        bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id)
        inline_markup.add(types.InlineKeyboardButton(text='HEU', callback_data="1elf"))
        inline_markup.add(types.InlineKeyboardButton(text='HEY2', callback_data="2elf"))
        inline_markup.add(types.InlineKeyboardButton(text='HE3', callback_data="3elf"))
        inline_markup.add(types.InlineKeyboardButton(text='HEY4', callback_data="4elf"))
        inline_markup.add(types.InlineKeyboardButton(text='? BACK ?', callback_data="5elf"))
        bot.send_message(call.message.chat.id, '? CJOOSE A NEW ONE', reply_markup=inline_markup)
        @bot.callback_query_handler(func=lambda call: True)
        def querry_handler2(call):
            if call.data == "1elf":
                bot.send_message(call.message.chat.id, 'YEEY, you have 1st')

Суть в том у что у меня задача такова: При появлении первой клавиатуры и нажатии 1-й из кнопок, появляется другая. Моя проблема состоит в том что я не понимаю, каким образом принять запрос отправленный кнопкой из 2-й клавиатуры


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

Автор решения: oleksandrigo

Ох ты ж ёпт.
Скажите мне, кто Вас заставляет впихивать одни хендлеры внутрь других? Кто этот ужасный и безнравственный человек?

@bot.message_handler()
def hear_menu(message):
    inline_markup = types.InlineKeyboardMarkup()
    # итак погнали. Во-первых не делайте такие непонятные колбек даты.
    # что значит 1? что значит 2?
    # inline_markup.add(types.InlineKeyboardButton(text='CAR', callback_data='1'))
    # делайте вот так, как ловить их покажу ниже
    inline_markup.add(types.InlineKeyboardButton(text='CAR', callback_data='prefix:1'))
    inline_markup.add(types.InlineKeyboardButton(text='BAR', callback_data='prefix:2'))
    inline_markup.add(types.InlineKeyboardButton(text='SAR', callback_data='prefix:3'))
    inline_markup.add(types.InlineKeyboardButton(text='TAR', callback_data='prefix:4'))
    inline_markup.add(types.InlineKeyboardButton(text='FAR', callback_data='prefix:5'))
    inline_markup.add(types.InlineKeyboardButton(text='JAR', callback_data='prefix:6'))
    # в общем мы добавили такой себе префикс с разделителем в виде двоеточия.
    # зачем? чтобы разделять типы колбеков
    # ниже я покажу как по префиксу ловить его
    # ну и само собой этот "prefix" вы можете назвать как вам удобно, главное чтобы 
    # вы уловили суть
    bot.send_message(message.chat.id, 'CHOOSE ONE', reply_markup=inline_markup)


# переходим к отлову нашего колбека
# так как клавиатура у нас как бы одна, так ведь, то логично её ловить одним хендлером.
# но это не всегда так, иногда лучше сделать два разных, зависит от удобства и задачи
# итак вместо убогого и по факту бесполезного func=lambda call: True
# мы делаем вот так
@bot.callback_query_handler(func=lambda call: call.data.split(":") == "prefix")
# что мы тут сделали? func=lambda call: - это у нас просто некая лямбда функция которая 
# принимает аргумент колбека, то есть наш call. Буквально.
# вместо простого True, который по факту говорит, мне наплевать что за колбек я возьму 
# его, хочешь ты этого или нет я поставил
# call.data.split(":")[0] == "prefix"
# то есть обращаемся к как-бы тексту колбека и разбиваем его по разделителю которым является двоеточие. 
# Так как метод split возвращает нам список/массив, (такой вот [prefix, 1])
# то мы берем нулевой элемент и если он будет "prefix" то все ок и хендлер срабатывает, 
# если нет игнор
def query_handler(call):
    bot.answer_callback_query(callback_query_id=call.id)
    inline_markup = types.InlineKeyboardMarkup()
    # так как call.data у нас не просто 1 или 2, а уже prefix:1, то мы снова сплитим 
    # его по двоеточию и берем уже первый элемент
    # которым будет эта самая цифра
    # для удобства записал результат сплита в переменную
    data_ = call.data.split(":")[1]
    if data_ == '1':
        bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id)
        inline_markup.add(types.InlineKeyboardButton(text='HEU', callback_data="prefix2:1elf"))
        inline_markup.add(types.InlineKeyboardButton(text='HEY2', callback_data="prefix2:2elf"))
        inline_markup.add(types.InlineKeyboardButton(text='HE3', callback_data="prefix2:3elf"))
        inline_markup.add(types.InlineKeyboardButton(text='HEY4', callback_data="prefix2:4elf"))
        inline_markup.add(types.InlineKeyboardButton(text='? BACK ?', callback_data="prefix2:5elf"))
        bot.send_message(call.message.chat.id, '? CJOOSE A NEW ONE', reply_markup=inline_markup)

# теперь вместо того чтобы заниматься извращениями мы делаем нормальный колбек хендлер, 
# (а не пихаем его внутрь другого хендлера).
# в фильтр (лямбда функцию) пишем не какой-то бесполезный True, а конкретное условие
# в данном случае prefix2 (можем сделать любое, абы только совпадало 
# с тем что написано в колбек дате кнопки)
@bot.callback_query_handler(func=lambda call: call.data.split(":")[0] == "prefix2")
def querry_handler2(call):
    data_ = call.data.split(":")[1]
    if data_ == "1elf":
        bot.send_message(call.message.chat.id, 'YEEY, you have 1st')

Примерно вот так. Удачи и больше так не делайте

→ Ссылка