Python Telegram Bot ConversationHandler 无法使用 webhook
Python Telegram Bot ConversationHandler not working with webhook
我想在我的机器人中创建一个使用 webhook 的 ConversationHandler,ConversationHandler 仅 运行 入口点的函数,之后它也不会 运行 状态函数, 运行 也不是回退函数。这个 CommandHandler 运行 在 bot 运行 轮询时没问题。
对话处理程序:
conv_handler = ConversationHandler(
entry_points=[CommandHandler("start", start)],
states={
NEW_PROJECT: [CallbackQueryHandler(project_name)],
PROJECT_NAME: [MessageHandler(Filters.regex(".*"), store_name_maybe_project_type)],
PROJECT_TYPE: [CallbackQueryHandler(store_type_maybe_admin)]
},
fallbacks=[CommandHandler('cancel', cancel)],
)
所有需要的函数:
def start(update, context):
# Gives button of add project
# We can use for loop to display buttons
keyboard = [
[InlineKeyboardButton("Add Project", callback_data="add_project")],
]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text("You have no projects right now.", reply_markup=reply_markup)
# if existing project then PROJECT or else NEW_PROJECT
return NEW_PROJECT
def project_name(update, context):
# asks for project name
query = update.callback_query
update.message.reply_text(text="Okay, Please enter your project name:")
return PROJECT_NAME
def store_name_maybe_project_type(update, context):
# stores project name and conditionally asks for project type
print(update.message.text)
keyboard = [
[InlineKeyboardButton("Telegram Group", callback_data="group")],
[InlineKeyboardButton("Telegram Channel", callback_data="channel")]
]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text("What do you want to make?", reply_markup=reply_markup)
return PROJECT_TYPE
def store_type_maybe_admin(update, context):
# stores project type and conditonally asks for making admin
print(update.message.text)
keyboard = [[InlineKeyboardButton("Done", callback_data="done")]]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text(f"Make a private {update.message.text} and make this bot the admin", reply_markup=reply_markup)
return ConversationHandler.END
def cancel(update, context):
update.message.reply_text("Awww, that's too bad")
return ConversationHandler.END
这是我设置 webhook 的方式(我认为问题出在某处):
@app.route(f"/{TOKEN}", methods=["POST"])
def respond():
"""Run the bot."""
update = telegram.Update.de_json(request.get_json(force=True), bot)
dispatcher = setup(bot, update)
dispatcher.process_update(update)
return "ok"
设置函数
def setup(bot, update):
# Create bot, update queue and dispatcher instances
dispatcher = Dispatcher(bot, None, workers=0)
##### Register handlers here #####
bot_handlers = initialize_bot(update)
for handler in bot_handlers:
dispatcher.add_handler(handler)
return dispatcher
然后我使用这条路线手动设置 webhook:
@app.route("/setwebhook", methods=["GET", "POST"])
def set_webhook():
s = bot.setWebhook(f"{URL}{TOKEN}")
if s:
return "webhook setup ok"
else:
return "webhook setup failed"
The add project button doesn't do anything.
ConversationHandler
将当前状态存储在内存中,因此一旦 conv_handler
到达其生命周期结束(即变量被删除或进程关闭),它就会丢失。现在您的代码片段没有显示您初始化 ConversationHandler
的位置,但我感觉您为每次传入的更新重新创建它 - 而且每个新实例都不知道前一个实例。
我有这种感觉,因为您也为每次更新创建了一个新的 Dispatcher
。那不是必需的,事实上我强烈建议不要这样做。不仅初始化可以保存的 Dispatcher
需要时间,而且如果您使用 chat/user/bot_data
,每次创建新实例时数据都会丢失。
initialize_bot
函数在 setup
中被调用,您在其中创建了新的 Dispatcher
,这就是为什么我的猜测是您创建了一个新的 ConversationHandler
每次更新。此外,我觉得该函数的 return 值似乎取决于 update
- 你的调度程序使用的处理程序应该是固定的......
免责声明:我目前是 python-telegram-bot
的维护者
我想在我的机器人中创建一个使用 webhook 的 ConversationHandler,ConversationHandler 仅 运行 入口点的函数,之后它也不会 运行 状态函数, 运行 也不是回退函数。这个 CommandHandler 运行 在 bot 运行 轮询时没问题。
对话处理程序:
conv_handler = ConversationHandler(
entry_points=[CommandHandler("start", start)],
states={
NEW_PROJECT: [CallbackQueryHandler(project_name)],
PROJECT_NAME: [MessageHandler(Filters.regex(".*"), store_name_maybe_project_type)],
PROJECT_TYPE: [CallbackQueryHandler(store_type_maybe_admin)]
},
fallbacks=[CommandHandler('cancel', cancel)],
)
所有需要的函数:
def start(update, context):
# Gives button of add project
# We can use for loop to display buttons
keyboard = [
[InlineKeyboardButton("Add Project", callback_data="add_project")],
]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text("You have no projects right now.", reply_markup=reply_markup)
# if existing project then PROJECT or else NEW_PROJECT
return NEW_PROJECT
def project_name(update, context):
# asks for project name
query = update.callback_query
update.message.reply_text(text="Okay, Please enter your project name:")
return PROJECT_NAME
def store_name_maybe_project_type(update, context):
# stores project name and conditionally asks for project type
print(update.message.text)
keyboard = [
[InlineKeyboardButton("Telegram Group", callback_data="group")],
[InlineKeyboardButton("Telegram Channel", callback_data="channel")]
]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text("What do you want to make?", reply_markup=reply_markup)
return PROJECT_TYPE
def store_type_maybe_admin(update, context):
# stores project type and conditonally asks for making admin
print(update.message.text)
keyboard = [[InlineKeyboardButton("Done", callback_data="done")]]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text(f"Make a private {update.message.text} and make this bot the admin", reply_markup=reply_markup)
return ConversationHandler.END
def cancel(update, context):
update.message.reply_text("Awww, that's too bad")
return ConversationHandler.END
这是我设置 webhook 的方式(我认为问题出在某处):
@app.route(f"/{TOKEN}", methods=["POST"])
def respond():
"""Run the bot."""
update = telegram.Update.de_json(request.get_json(force=True), bot)
dispatcher = setup(bot, update)
dispatcher.process_update(update)
return "ok"
设置函数
def setup(bot, update):
# Create bot, update queue and dispatcher instances
dispatcher = Dispatcher(bot, None, workers=0)
##### Register handlers here #####
bot_handlers = initialize_bot(update)
for handler in bot_handlers:
dispatcher.add_handler(handler)
return dispatcher
然后我使用这条路线手动设置 webhook:
@app.route("/setwebhook", methods=["GET", "POST"])
def set_webhook():
s = bot.setWebhook(f"{URL}{TOKEN}")
if s:
return "webhook setup ok"
else:
return "webhook setup failed"
The add project button doesn't do anything.
ConversationHandler
将当前状态存储在内存中,因此一旦 conv_handler
到达其生命周期结束(即变量被删除或进程关闭),它就会丢失。现在您的代码片段没有显示您初始化 ConversationHandler
的位置,但我感觉您为每次传入的更新重新创建它 - 而且每个新实例都不知道前一个实例。
我有这种感觉,因为您也为每次更新创建了一个新的 Dispatcher
。那不是必需的,事实上我强烈建议不要这样做。不仅初始化可以保存的 Dispatcher
需要时间,而且如果您使用 chat/user/bot_data
,每次创建新实例时数据都会丢失。
initialize_bot
函数在 setup
中被调用,您在其中创建了新的 Dispatcher
,这就是为什么我的猜测是您创建了一个新的 ConversationHandler
每次更新。此外,我觉得该函数的 return 值似乎取决于 update
- 你的调度程序使用的处理程序应该是固定的......
免责声明:我目前是 python-telegram-bot