Телеграм бот quiz архитектура
Пишу телеграм бот (aiogram, SQLite) для квиза. Бот задает вопрос, юзер отвечает, бот проверяет ответ, пишет юзеру верно/неверно и задает следующий. В конце пишет, сколько правильных ответов. Имею табличку в SQLite с вопросами и ответами. Столкнулся на моменте, как дождаться ответа от юзера и задать следующий вопрос? Выглядит так, что делать кучу стейтов не рационально, и не будет возможности развития. Хочется, чтобы сколько я загружу вопросов в базу, столько он и задаст. Думал в сторону рекурсии, но чет никак не могу придумать хендлер и как это реализовать. Подскажите, пожалуйста :)
Добавляю пример моего кода - он задает 2 и 3 вопрос, проверяет 1 и 2 вопрос. На 10 вопросов таких кусков будет 10, они полностью одинаковые) И ниже 3 функции, которые ему помогают (ходят в базу за данными)
@dp.message_handler(state=Quiz.Q2, chat_type = types.ChatType.PRIVATE)
async def show_question(message: types.Message):
start_num = 1
correct_answer = get_correct_answer(start_num)
await message.answer(correct_answer)
start_num = 2
if message.text == "Правда":
if "true" == correct_answer:
await message.answer("Вы угадали")
elif message.text == "Ложь":
if "false" == correct_answer:
await message.answer("Вы угадали!")
else:
await message.answer("Вы ошиблись")
question_text = send_question(start_num)
question_img = send_question_img(start_num)
await message.answer(question_text)
await dp.bot.send_photo(message.from_user.id, question_img)
await Quiz.Q3.set()
@dp.message_handler(state=Quiz.Q3, chat_type = types.ChatType.PRIVATE)
async def show_question(message: types.Message):
start_num = 2
correct_answer = get_correct_answer(start_num)
await message.answer(correct_answer)
start_num = 3
if message.text == "Правда":
if "true" == correct_answer:
await message.answer("Вы угадали")
elif message.text == "Ложь":
if "false" == correct_answer:
await message.answer("Вы угадали!")
else:
await message.answer("Вы ошиблись")
question_text = send_question(start_num)
question_img = send_question_img(start_num)
await message.answer(question_text)
await dp.bot.send_photo(message.from_user.id, question_img)
await Quiz.Q4.set()
Функции:
def send_question(id):
text = db.get_question_info(id)[0][0]
return text
def send_question_img(id):
img = db.get_question_info(id)[0][1]
return img
def get_correct_answer(id):
answer = db.get_question_answer(id)
return answer
Ответы (1 шт):
Создаёшь словарь с ключами - пользовательскими ID и значениями - индексами их вопросов.
В хэндлере нового сообщения сравниваешь сообщение пользователя и правильный ответ по индексу. Пишешь - верно/неверно. Увеличиваешь индекс вопроса в словаре. Если индекс больше, чем кол-во вопросов - пишешь, что вопросы кончились
users = {} #словарь с индексами вопросов
@dp.message_handler(chat_type = types.ChatType.PRIVATE)
async def message_handler(message: types.Message):
user_id = message.from_user.id
if message.from_user.id not in users: #если пользователя нет в ключах словаря
users[user_id] = 0 #индекс текущего вопроса у пользователя - 0
await show_question(user_id) #показываем первый вопрос
return #для того, чтобы если игрок напишет первым сообщением Правда или Ложь,
#ему не засчитывался ответ - заканчиваем функцию
question_id = users[user_id] #получаем индекс (id) вопроса у пользователя
correct_answer = get_correct_answer(question_id)
if message.text == "Правда":
if "true" == correct_answer:
await message.answer("Вы угадали")
elif message.text == "Ложь":
if "false" == correct_answer:
await message.answer("Вы угадали!")
else:
await message.answer("Вы ошиблись")
users[user_id] += 1
await show_question(user_id) #показываем новый вопрос
async def show_question(user_id): #отдельная функция для покзаа вопроса
question_id = users[user_id]
await dp.bot.send_message(user_id, send_question(question_id)
await dp.bot.send_photo(user_id, send_question_img(question_id)
async def show_right_answer(user_id): #отдельная функция для показа правильного ответа
question_id = users[user_id]
await dp.bot.send_message(user_id, get_correct_answer(question_id))
Что-то вроде того