#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. Я сделал это некоторое время назад, спасибо.