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

的维护者