Python Telegram Bot 如何等待用户回答问题并返回 [英] Python Telegram Bot how to wait for user answer to a question And Return It

查看:34
本文介绍了Python Telegram Bot 如何等待用户回答问题并返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上下文:

我正在使用 PyTelegramBotAPiPython 电报机器人

当用户开始对话时,我正在运行一个代码.

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 处理以 starthelp

  • the trick was to use next_step_handler, and message_handler_function to handle command starting with start and help

然后,正如@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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