我正在使用 PyTelegramBotAPi 或 Python 电报机器人
当用户开始对话时,我正在运行一个代码.
当用户开始对话时,我需要向他发送第一张图片和一个问题他是否看到图片中的东西,该函数需要等待用户输入并返回是否他看到了.
之后,我需要不断循环发送图片并等待答案并对其运行二分算法.
到目前为止我尝试过的:
我尝试使用等待响应的回复标记或带有处理程序的内联键盘,但我被卡住了,因为我的代码正在运行而没有等待用户输入.
代码:
@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)
我在用户输入上运行的算法是这样的:
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)
我希望我能清楚地解释问题,请随时提出任何澄清.如果您知道什么可以为我指明解决此问题的正确方向,请告诉我.
我尝试过类似的问题,但没有得到答案.
我找到了答案:
- 诀窍是使用 next_step_handler, 和
message_handler_function
处理以start
和help
然后,正如@ALi 在他的回答中所建议的那样,我会将用户输入的答案以及他回答的问题 id 保存在字典中,其中键是问题,id 是答案.
一旦用户回答了所有问题,我就可以对他的回答运行算法
代码如下:
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}")