From 9ff2319990710af8f86aabb7147959aafc990881 Mon Sep 17 00:00:00 2001 From: DIKER0K Date: Fri, 12 Dec 2025 21:05:08 +0500 Subject: [PATCH] aiogram telegram bot --- app/webhooks/telegram.py | 85 ++++++++++++++++++++++++---------------- requirements.txt | 2 +- 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/app/webhooks/telegram.py b/app/webhooks/telegram.py index 991f45c..59159a8 100644 --- a/app/webhooks/telegram.py +++ b/app/webhooks/telegram.py @@ -1,58 +1,77 @@ import os from fastapi import APIRouter, Request, HTTPException +from aiogram import Bot, Dispatcher, F +from aiogram.types import Update, Message +from aiogram.fsm.state import State, StatesGroup +from aiogram.fsm.context import FSMContext +from aiogram.fsm.storage.memory import MemoryStorage + from app.services.auth import AuthService -from telebot import TeleBot, types -import asyncio router = APIRouter() +BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") +WEBHOOK_SECRET = os.getenv("TELEGRAM_WEBHOOK_SECRET", "") + +bot = Bot(token=BOT_TOKEN) +dp = Dispatcher(storage=MemoryStorage()) + auth_service = AuthService() +# ===== FSM ===== -BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") -WEBHOOK_SECRET = os.getenv("TELEGRAM_WEBHOOK_SECRET", "") # опционально -bot = TeleBot(BOT_TOKEN, threaded=False) # threaded=False обычно проще в async-сервисах +class Register(StatesGroup): + username = State() + code = State() -API_URL = os.getenv("API_URL") -user_states = {} # ⚠️ см. примечание ниже про хранение +# ===== Handlers ===== -@bot.message_handler(commands=['start']) -def start(message): - if len(message.text.split()) > 1: - username = message.text.split()[1] - user_states[message.chat.id] = {"username": username} - bot.reply_to(message, "📋 Введите код из лаунчера:") +@dp.message(F.text == "/start") +async def start(message: Message, state: FSMContext): + args = message.text.split() + if len(args) > 1: + await state.update_data(username=args[1]) + await state.set_state(Register.code) + await message.answer("📋 Введите код из лаунчера:") else: - bot.reply_to(message, "🔑 Введите ваш игровой никнейм:") - bot.register_next_step_handler(message, process_username) + await state.set_state(Register.username) + await message.answer("🔑 Введите ваш игровой никнейм:") -def process_username(message): - user_states[message.chat.id] = {"username": message.text.strip()} - bot.reply_to(message, "📋 Теперь введите код из лаунчера:") +@dp.message(Register.username) +async def process_username(message: Message, state: FSMContext): + await state.update_data(username=message.text.strip()) + await state.set_state(Register.code) + await message.answer("📋 Теперь введите код из лаунчера:") -@bot.message_handler(func=lambda m: m.chat.id in user_states) -def verify_code(message): - username = user_states[message.chat.id]["username"] +@dp.message(Register.code) +async def process_code(message: Message, state: FSMContext): + data = await state.get_data() + username = data["username"] code = message.text.strip() try: - asyncio.run(auth_service.verify_code(username, code, message.chat.id)) - bot.reply_to(message, "✅ Аккаунт подтвержден!") + await auth_service.verify_code( + username=username, + code=code, + telegram_chat_id=message.chat.id, + ) + await message.answer("✅ Аккаунт подтвержден!") + await state.clear() except Exception as e: - bot.reply_to(message, "❌ Ошибка: " + str(e)) + await message.answer(f"❌ Ошибка: {e}") + await state.clear() - user_states.pop(message.chat.id, None) +# ===== Webhook endpoint ===== -# ====== WEBHOOK ENDPOINT ====== @router.post("/telegram/webhook") async def telegram_webhook(request: Request): - # простой секрет, чтобы никто кроме Telegram не слал апдейты if WEBHOOK_SECRET: - header = request.headers.get("X-Telegram-Bot-Api-Secret-Token") - if header != WEBHOOK_SECRET: - raise HTTPException(status_code=403, detail="forbidden") + token = request.headers.get("X-Telegram-Bot-Api-Secret-Token") + if token != WEBHOOK_SECRET: + raise HTTPException(status_code=403, detail="Forbidden") - update_json = await request.json() - update = types.Update.de_json(update_json) - bot.process_new_updates([update]) + data = await request.json() + update = Update.model_validate(data) + + await dp.feed_update(bot, update) return {"ok": True} diff --git a/requirements.txt b/requirements.txt index 3d96f53..131df5a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,4 @@ pydantic>=2.0.0 cryptography>=43.0.0 pytelegrambotapi>=2.0.0 httpx>=0.27.2 - +aiogram>=3.20.0