ConversationHandler не работает при развертывании на Heroku, но хорошо работает при запуске на локальной машине

#python-telegram-bot

Вопрос:

Я использую библиотеку ботов для телеграмм Python, чтобы создать бота, у которого есть диалог, который позволяет пользователям называть свой проект, планы платежей и т. Д. Разговор состоит из обработчиков сообщений и обработчиков обратного вызова. Проблема, с которой я сталкиваюсь, заключается в том, что этот разговор работал нормально, когда я использовал этого бота со своего локального компьютера, но когда я развернул его на heroku, я не могу вести полный разговор, в какой-то момент он перестанет отвечать, и мне придется отменить разговор(что удивительно, работает со скоростью молнии). Все остальные обработчики моего приложения работают так, как ожидалось, и быстро реагируют.

Я использую webhook в этом приложении.

Собеседник:

 add_project_handler = ConversationHandler(
        entry_points=[CallbackQueryHandler(project_name, pattern="add_project")],
        states={
            PROJECT_NAME: [MessageHandler(Filters.regex(".*"), store_name_maybe_project_type)],
            PROJECT_TYPE: [CallbackQueryHandler(store_type_maybe_admin)],
            ADMIN:[CallbackQueryHandler(connect_channel)],
            CONNECT:[MessageHandler(Filters.regex(".*"), connect_channel_add_currency)],
            CURRENCY:[CallbackQueryHandler(store_currency_maybe_frequency)],
            FREQUENCY:[CallbackQueryHandler(store_frequency_maybe_amount)],
            MONEY:[MessageHandler(Filters.regex(".*"), store_amount_maybe_bot)],
            TOKEN:[MessageHandler(Filters.regex(".*"), store_bot_show_links)],
            PAY_SETUP:[CallbackQueryHandler(setup_payment)],
            PAYPAL:[MessageHandler(Filters.regex(".*"), handle_client_id)],
            CLIENT_ID:[MessageHandler(Filters.regex(".*"), handle_client_secret)],
        },
        fallbacks=[CommandHandler('cancel', cancel)],
    )
handlers.append(add_project_handler)
 

Редактировать:

Поэтому я проверил журналы и увидел действительно странное поведение, поэтому он получает обновление, и прямо сейчас состояние разговора должно было быть 1, но там написано «выбор разговора с состоянием Нет». Это тоже происходит трижды.

 2021-10-01T16:55:59.411864 00:00 heroku[router]: at=info method=POST path="/1967487217:AAGDmzoxPPlB386VuEYr4s8dPM50fr49d84" host=invitememberbot.herokuapp.com request_id=6d10ee36-ebe4-40de-91b3-48c5e33d6172 fwd="91.108.6.63" dyno=web.1 connect=0ms service=2ms status=200 bytes=154 protocol=https
2021-10-01T16:55:59.415201 00:00 app[web.1]: 2021-10-01 16:55:59,414 - telegram.ext.dispatcher - DEBUG - Processing Update: {'callback_query': {'chat_instance': '1523769404808794079', 'id': '4756348607585474313', 'data': 'channel', 'message': {'delete_chat_photo': False, 'chat': {'id': 1107423707, 'first_name': 'Palash', 'type': 'private', 'username': 'raghu_palash', 'last_name': 'Raghuwanshi'}, 'channel_chat_created': False, 'date': 1633106830, 'supergroup_chat_created': False, 'reply_markup': {'inline_keyboard': [[{'callback_data': 'channel', 'text': 'Paid Telegram Channel'}]]}, 'group_chat_created': False, 'photo': [], 'caption_entities': [], 'new_chat_members': [], 'message_id': 2657, 'entities': [], 'text': 'What do you want to make?', 'new_chat_photo': [], 'from': {'id': 1967487217, 'first_name': 'InviteMemberBot', 'username': 'InviteMemberFiverrBot', 'is_bot': True}}, 'from': {'language_code': 'en', 'last_name': 'Raghuwanshi', 'id': 1107423707, 'first_name': 'Palash', 'username': 'raghu_palash', 'is_bot': False}}, 'update_id': 334393256}
2021-10-01T16:55:59.415374 00:00 app[web.1]: 2021-10-01 16:55:59,415 - telegram.ext.conversationhandler - DEBUG - selecting conversation (1107423707, 1107423707) with state None
2021-10-01T16:55:59.415584 00:00 app[web.1]: 10.1.90.119 - - [01/Oct/2021:16:55:59  0000] "POST /1967487217:AAGDmzoxPPlB386VuEYr4s8dPM50fr49d84 HTTP/1.1" 200 2 "-" "-"
2021-10-01T16:55:59.415742 00:00 app[web.1]: 2021-10-01 16:55:59,415 - telegram.ext.conversationhandler - DEBUG - selecting conversation (1107423707, 1107423707) with state None
2021-10-01T16:55:59.415867 00:00 app[web.1]: 2021-10-01 16:55:59,415 - telegram.ext.conversationhandler - DEBUG - selecting conversation (1107423707, 1107423707) with state None
 

И вот что еще более странно: когда я дважды быстро нажимаю на кнопку, она переводит меня в следующее состояние.

 2021-10-01T17:15:24.421256 00:00 heroku[router]: at=info method=POST path="/1967487217:AAGDmzoxPPlB386VuEYr4s8dPM50fr49d84" host=invitememberbot.herokuapp.com request_id=ea099aff-e9dd-46fa-8516-958677290171 fwd="91.108.6.63" dyno=web.1 connect=0ms service=6ms status=200 bytes=154 protocol=https
