我试图同时处理InlineKeyboardButton callback_data和自由文本数据。这是我的情况:
提示带有多个按钮的InlineKeyboard,用户单击一个按钮,然后要求输入一些自由文本以供BE使用。
我试图将CallbackQueryHandler(回调函数中的几个InlineKeyboardMarkup)用作ConversationHandler的入口点,然后触发MessageHandler,但没有成功。 我需要捕获自由文本更新(基本上等待用户输入)。
def start(update, context):
keyboard = [[InlineKeyboardButton("bal bla", callback_data='1'),
InlineKeyboardButton("bla bla", callback_data='2')],
[InlineKeyboardButton("bla bla)", callback_data='3'),
InlineKeyboardButton("bla bla", callback_data= '4')],
[InlineKeyboardButton("bla bla", callback_data='5')]]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text('Please choose:', reply_markup=reply_markup)
reply_text = {'text': ''}
def reply_message(update, context):
message = update.message.text
reply_text['text'] = message
return reply_text['text']
def button(update, context, user_data):
query = update.callback_query
query.edit_message_text(text="Loading....\n \r")
if query.data == '1':
pass
elif query.data == '2':
pass
elif query.data == '3':
keyboard = [[InlineKeyboardButton('BBB', callback_data='21'),
InlineKeyboardButton('GGG', callback_data='22')],
[InlineKeyboardButton('PPP', callback_data='23')]]
reply_markup1 = InlineKeyboardMarkup(keyboard)
query.edit_message_text('Please select:', reply_markup=reply_markup1)
elif query.data == '21':
query.edit_message_text('input customer name ')
return 1
if : #no idea which condition to give here
print(reply_text['text'], '\n ^ new free text message here ^')
def main():
conv_handler= ConversationHandler(
entry_points=[
CallbackQueryHandler(button)
],
states={
1 : [MessageHandler(Filters.text, reply_message)],
},
fallbacks= []
)
try:
updater = Updater(bot_token, use_context=True)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CallbackQueryHandler(button))
updater.dispatcher.add_handler(conv_handler)
updater.start_polling()
updater.idle()
except Exception as e:
print(e)
答案 0 :(得分:0)
嘿,我通过提供一个函数来解析用户输入并使用上下文的user_data方法记住输入来解决了这个问题。
def check_user_input(update, context):
# get last user text
user_input = update.message.text
# get user_data context
user_data = context.user_data
# set new context user_input
user_data['user_input'] = user_input
context.user_data['user_input'] = user_data['user_input']
if "Text" in user_input:
# do something... i.e reply w/o keyboard
update.message.reply_text(
("{}?!, sounds interesting, tell me more".format(
user_input)))
return GUEST_CHOICE
else:
# ask again
reply_keyboard = [['Text'],['Done']]
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
update.message.reply_text(
("{}?!, i dont know anything...".format(
user_input),reply_markup=markup))
return CHECK_CHOICE
这似乎是处理和记住用户输入的首选方法。
现在可以根据需要在ConversationHandler / MessageHandlers中调用此函数。您只需返回指定的ConversationHandler状态。因此,我将使用两个状态(GUEST_CHOICE和CHECK_CHOICE状态)来处理单个用户输入验证。
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
states={
# Ask Guest
GUEST_CHOICE: [MessageHandler(Filters.regex('^(Text)$'),
guest_choice),
],
# Verify input
CHECK_CHOICE: [MessageHandler(Filters.text,
check_user_input),
],
},
fallbacks=[MessageHandler(Filters.regex('^Done$'), done, CommandHandler('start', start))],
allow_reentry = False,
per_user=True,
conversation_timeout=3600,
name="test"
)
按照定义,/ start用作用户启动对话处理程序。这将调用start()方法,即:
def start(update, context):
reply_keyboard = [['Text'],['Done']]
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
# Setup keyboard and reply
update.message.reply_text(
("Hey {}, how can i help you?".format(
update.message.chat['first_name'])),
reply_markup=markup)
return CHECK_CHOICE
start()将设置标记键盘,之后的任何输入都将以CHECK_CHOICE状态处理,此状态将在此处调用check_user_input(请参见上文)。这将返回GUEST_CHOICE,因此它将调用guest_choice(),即:
def guest_choice(update, context):
user_data = context.user_data
# Check authentication request
if "bob" in user_data['user_input']:
update.message.reply_text("Hey {}".format(user_data['user_input']))
else:
update.message.reply_text("Where is bob?!")
return CHECK_INPUT
“完成”方法将清理对话
def done(update, context):
markup = get_markup(context)
update.message.reply_text("Bye")
return ConversationHandler.END
好的,很快就升级了……我从自己的会话处理程序的工作版本中重写了该代码,请检查是否存在错误:)也许必须在Done方法中清除user_data。