aiogram telegram bot
This commit is contained in:
@ -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}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user