Много уровневое меню ReplyKeyboardMarkup

Всем привет, начал изучать создания бота на python с использованием pyTelegramBotAPI.
Не могу разобраться как с использованием ReplyKeyboardMarkup сделать многоуровневое меню.
По типу

  • Меню
    • Исходный язык
      • Английский
      • Русский
      • Другой язык
      • Другой язык
      • Назад(переход к Меню)
    • Язык перевода
      • Английский
      • Русский
      • Другой язык
      • Другой язык
      • Назад(переход к Меню)
    • Назад(переход к Меню)

Но не как не могу разобраться, как правильно сделать такое многоуровневое меню, как корректно отслеживать нажатия, чтобы при этом другие сообщения ни как не помешали процессу выбора в меню.

Сколько ищу не могу найти ни нормального туториала ни примера, все в примерах используют InlineKeyboardMarkup и уделяют работе с ней больше внимания чем ReplyKeyboardMarkup.

На первом скрине то что у меня получилось сделать.
На втором то как я хотел бы сделать.

Буду благодарен если кто объяснит как это нормально сделать.

Пример работы моего бота и бота с котрого беру пример

Исходный код моего бота

import config
import telebot
import translate
from telebot import types

bot = telebot.TeleBot(config.TOKEN)

Source_Language = 'Русский'
Target_Language = 'Английский'

@bot.message_handler(commands=['start'])
def first(message):
    keyboard = types.ReplyKeyboardMarkup(True,False)
    keyboard.add('Меню')
    send = bot.send_message(message.chat.id, 'Привет! Я переводчик! \n Знаю достаточно языков \n Просто напишите текст на английском или русском языке или нажмите ‘Меню’ внизу, чтобы сменить язык или выбрать режим работы.',reply_markup=keyboard)
    bot.register_next_step_handler(send,second)

def second(message):
    if message.text == 'Меню':
        keyboard = types.ReplyKeyboardMarkup(True,False)

        keyboard.row('Исходный язык','Язык перевода')
        keyboard.add('Cancel')
        send = bot.send_message(message.chat.id,'Выбирай', reply_markup=keyboard)
        bot.register_next_step_handler(send,third)
    else:
        bot.send_message(message.chat.id,'Сорян не понял')

def third(message):
    if message.text == 'Исходный язык':
        keyboard = types.ReplyKeyboardMarkup(True,False)
        keyboard.row('Английский','Русский')
        keyboard.add('Cancel')
        send = bot.send_message(message.chat.id,'Выбери язык', reply_markup=keyboard)
        bot.register_next_step_handler(send,Select_Source_Language)
    elif message.text == 'Язык перевода':
        keyboard = types.ReplyKeyboardMarkup(True,False)
        keyboard.row('Русский','Английский')
        keyboard.add('Cancel')
        send = bot.send_message(message.chat.id,'Выбери язык', reply_markup=keyboard)
        bot.register_next_step_handler(send,Select_Target_Language)
    elif message.text == 'Cancel':
        first(message)
    else:
        bot.send_message(message.chat.id,'Сорян не понял')

def SetSourceLanguage(message):
    global Source_Language
    Source_Language = message.text
    bot.send_message(message.chat.id,'Выбраны языки S:{} -> T:{}'.format(Source_Language,Target_Language))
    first(message)

def SetTargetLanguage(message):
    global Target_Language
    Target_Language = message.text
    bot.send_message(message.chat.id,'Выбраны языки S:{} -> T:{}'.format(Source_Language,Target_Language))
    first(message)

def Select_Source_Language(message):
    if message.text == 'Английский':
        SetSourceLanguage(message)
    elif message.text == 'Русский':
        SetSourceLanguage(message)
    elif message.text == 'Cancel':
        first(message)
    else:
        bot.send_message(message.chat.id,'Сорян не понял')

def Select_Target_Language(message):
    if message.text == 'Английский':
        SetTargetLanguage(message)
    elif message.text == 'Русский':
        SetTargetLanguage(message)
    elif message.text == 'Cancel':
        first(message)
    else:
        bot.send_message(message.chat.id,'Сорян не понял')

@bot.message_handler(content_types=["text"])
def send_messages(message): # Название функции не играет никакой роли, в принципе
    bot.send_message(message.chat.id,'это реакция на текст')


if __name__ == '__main__':
    bot.infinity_polling()

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

Автор решения: D. Violet

т.к. ReplyKeyboardMarkup является заготовкой текстового сообщения, которое отправляется в чат, Вам требуется обрабатывать все такие сообщения с помощью @bot.message_handler(content_types=["text"])

например так:

@bot.message_handler(commands=['start'])
def menu(message):
    start_menu = types.ReplyKeyboardMarkup(True, True)
    start_menu.row('Исходный язык', 'Язык перевода')
    bot.send_message(message.chat.id, 'Стартовое меню', reply_markup=start_menu)


@bot.message_handler(content_types=['text'])
def handle_text(message):
    if message.text == 'Исходный язык':
        source_language_menu = types.ReplyKeyboardMarkup(True, True)
        source_language_menu.row('Английский', 'Русский')
        source_language_menu.row('Другой', 'Другой 1')
        source_language_menu.row('Назад')
        bot.send_message(message.chat.id, 'Исходный язык - меню', reply_markup=source_language_menu)

    elif message.text == 'Язык перевода':
        translation_language_menu = types.ReplyKeyboardMarkup(True, True)
        translation_language_menu.row('Английский', 'Русский')
        translation_language_menu.row('Другой', 'Другой 1')
        translation_language_menu.row('Назад')
        bot.send_message(message.chat.id, 'Язык перевода - меню', reply_markup=translation_language_menu)

    elif message.text == 'Назад':
        menu(message)

однако если я не верно трактовал Ваш вопрос, Вы можете уточнить в комментариях с чем именно сложность.

→ Ссылка