gpt4 book ai didi

python - 使用 python-telegram-bot 构建菜单的正确方法

转载 作者:太空狗 更新时间:2023-10-29 21:35:58 34 4
gpt4 key购买 nike

我使用 python-telegram-bot 并尝试像 BotFather 机器人那样构建一个嵌套菜单系统。例如,您有一个通用的机器人菜单

pic.1

您可以在其中选择“编辑机器人”并获得相应的新菜单

pic.2

带有返回上一个菜单的选项。

我尝试用代码来实现:

# main menu
def start(bot, update):
menu_main = [[InlineKeyboardButton('Option 1', callback_data='m1')],
[InlineKeyboardButton('Option 2', callback_data='m2')],
[InlineKeyboardButton('Option 3', callback_data='m3')]]
reply_markup = InlineKeyboardMarkup(menu_main)
update.message.reply_text('Choose the option:', reply_markup=reply_markup)

# all other menus
def menu_actions(bot, update):
query = update.callback_query

if query.data == 'm1':
# first submenu
menu_1 = [[InlineKeyboardButton('Submenu 1-1', callback_data='m1_1')],
[InlineKeyboardButton('Submenu 1-2', callback_data='m1_2')]]
reply_markup = InlineKeyboardMarkup(menu_1)
bot.edit_message_text(chat_id=query.message.chat_id,
message_id=query.message.message_id,
text='Choose the option:',
reply_markup=reply_markup)
elif query.data == 'm2':
# second submenu
# first submenu
menu_2 = [[InlineKeyboardButton('Submenu 2-1', callback_data='m2_1')],
[InlineKeyboardButton('Submenu 2-2', callback_data='m2_2')]]
reply_markup = InlineKeyboardMarkup(menu_2)
bot.edit_message_text(chat_id=query.message.chat_id,
message_id=query.message.message_id,
text='Choose the option:',
reply_markup=reply_markup)
elif query.data == 'm1_1':
...
elif query.data == 'm1_2':
...
# and so on for every callback_data option

...

# handlers
dispatcher.add_handler(CommandHandler('start', start))
dispatcher.add_handler(CallbackQueryHandler(menu_actions))

此代码有效,但我觉得它有点不合理 — 构建一个长的 elif 树。

此外,我不知道如何为用户提供从二级菜单返回主菜单的选项(因为主菜单位于另一个处理程序中,我无法通过回调捕获它来自 CallbackQueryHandler)。

所以问题是——构建这种菜单系统的最佳实践是什么?

最佳答案

您应该在 CallbackQueryHandler 中使用参数 pattern。为键盘和消息使用类或函数也是一件好事。
要返回主菜单,请将返回按钮添加到具有特定回调模式的子菜单。

请注意:您在菜单中使用edit_message_text。这意味着如果您从任何菜单中使用 reply_text 方法调用 start 函数,则不会发生任何事情。

具有功能的完整工作示例:

#!/usr/bin/env python3.8
from telegram.ext import Updater
from telegram.ext import CommandHandler, CallbackQueryHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
############################### Bot ############################################
def start(bot, update):
bot.message.reply_text(main_menu_message(),
reply_markup=main_menu_keyboard())

def main_menu(bot, update):
bot.callback_query.message.edit_text(main_menu_message(),
reply_markup=main_menu_keyboard())

def first_menu(bot, update):
bot.callback_query.message.edit_text(first_menu_message(),
reply_markup=first_menu_keyboard())

def second_menu(bot, update):
bot.callback_query.message.edit_text(second_menu_message(),
reply_markup=second_menu_keyboard())

def first_submenu(bot, update):
pass

def second_submenu(bot, update):
pass

def error(update, context):
print(f'Update {update} caused error {context.error}')

############################ Keyboards #########################################
def main_menu_keyboard():
keyboard = [[InlineKeyboardButton('Menu 1', callback_data='m1')],
[InlineKeyboardButton('Menu 2', callback_data='m2')],
[InlineKeyboardButton('Menu 3', callback_data='m3')]]
return InlineKeyboardMarkup(keyboard)

def first_menu_keyboard():
keyboard = [[InlineKeyboardButton('Submenu 1-1', callback_data='m1_1')],
[InlineKeyboardButton('Submenu 1-2', callback_data='m1_2')],
[InlineKeyboardButton('Main menu', callback_data='main')]]
return InlineKeyboardMarkup(keyboard)

def second_menu_keyboard():
keyboard = [[InlineKeyboardButton('Submenu 2-1', callback_data='m2_1')],
[InlineKeyboardButton('Submenu 2-2', callback_data='m2_2')],
[InlineKeyboardButton('Main menu', callback_data='main')]]
return InlineKeyboardMarkup(keyboard)

############################# Messages #########################################
def main_menu_message():
return 'Choose the option in main menu:'

def first_menu_message():
return 'Choose the submenu in first menu:'

def second_menu_message():
return 'Choose the submenu in second menu:'

############################# Handlers #########################################
updater = Updater('XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', use_context=True)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CallbackQueryHandler(main_menu, pattern='main'))
updater.dispatcher.add_handler(CallbackQueryHandler(first_menu, pattern='m1'))
updater.dispatcher.add_handler(CallbackQueryHandler(second_menu, pattern='m2'))
updater.dispatcher.add_handler(CallbackQueryHandler(first_submenu, pattern='m1_1'))
updater.dispatcher.add_handler(CallbackQueryHandler(second_submenu, pattern='m2_1'))
updater.dispatcher.add_error_handler(error)

updater.start_polling()
################################################################################

抱歉,我在制表符中有两个空格。 :)

更新:修复子菜单对象。

关于python - 使用 python-telegram-bot 构建菜单的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51125356/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com