Skip to main content

Бот с опросами

Простой бот, который шлёт опросы, обрабатывает ответы и считает счёт.

Минимальный пример (Python + aiogram)

import asyncio, os
from aiogram import Bot, Dispatcher
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer
from aiogram.types import Message, PollAnswer
from aiogram.filters import Command

session = AiohttpSession(api=TelegramAPIServer.from_base('https://api.telefon.chat'))
bot = Bot(token=os.environ['BOT_TOKEN'], session=session)
dp = Dispatcher()

# poll_id → правильный вариант
correct_answers = {}
# user_id → счёт
scores = {}

QUESTIONS = [
{'q': 'Столица Франции?', 'opts': ['Лондон', 'Париж', 'Берлин'], 'correct': 1},
{'q': '2 + 2 = ?', 'opts': ['3', '4', '5'], 'correct': 1},
{'q': 'Цвет неба?', 'opts': ['Зелёный', 'Синий', 'Красный'], 'correct': 1},
]

@dp.message(Command('quiz'))
async def start_quiz(m: Message):
for q in QUESTIONS:
sent = await bot.send_poll(
chat_id=m.chat.id,
question=q['q'],
options=q['opts'],
type='quiz',
correct_option_id=q['correct'],
is_anonymous=False,
open_period=20
)
correct_answers[sent.poll.id] = q['correct']
await asyncio.sleep(22)

# Показать счёт
if scores:
leaderboard = sorted(scores.items(), key=lambda x: -x[1])[:10]
text = '🏆 Топ:\n' + '\n'.join(f'{i+1}. user {uid}: {s}' for i, (uid, s) in enumerate(leaderboard))
await m.answer(text)

@dp.poll_answer()
async def on_answer(answer: PollAnswer):
pid = answer.poll_id
if pid in correct_answers:
if correct_answers[pid] in answer.option_ids:
scores[answer.user.id] = scores.get(answer.user.id, 0) + 1

if __name__ == '__main__':
asyncio.run(dp.start_polling(bot))

Что покрывает

  • sendPoll с type='quiz'
  • open_period — авто-закрытие
  • poll_answer event — отслеживание голосов
  • Подсчёт счёта в памяти бота

Расширение

Для постоянного хранения счёта (между рестартами) — записывайте в БД (SQLite/Postgres).

См. также Викторины, События опросов.