@NeZabuduTebya

Телеграмм-бот не ждет ответа, а выводит все сразу что делать?

бот не ждет пока пользователь ответит на вопрос, а сразу выводит все вопросы, register_next_step_handler вроде работает, а вроде нет
@bot.message_handler(content_types=['text'])
def tt(message):
    if message.text == 'Начать тест':
        user_score = 0
        user_num = 1
        for i in range(5):
            markup = types.ReplyKeyboardMarkup(resize_keyboard=True,one_time_keyboard=True)
            quest = get_quest(user_num)
            print(quest)
            answers = get_answers(user_num).split('|')
            answers.sort()
            for j in answers:
                btn1 = types.KeyboardButton(j)
                markup.add(btn1)
            mess = "<b>{}. {}</b>\n\nA.{}\n\nB.{}\n\nC.{}\n\nD.{}".format(i+1,quest,answers[0],answers[1],answers[2],answers[3])
            bot.send_message(message.chat.id,mess,reply_markup=markup,parse_mode='html')
            bot.register_next_step_handler(message,check_answer,user_num,user_score)
            user_num += 1
def check_answer(message,num,score):
    right = get_right(num)
    if message.text == right:
        score += 1
    print(score)
    bot.send_message(message.chat.id,'Идем дальше')

654a810c787d2271726917.png
  • Вопрос задан
  • 118 просмотров
Пригласить эксперта
Ответы на вопрос 2
kendyland
@kendyland
дело в том что ты вызываешь bot.register_next_step_handler в цикле for и каждый раз когда цикл создает новую клавиатуру и вызывает bot.send_message он также регестрирует нект степ хендлер. Это приводит к тому, что любое сообщение юзера бот запускает все циклы

короче, мне лень было это писать самому, поэтому я попросилл чат жпт реворкнуть архитектуру и он накидал вот это

@bot.message_handler(content_types=['text'])
def start_test(message):
    if message.text == 'Начать тест':
        user_data = {
            'user_score': 0,
            'user_num': 1
        }
        ask_question(message, user_data)

def ask_question(message, user_data):
    num = user_data['user_num']
    if num > 5:
        # Завершаем тест
        bot.send_message(message.chat.id, f'Тест завершен. Ваш счет: {user_data["user_score"]}')
        return

    quest = get_quest(num)
    answers = get_answers(num).split('|')
    answers.sort()

    markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
    for j in answers:
        btn = types.KeyboardButton(j)
        markup.add(btn)

    mess = f"<b>{num}. {quest}</b>\n\nA.{answers[0]}\n\nB.{answers[1]}\n\nC.{answers[2]}\n\nD.{answers[3]}"
    bot.send_message(message.chat.id, mess, reply_markup=markup, parse_mode='html')

    user_data['user_num'] += 1
    bot.register_next_step_handler(message, check_answer, user_data)

def check_answer(message, user_data):
    right = get_right(user_data['user_num'])
    if message.text == right:
        user_data['user_score'] += 1
    bot.send_message(message.chat.id, 'Идем дальше')
    ask_question(message, user_data)
Ответ написан
Комментировать
@TKDBOT
Учу python. Готов к конструктивной критике.
У тебя как верно заметили все сообщения отправляются в цикле разом.
Можно сделать каждый вопрос отдельным def и перебрасывать юзера о шагам.

Пример использования состояний
import telebot # telebot

from telebot import custom_filters
from telebot.handler_backends import State, StatesGroup #States

# States storage
from telebot.storage import StateMemoryStorage



state_storage = StateMemoryStorage() # you can init here another storage

bot = telebot.TeleBot("TOKEN",
state_storage=state_storage)


# States group.
class MyStates(StatesGroup):
    # Just name variables differently
    name = State() # creating instances of State class is enough from now
    surname = State()
    age = State()




@bot.message_handler(commands=['start'])
def start_ex(message):
    """
    Start command. Here we are starting state
    """
    bot.set_state(message.from_user.id, MyStates.name, message.chat.id)
    bot.send_message(message.chat.id, 'Hi, write me a name')
 

# Any state
@bot.message_handler(state="*", commands=['cancel'])
def any_state(message):
    """
    Cancel state
    """
    bot.send_message(message.chat.id, "Your state was cancelled.")
    bot.delete_state(message.from_user.id, message.chat.id)

@bot.message_handler(state=MyStates.name)
def name_get(message):
    """
    State 1. Will process when user's state is MyStates.name.
    """
    bot.send_message(message.chat.id, 'Now write me a surname')
    bot.set_state(message.from_user.id, MyStates.surname, message.chat.id)
    with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
        data['name'] = message.text
 
 
@bot.message_handler(state=MyStates.surname)
def ask_age(message):
    """
    State 2. Will process when user's state is MyStates.surname.
    """
    bot.send_message(message.chat.id, "What is your age?")
    bot.set_state(message.from_user.id, MyStates.age, message.chat.id)
    with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
        data['surname'] = message.text
 
# result
@bot.message_handler(state=MyStates.age, is_digit=True)
def ready_for_answer(message):
    """
    State 3. Will process when user's state is MyStates.age.
    """
    with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
        msg = ("Ready, take a look:\n<b>"
               f"Name: {data['name']}\n"
               f"Surname: {data['surname']}\n"
               f"Age: {message.text}</b>")
        bot.send_message(message.chat.id, msg, parse_mode="html")
    bot.delete_state(message.from_user.id, message.chat.id)

#incorrect number
@bot.message_handler(state=MyStates.age, is_digit=False)
def age_incorrect(message):
    """
    Wrong response for MyStates.age
    """
    bot.send_message(message.chat.id, 'Looks like you are submitting a string in the field age. Please enter a number')

# register filters

bot.add_custom_filter(custom_filters.StateFilter(bot))
bot.add_custom_filter(custom_filters.IsDigitFilter())

bot.infinity_polling(skip_pending=True)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы