Как повторить функцию и обработчик, пока пользователь не даст действительный ответ telegram-боту?

#python #telegram #chatbot #telegram-bot #python-telegram-bot

#python #telegram #чат-бот #telegram-бот #python-telegram-bot

Вопрос:

Я только что начал учиться создавать telegram-бота с использованием модуля telegram-bot-api-python. Я создал три функции, одну /start командную функцию для запуска converstaion, и эта функция запрашивает номер телефона пользователя и отправляет его другому вызываемому обработчику или функции, reply_with_number где ответ пользователя будет подтвержден с помощью if else инструкций, и если ответ пользователя действителен, то он будет отправлен другому вызываемому обработчику или функции, ask_link это последний, и он ответит мне ссылкой. Все в порядке, но когда пользователь вводит некоторую строку типа « thisstring » вместо номера телефона, тогда функция reply_with_number должна продолжать работать или продолжать запрашивать действительный номер телефона, пока он не введет действительный. Но мой просто выходит из этого reply_with_number и запускает следующий ask_link обработчик, не дожидаясь ответа. Как можно решить эту проблему? Мой код:

 import time
from telegram import MessageEntity,Bot
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, ConversationHandler
from telegram import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove

updater = Updater(token=token, use_context=True)
dispatcher = updater.dispatcher

def start(update, context):
    username = update.message.from_user.first_name
    context.bot.send_message(chat_id=update.effective_chat.id,
                             text=f"Hello {username}, Welcome to my bot!")
    context.bot.send_message(chat_id=update.effective_chat.id,
                             text='May i know your phone no ?')

def reply_with_number(update, context):
        if update.message.text and len(update.message.text) <= 13:
            try:
                if update.message.text[0:3] == ' 91':
                    phone_number = int(update.message.text[3:])
                elif update.message.text[0:2] == '91':
                    phone_number = int(update.message.text[2:])
                elif update.message.text[0] == '0':
                    phone_number = int(update.message.text[1:])
                else:
                    phone_number = int(update.message.text)
                    context.bot.send_message(chat_id=update.effective_chat.id,
                                             text='Looks good!',
                                             reply_markup=reply_markup)
            except Exception as e:
                update.message.reply_text('Please enter phone number not strings!')

def ask_link(update, context):
    link = update.message.text
    neat_url = strip(link)
    if neat_url != None:
        context.bot.send_message(chat_id=update.effective_chat.id,
                                 text='Link looks good')
    elif neat_url == None:
        context.bot.send_message(chat_id=update.effective_chat.id,
                                 text='Its invalid!')


start_handler = CommandHandler('start', start)
dispatcher.add_handler(start_handler)

reply_handler = MessageHandler(Filters.contact | Filters.text, reply_with_number)
dispatcher.add_handler(reply_handler)

ask_for_link = MessageHandler(Filters.text, ask_link)
dispatcher.add_handler(ask_for_link)

updater.start_polling()
  

Скриншот проблемы:
введите описание изображения здесь

Комментарии:

1. Если вы хотите продолжать работать reply_with_number , пока пользователь не введет действительный ввод, вам, вероятно, следует добавить цикл reply_with_number . Условие цикла должно проверять, ввел ли пользователь допустимый ввод; и продолжать повторять, если ввод был недействительным.

2. Конечно, я попробую это и дам вам знать. Спасибо, что помогли мне.

Ответ №1:

Для этой ситуации вы должны использовать ConversationHandler и просто вернуть правильное сообщение для пользователя, чтобы повторить попытку, и правильный возврат, чтобы бот знал, что пользователь все еще находится на том же шаге обработчика беседы, например:

 from telegram.ext import CommandHandler, MessageHandler, Filters, ConversationHandler


FIRST_STEP, SECOND_STEP = range(2)

conversation_handler = ConversationHandler(
    entry_points=[CommandHandler('start', start)],
    states={
        FIRST_STEP: [MessageHandler(Filters.text amp; ~Filters.command, first_step)],
        SECOND_STEP: [MessageHandler(Filters.text amp; ~Filters.command, second_step)],
    },
    fallbacks=[CommandHandler('cancel', cancel)]
)

def start(bot, update):
    bot.send_message(
        chat_id=update.message.chat_id, 
        text='2   2 = ?', 
        parse_mode='markdown')
    return FIRST_STEP

def cancel(bot, update):
    bot.send_message(
        chat_id=update.message.chat_id, 
        text='2   2 = ?')
    return ConversationHandler.END

def first_step(bot, update):
    if update.message.text != '4':
        bot.send_message(
            chat_id=update.message.chat_id, 
            text='Sorry try again to enter a valid input.')
        bot.send_message(
            chat_id=update.message.chat_id, 
            text='2   2 = ?')
        return FIRST_STEP
    else:
        bot.send_message(
            chat_id=update.message.chat_id, 
            text='The answer is right, you are in the next step')
        return SECOND_STEP

def second_step(bot, update):
    bot.send_message(
        chat_id=update.message.chat_id, 
        text='Correct answer', 
        parse_mode='markdown')
    return ConversationHandler.END
  

Справочные документы:
https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.conversationhandler.html ?выделите = обработчик разговора