2021-10-01T17:15:24.420031 00:00 app[web.1]: 2021-10-01 17:15:24,419 - telegram.ext.dispatcher - DEBUG - Processing Update: {'callback_query': {'chat_instance': '1523769404808794079', 'id': '4756348606350994438', 'data': 'channel_done', 'message': {'delete_chat_photo': False, 'chat': {'id': 1107423707, 'first_name': 'Palash', 'type': 'private', 'username': 'raghu_palash', 'last_name': 'Raghuwanshi'}, 'channel_chat_created': False, 'date': 1633107558, 'supergroup_chat_created': False, 'reply_markup': {'inline_keyboard': [[{'callback_data': 'channel_done', 'text': 'Done'}]]}, 'group_chat_created': False, 'photo': [], 'caption_entities': [], 'new_chat_members': [], 'message_id': 2659, 'entities': [], 'text': "Please create a private Telegram channel and click Done when it's ready:", 'new_chat_photo': [], 'from': {'id': 1967487217, 
'first_name': 'InviteMemberBot', 'username': 'InviteMemberFiverrBot', 'is_bot': True}}, 'from': {'language_code': 'en', 
'last_name': 'Raghuwanshi', 'id': 1107423707, 'first_name': 'Palash', 'username': 'raghu_palash', 'is_bot': False}}, 'update_id': 334393260}
2021-10-01T17:15:24.420209 00:00 app[web.1]: 2021-10-01 17:15:24,420 - telegram.ext.conversationhandler - DEBUG - selecting conversation (1107423707, 1107423707) with state 1
 

I don’t understand why it worked fine when I ran it on my own machine, but does this on heroku.

Additional Information —

These are the functions that are involved in this log:

 def store_type_maybe_admin(update, context):
    # Open db connection
    conn = DB_POOL.getconn()
    cur = conn.cursor()

    # stores project type and conditonally asks for making admin
    query = update.callback_query
    query.answer()

    keyboard = [[InlineKeyboardButton("Done", callback_data="channel_done")]]
    reply_markup = InlineKeyboardMarkup(keyboard)
    if query.data != "channel_done":
        context.user_data["project_type"] = query.data
        q = "UPDATE project SET project_type = %s WHERE id = %s"
        cur.execute(q, (query.data, context.user_data["project_id"]))
        conn.commit()
        message = f"Please create a private Telegram {query.data} and click Done when it's ready:"
        video = "BAACAgUAAxkDAAICCGFK8ud7FDZ2qbzOkQfrDId-abgXAAKqAwAC-KBYVquzwMps2x7GIQQ"
        return_value = PROJECT_TYPE
    else:
        message = "Please add this bot (@InviteMemberFiverrBot) to the channel admins. It needs Add Subscribers permission.nnPress Done when it's ready:" 
        video = "BAACAgUAAxkDAAICFmFK9GB185nfUvTeE6P3ZTnEp1YEAAKxAwAC-KBYVtfAgpeMwSB0IQQ"
        return_value = ADMIN
    # Send a video
    context.bot.send_video(chat_id=update.effective_chat.id, video=video)
    context.bot.send_message(chat_id=update.effective_chat.id ,text=message, reply_markup=reply_markup, parse_mode="markdown")

    DB_POOL.putconn(conn)
    return return_value # will be either PROJECT_TYPE = 1 or ADMIN = 2

def connect_channel(update, context):
    query = update.callback_query
    query.answer()

    video = "BAACAgUAAxkDAAICGWFK9ShTxKcIN32o9njkIQMCXcwoAAKyAwAC-KBYVi7hYk0auE7IIQQ"
    context.bot.send_video(chat_id=update.effective_chat.id, video=video)
    context.bot.send_message(
        chat_id=update.effective_chat.id, 
        text=f"To connect the channel, please forward a message (any) from the channel to this bot."
    )
    return CONNECT
 

Вот как я настроил своего бота:

 bot = telegram.Bot(token=TOKEN)
dispatcher = setup(bot, db_pool)

@app.route(f"/{TOKEN}", methods=["POST"])
def respond():
    """Run the bot."""
    update = telegram.Update.de_json(request.get_json(force=True), bot)
    dispatcher.process_update(update)
    return "ok"
 

функция настройки:

 def setup(bot, db_pool):

    # Create bot, update queue and dispatcher instances
    dispatcher = Dispatcher(bot, None, workers=0)

    ##### Register handlers here #####
    initialize_bot_handlers = initialize_bot(db_pool) # initialize_bot returns a list of handlers
    for handler in initialize_bot_handlers:
        dispatcher.add_handler(handler)
    
    return dispatcher
 

Обработчик разговора находится внутри функции initialize_bot.

Комментарии:

1. Я рекомендую установить уровень журнала PTBs для отладки и проверить как журнал heroku, так и журналы ptbs. Кстати, как и Filters.regex(".*") любой текст, вы также можете просто использовать Filters.text .

2. Спасибо за предложение @CallMeStag, я обновил ответ после получения выходных данных журнала, также я добавил информацию, которая может потребоваться, я был бы очень признателен, если бы вы помогли мне с этим.

3. вы должны отозвать токен бота, который вы опубликовали в журналах 😉

4. Я сделал это некоторое время назад, спасибо.