我正在尝试使用python-telegram-bot
软件包创建电报对话机器人,我想知道对对话中每个状态实现"返回主菜单"按钮的最佳实践是什么。<<<<<<<<<<<<<<<<<</p>
出于某种原因,我觉得我以错误的方式做。背向主菜单按钮实际上除了绘制应该立即绘制主菜单按钮外没有任何作用,但通常需要0.5-3秒,有时甚至更长(一次只有一个用户与Bot交谈(。
我基本上对每个状态都使用 CallbackQueryHandler(back_to_main_menu, pattern='^main_menu$')
,尽管我到目前为止找不到其他更好的解决方案,但我敢肯定这不是正确的方法。
注意:下面的示例只是我如何使用CallbackQueryHandler
的一个示例。我的状态机有13个州,其中10个状态我得到了一个主菜单按钮。
我需要的简短示例:
import os
from telegram.ext import Updater, ConversationHandler, CommandHandler, CallbackQueryHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardRemove
FIRST, SECOND, MAIN_MENU = range(3)
def get_main_menu():
return [[InlineKeyboardButton("First", callback_data='first')],
[InlineKeyboardButton("Second", callback_data='second')]]
def add_main_menu_button(bot, update, message, menu):
query = update.callback_query
menu.append([InlineKeyboardButton("Back to main menu", callback_data="main_menu")])
reply_markup = InlineKeyboardMarkup(menu)
bot.edit_message_text(message, chat_id=query.message.chat_id, message_id=query.message.message_id,
reply_markup=reply_markup)
def back_to_main_menu(bot, update):
query = update.callback_query
reply_markup = InlineKeyboardMarkup(get_main_menu())
bot.edit_message_text("Example example 2", chat_id=query.message.chat_id, message_id=query.message.message_id, reply_markup=reply_markup)
return MAIN_MENU
def second(bot, update):
add_main_menu_button(bot, update, "E e", list())
def first(bot, update):
add_main_menu_button(bot, update, "T t", list())
def start(bot, update):
reply_markup = InlineKeyboardMarkup(get_main_menu())
update.message.reply_text("Example example 1", reply_markup=reply_markup)
return MAIN_MENU
def cancel(bot, update):
update.message.reply_text('Bye! I hope we can talk again some day.', reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
def main():
updater = Updater(os.environ["BOT_TOKEN"])
conversation_handler = ConversationHandler(entry_points=[CommandHandler('start', start)],
states={FIRST: [CallbackQueryHandler(back_to_main_menu, pattern='^main_menu$')],
SECOND: [CallbackQueryHandler(back_to_main_menu, pattern='^main_menu$')],
MAIN_MENU: [CallbackQueryHandler(first, pattern='first'),
CallbackQueryHandler(second)]},
fallbacks=[CommandHandler('cancel', cancel)],
allow_reentry=True
)
updater.dispatcher.add_handler(conversation_handler)
updater.start_polling()
updater.idle()
此外,当我在对话中使用多个callbackqueryhandler时,我会收到以下警告:
WARNING:root:If 'per_message=False', 'CallbackQueryHandler' will not be tracked for every message
这让我认为自己做错了。
谢谢。
对于每个对话,您只需要将一个CallbackQueryHandler
指定为后备。例如:
START = range(1)
start_conv_handler = ConversationHandler(entry_points=[CommandHandler('start', start)],
states={
START: [CommandHandler('start', start)]
},
fallbacks= CallbackQueryHandler(main_callback_handler)]
)
,然后在该单一的CallbackQueryHandler
中您可以计划所有希望按钮执行的尸体操作。由于您可以在处理程序收到的查询中添加任何需要的信息,因此可以通过将return CallbackQueryHandler
放在描述对话步骤的每个函数的末尾(在我的示例中start
(来播放更复杂的方案。
所以看起来像:
def start(bot, update):
... your code here
return CallbackQueryHandler