Python Telegram Bot 如何等待用户回答问题并返回 [英] Python Telegram Bot how to wait for user answer to a question And Return It
问题描述
上下文:
我正在使用 PyTelegramBotAPi 或 Python 电报机器人
当用户开始对话时,我正在运行一个代码.
I have a code I am running when a user starts the conversation.
当用户开始对话时,我需要向他发送第一张图片和一个问题他是否看到图片中的东西,该函数需要等待用户输入并返回是否他看到了.
When the user starts the conversation I need to send him the first picture and a question if He saw something in the picture, the function needs to wait for the user input and return whether he saw it or not.
之后,我需要不断循环发送图片并等待答案并对其运行二分算法.
After that, I will need to keep sending the picture in a loop and wait for the answer and run a bisection algorithm on it.
到目前为止我尝试过的:
我尝试使用等待响应的回复标记或带有处理程序的内联键盘,但我被卡住了,因为我的代码正在运行而没有等待用户输入.
I tried to use reply markup that waits for a response or an inline keyboard with handlers but I am stuck because my code is running without waiting for the user input.
代码:
@bot.message_handler(func=lambda msg: msg in ['Yes', 'No'])
@bot.message_handler(commands=['start', 'help'])
def main(message):
"""
This is my main function
"""
chat_id = message.chat.id
try:
reply_answer = message.reply_to_message.text
except AttributeError:
reply_answer = '0'
# TODO : should wait for the answer asynchnonossly
def tester(n, reply_answer):
"""
Displays the current candidate to the user and asks them to
check if they see wildfire damages.
"""
print('call......')
bisector.index = n
bot.send_photo(
chat_id=chat_id,
photo=bisector.image.save_image(),
caption=f"Did you see it Yes or No {bisector.date}",
reply_markup=types.ForceReply(selective=True))
# I SHOUL WAIT FOR THE INPUT HERE AND RETURN THE USER INPUT
return eval(reply_answer)
culprit = bisect(bisector.count, lambda x: x, partial(tester, reply_answer=reply_answer) )
bisector.index = culprit
bot.send_message(chat_id, f"Found! First apparition = {bisector.date}")
bot.polling(none_stop=True)
我在用户输入上运行的算法是这样的:
The algorithm I am running on the user input is something like this :
def bisect(n, mapper, tester):
"""
Runs a bisection.
- `n` is the number of elements to be bisected
- `mapper` is a callable that will transform an integer from "0" to "n"
into a value that can be tested
- `tester` returns true if the value is within the "right" range
"""
if n < 1:
raise ValueError('Cannot bissect an empty array')
left = 0
right = n - 1
while left + 1 < right:
mid = int((left + right) / 2)
val = mapper(mid)
tester_values = tester(val) # Here is where I am using the ouput from Telegram bot
if tester_values:
right = mid
else:
left = mid
return mapper(right)
我希望我能清楚地解释问题,请随时提出任何澄清.如果您知道什么可以为我指明解决此问题的正确方向,请告诉我.
I hope I was clear explaining the problem, feel free to ask any clarification. If you know something that can point me in the right direction in order to solve this problem, let me know.
我尝试过类似的问题,但没有得到答案.
I have tried a similar question but I am not getting answers.
推荐答案
我找到了答案:
诀窍是使用 next_step_handler, 和
message_handler_function
处理以start
和help
the trick was to use next_step_handler, and
message_handler_function
to handle command starting withstart
andhelp
然后,正如@ALi 在他的回答中所建议的那样,我会将用户输入的答案以及他回答的问题 id 保存在字典中,其中键是问题,id 是答案.
Then as suggested by @ALi in his answer, I will be saving the user input answer as well as the question id he replied to in a dictionary where keys are questions and id are the answer.
一旦用户回答了所有问题,我就可以对他的回答运行算法
Once the user has answered all questions, I can run the algorithms on his answer
代码如下:
user_dict = {}
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
# initialise the the bisector and
bisector = LandsatBisector(LON, LAT)
indice = 0
message = send_current_candidate(bot, message, bisector, indice)
bot.register_next_step_handler(
message, partial(
process_step, indice, bisector))
def process_step(indice, bisector, message):
# this run a while loop and will that send picture and will stop when the count is reached
response = message.text
user = User.create_get_user(message, bisector=bisector)
if indice < bisector.count - 1:
indice += 1
try:
# get or create
user.responses[bisector.date] = response # save the response
message = send_current_candidate(bot, message, bisector, indice)
bot.register_next_step_handler(
message, partial(
process_step, indice, bisector))
except Exception as e:
print(e)
bot.reply_to(message, 'oooops')
else:
culprit = bisect(bisector.count,
lambda x: x,
partial(
tester_function,
responses=list(user.responses.values())))
bisector.index = culprit
bot.reply_to(message, f"Found! First apparition = {bisector.date}")
这篇关于Python Telegram Bot 如何等待用户回答问题并返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!