对话状态的双重性。如何强制bot仅在子ConversationHandler中检查更新?
我在使用ConversationHandler的时候遇到了一些问题,可能是因为我对它的用法理解得不太透彻。我在PTB中使用父子ConversationHandlers,具体是这样:
...
child_conv_handler = ConversationHandler(
entry_points=[CommandHandler("start_child", start_child_func)],
states={
CHILD_STATE: [
CommandHandler("search", search),
CommandHandler("add", add),
CommandHandler("exit", exit),
],
},
fallbacks=[MessageHandler(filters.TEXT, fallback_message),],
)
parent_conv_handler = ConversationHandler(
entry_points=[CommandHandler("start_parent", start_parent_func)],
states={
PARENT_STATE: [
CommandHandler("stats", stats),
child_conv_handler,
],
},
fallbacks=[CommandHandler("stop", stop)],
)
application.add_handler(parent_conv_handler)
application.run_polling(allowed_updates=Update.ALL_TYPES)
我进行的操作如下:
- 发送了/start_parent来启动父ConversationHandler;
- start_parent_func这个回调函数返回了对话状态PARENT_STATE;
- 发送了/start_child来启动子ConversationHandler;
- start_child_func这个回调函数返回了对话状态CHILD_STATE;
(注意!)
- 发送了/stats命令,
CommandHandler("stats", stats)
被触发(stats回调函数正常工作!)。
看起来所有的更新首先都是由PARENT_STATE的处理器来检查。这意味着机器人同时处于两个状态:PARENT_STATE和CHILD_STATE。出于某种原因,PARENT_STATE的优先级更高。但我希望CHILD_STATE的优先级更高,能够先被检查。
是的,我可以把children_conv_handler放在列表的最前面,这样就能得到我想要的结果(触发MessageHandler(filters.TEXT, fallback_message)
),但如果我需要两个子处理器child_conv_handler1和child_conv_handler2呢?在这种情况下,我不知道该怎么做。如何让CHILD_STATE成为主要状态,或者如何让parent_conv_handler进入某种“死胡同状态”,以便子处理器可以启动?
更新1: 这是一个包含两个子ConversationHandlers的例子:
...
child_conv_handler1 = ConversationHandler(
entry_points=[CommandHandler("start_child1", start_child_func1)],
states={
CHILD_STATE1: [
CommandHandler("stats", child_stats1),
],
},
fallbacks=[MessageHandler(filters.TEXT, fallback_message),],
)
child_conv_handler2 = ConversationHandler(
entry_points=[CommandHandler("start_child2", start_child_func2)],
states={
CHILD_STATE2: [
CommandHandler("stats", child_stats2),
],
},
fallbacks=[MessageHandler(filters.TEXT, fallback_message),],
)
parent_conv_handler = ConversationHandler(
entry_points=[CommandHandler("start_parent", start_parent_func)],
states={
PARENT_STATE: [
CommandHandler("stats", parent_stats),
child_conv_handler1,
child_conv_handler2
],
},
fallbacks=[CommandHandler("stop", stop)],
)
application.add_handler(parent_conv_handler)
application.run_polling(allowed_updates=Update.ALL_TYPES)
1 个回答
第一个返回True的处理器的check_update()方法将会被使用。
调整一下
更新1:在确定哪个处理器来处理更新时,并没有特别处理子对话。所以目前没有内置的方法来处理有两个子对话的情况。一个解决办法是把每个子对话放在不同的父状态中,或者把两个子对话合并成一个。我已经把这个问题添加到https://github.com/python-telegram-bot/python-telegram-bot/issues/2770上。
免责声明:我目前是python-telegram-bot
的维护者。