aiogram telegram bot

This commit is contained in:
2025-12-12 21:05:08 +05:00
parent 3aac426364
commit 9ff2319990
2 changed files with 53 additions and 34 deletions

View File

@ -1,58 +1,77 @@
import os import os
from fastapi import APIRouter, Request, HTTPException 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 app.services.auth import AuthService
from telebot import TeleBot, types
import asyncio
router = APIRouter() 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() auth_service = AuthService()
# ===== FSM =====
BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") class Register(StatesGroup):
WEBHOOK_SECRET = os.getenv("TELEGRAM_WEBHOOK_SECRET", "") # опционально username = State()
bot = TeleBot(BOT_TOKEN, threaded=False) # threaded=False обычно проще в async-сервисах code = State()
API_URL = os.getenv("API_URL") # ===== Handlers =====
user_states = {} # ⚠️ см. примечание ниже про хранение
@bot.message_handler(commands=['start']) @dp.message(F.text == "/start")
def start(message): async def start(message: Message, state: FSMContext):
if len(message.text.split()) > 1: args = message.text.split()
username = message.text.split()[1] if len(args) > 1:
user_states[message.chat.id] = {"username": username} await state.update_data(username=args[1])
bot.reply_to(message, "📋 Введите код из лаунчера:") await state.set_state(Register.code)
await message.answer("📋 Введите код из лаунчера:")
else: else:
bot.reply_to(message, "🔑 Введите ваш игровой никнейм:") await state.set_state(Register.username)
bot.register_next_step_handler(message, process_username) await message.answer("🔑 Введите ваш игровой никнейм:")
def process_username(message): @dp.message(Register.username)
user_states[message.chat.id] = {"username": message.text.strip()} async def process_username(message: Message, state: FSMContext):
bot.reply_to(message, "📋 Теперь введите код из лаунчера:") 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) @dp.message(Register.code)
def verify_code(message): async def process_code(message: Message, state: FSMContext):
username = user_states[message.chat.id]["username"] data = await state.get_data()
username = data["username"]
code = message.text.strip() code = message.text.strip()
try: try:
asyncio.run(auth_service.verify_code(username, code, message.chat.id)) await auth_service.verify_code(
bot.reply_to(message, "✅ Аккаунт подтвержден!") username=username,
code=code,
telegram_chat_id=message.chat.id,
)
await message.answer("✅ Аккаунт подтвержден!")
await state.clear()
except Exception as e: 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") @router.post("/telegram/webhook")
async def telegram_webhook(request: Request): async def telegram_webhook(request: Request):
# простой секрет, чтобы никто кроме Telegram не слал апдейты
if WEBHOOK_SECRET: if WEBHOOK_SECRET:
header = request.headers.get("X-Telegram-Bot-Api-Secret-Token") token = request.headers.get("X-Telegram-Bot-Api-Secret-Token")
if header != WEBHOOK_SECRET: if token != WEBHOOK_SECRET:
raise HTTPException(status_code=403, detail="forbidden") raise HTTPException(status_code=403, detail="Forbidden")
update_json = await request.json() data = await request.json()
update = types.Update.de_json(update_json) update = Update.model_validate(data)
bot.process_new_updates([update])
await dp.feed_update(bot, update)
return {"ok": True} return {"ok": True}

View File

@ -11,4 +11,4 @@ pydantic>=2.0.0
cryptography>=43.0.0 cryptography>=43.0.0
pytelegrambotapi>=2.0.0 pytelegrambotapi>=2.0.0
httpx>=0.27.2 httpx>=0.27.2
aiogram>=3.20.0