Обработка отсутствия ответа на викторину в aiogram
Пишу бота для создания и проведения викторин с помощью библиотеки aiogram. Суть проблемы в следующем: бот присылает викторину пользователю:
await bot.send_poll(call.from_user.id,
question='2+2',
options=[3, 4],
is_anonymous=False,
type=PollType.QUIZ,
correct_option_id=1,
explanation=None,
open_period=10
)
Затем ждет ответа
@dp.poll_answer_handler()
async def get_user_answer_and_send_new_poll(poll_answer: types.PollAnswer):
# Здесь проверяет правильный ли ответ, заносит в табличку, а затем здесь же отправляет следующий вопрос
await bot.send_poll(poll_answer.user.id,
question='3+3',
options=[5, 6],
is_anonymous=False,
type=PollType.QUIZ,
correct_option_id=1,
explanation=None,
open_period=10
)
pass
При ответах на вопросы всё работает замечательно. Но дело в том, что если этот open_period=10 закончится, то бот ничего не отправит. Была мысль попробовать через @dp.poll_handler(lambda active_quiz: active_quiz.is_closed is True), но не совсем понял, как это работает. И здесь тоже возникает вопрос, как мне отправить новый вопрос человеку, если я не знаю, как взять его user_id? Через callback, message, poll_answer это можно легко сделать, но если человек ничего не ответил..
Хотелось бы отследить отсутствие ответа на вопрос и сразу же отправить новый. Прошу помощи в этом вопросе.
Ответы (1 шт):
Так как сохраняю промежуточные ответы в словаре, где ключ - это id пользователя, а значение - это класс, в который записываются количество правильных ответов, добавил туда текущий на данный момент вопрос, который переключается, когда игрок отвечает на вопрос или время вопроса истекло. Вот сам словарь и пример класса:
users = {}
class User():
def __init__(self, correct_answers=0, current_question=1):
self.correct_answers = correct_answers
self.current_question = current_question
Когда отправляю пользователю первый вопрос, сохраняю его в users:
users[call.from_user.id] = User()
Теперь в функцию, отправляющую вопрос, добавляю следующий код:
time_to_answer = 10
await bot.send_poll(call.from_user.id,
question='2+2',
options=[3, 4],
is_anonymous=False,
type=PollType.QUIZ,
correct_option_id=1,
explanation=None,
open_period=time_to_answer
)
await asyncio.sleep(time_to_answer)
user: User = users.get(call.from_user.id)
current_question = user.current_question
if current_question == 1:
user.current_question += 1
# А здесь отправляем новый вопрос
await send_question(user, call.from_user.id, user.current_question)
Сама функция для отправки вопроса:
async def send_question(user: User, user_id: int, current_question: int):
# Здесь отправляем новый вопрос
await asyncio.sleep(10)
user: User = users.get(call.from_user.id)
user_current_question = user.current_question
if user_current_question == current_question:
user.current_question += 1
# Cнова отправляем новый вопрос
await send_question(user, call.from_user.id, user.current_question)
И вот хэндлер, принимающий ответы пользователей:
@dp.poll_answer_handler()
async def get_user_answer_and_send_new_poll(poll_answer: types.PollAnswer):
user: UserPlayInQuiz = users_base.get(poll_answer.user.id)
# Здесь проверяет правильный ли ответ, заносит в табличку, а затем здесь же отправляет следующий вопрос
user.current_question += 1
await send_question(user, poll_answer.user.id, user.current_question)