напиши код на пайтон для телеграм бота викторины с...
Creato il: 22 aprile 2025
Creato il: 22 aprile 2025
напиши код на пайтон для телеграм бота викторины с пополняемой пользователем базой вопросов
Ниже — полностью‑готовый пример Telegram‑бота‑викторины на python‑telegram‑bot v20+.
Он хранит вопросы в файле questions.json
; пользователи могут пополнять базу командой /add
.
Перед запуском
pip install python-telegram-bot~=20.7
- Создайте бота у @BotFather и положите его токен в переменную окружения
TELEGRAM_TOKEN
(или подставьте прямо в код, но это небезопасно).
python#!/usr/bin/env python import json import os import random from pathlib import Path from typing import Dict, List from telegram import Update from telegram.ext import ( ApplicationBuilder, CommandHandler, MessageHandler, ConversationHandler, ContextTypes, filters ) # ---------- постоянное хранилище вопросов ---------- DB_PATH = Path("questions.json") def load_db() -> List[Dict[str, str]]: if DB_PATH.exists(): with DB_PATH.open(encoding="utf-8") as f: return json.load(f) return [] def save_db(db: List[Dict[str, str]]) -> None: with DB_PATH.open("w", encoding="utf-8") as f: json.dump(db, f, ensure_ascii=False, indent=2) QUESTIONS = load_db() # ---------- /start и help ---------- START_TEXT = ( "👋 Привет! Это бот‑викторина.\n\n" "Доступные команды:\n" " /quiz – получить случайный вопрос\n" " /add – добавить новый вопрос\n" " /cancel – отменить ввод\n" " /help – показать эту справку" ) async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text(START_TEXT) # ---------- режим QUIZ ---------- QUIZ_WAITING_ANSWER = 100 # arbitrary state id async def quiz(update: Update, context: ContextTypes.DEFAULT_TYPE): if not QUESTIONS: await update.message.reply_text("Пока нет ни одного вопроса. Добавьте их через /add!") return ConversationHandler.END q = random.choice(QUESTIONS) context.user_data["current_q"] = q await update.message.reply_text(f"❓ {q['question']}\n(жду ваш ответ в следующем сообщении)") return QUIZ_WAITING_ANSWER async def check_answer(update: Update, context: ContextTypes.DEFAULT_TYPE): user_answer = update.message.text.strip().lower() q = context.user_data.get("current_q") if not q: await update.message.reply_text("Не удалось найти вопрос. Попробуйте /quiz ещё раз.") return ConversationHandler.END correct = q["answer"].strip().lower() if user_answer == correct: await update.message.reply_text("✅ Верно!") else: await update.message.reply_text(f"❌ Неправильно.\nПравильный ответ: {q['answer']}") return ConversationHandler.END # ---------- режим ADD ---------- ASK_Q, ASK_A = range(2) async def add_start(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("Введите текст нового вопроса или /cancel для отмены.") return ASK_Q async def add_get_question(update: Update, context: ContextTypes.DEFAULT_TYPE): context.user_data["new_question"] = update.message.text.strip() await update.message.reply_text("Теперь введите правильный ответ:") return ASK_A async def add_get_answer(update: Update, context: ContextTypes.DEFAULT_TYPE): answer = update.message.text.strip() question = context.user_data.pop("new_question") QUESTIONS.append({"question": question, "answer": answer}) save_db(QUESTIONS) await update.message.reply_text("📝 Вопрос сохранён! Спасибо.\nХотите ещё? /add или /quiz") return ConversationHandler.END # ---------- общая отмена ---------- async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("Действие отменено.") return ConversationHandler.END def main(): token = os.getenv("TELEGRAM_TOKEN") if not token: raise RuntimeError("Установите переменную окружения TELEGRAM_TOKEN") app = ApplicationBuilder().token(token).build() # /start и /help app.add_handler(CommandHandler(["start", "help"], start)) # /quiz quiz_conv = ConversationHandler( entry_points=[CommandHandler("quiz", quiz)], states={QUIZ_WAITING_ANSWER: [MessageHandler(filters.TEXT & ~filters.COMMAND, check_answer)]}, fallbacks=[CommandHandler("cancel", cancel)], ) app.add_handler(quiz_conv) # /add add_conv = ConversationHandler( entry_points=[CommandHandler("add", add_start)], states={ ASK_Q: [MessageHandler(filters.TEXT & ~filters.COMMAND, add_get_question)], ASK_A: [MessageHandler(filters.TEXT & ~filters.COMMAND, add_get_answer)], }, fallbacks=[CommandHandler("cancel", cancel)], ) app.add_handler(add_conv) # универсальная /cancel app.add_handler(CommandHandler("cancel", cancel)) print("Bot is running… Ctrl+C to stop.") app.run_polling() if __name__ == "__main__": main()
Хранение данных.
questions.json
рядом со скриптом.[{"question": "...", "answer": "..."}, …]
.Викторина.
/quiz
отправляет случайный вопрос.Добавление вопросов.
/add
запускает диалог из двух шагов: текст вопроса → текст ответа.Многопользовательский режим.
context.user_data
, поэтому разные пользователи могут играть независимо.При желании можно:
Удачных квиз‑баталий!