From f3d86ffddef1ebb119bd7b3664697e3a24c35cd8 Mon Sep 17 00:00:00 2001 From: DIKER0K Date: Fri, 12 Dec 2025 20:31:40 +0500 Subject: [PATCH] WebHook telegram bot test --- app/webhooks/telegram.py | 62 ++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 22 +++++++------- main.py | 39 +++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 11 deletions(-) create mode 100644 app/webhooks/telegram.py diff --git a/app/webhooks/telegram.py b/app/webhooks/telegram.py new file mode 100644 index 0000000..bbe3565 --- /dev/null +++ b/app/webhooks/telegram.py @@ -0,0 +1,62 @@ +import os +from fastapi import APIRouter, Request, HTTPException +from telebot import TeleBot, types + +router = APIRouter() + +BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") +WEBHOOK_SECRET = os.getenv("TELEGRAM_WEBHOOK_SECRET", "") # опционально +bot = TeleBot(BOT_TOKEN, threaded=False) # threaded=False обычно проще в async-сервисах + +# ====== ВАШИ ХЕНДЛЕРЫ (почти без изменений) ====== +import httpx + +API_URL = os.getenv("API_URL") +user_states = {} # ⚠️ см. примечание ниже про хранение + +@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, "📋 Введите код из лаунчера:") + else: + bot.reply_to(message, "🔑 Введите ваш игровой никнейм:") + bot.register_next_step_handler(message, process_username) + +def process_username(message): + user_states[message.chat.id] = {"username": message.text.strip()} + bot.reply_to(message, "📋 Теперь введите код из лаунчера:") + +@bot.message_handler(func=lambda m: m.chat.id in user_states) +def verify_code(message): + username = user_states[message.chat.id]["username"] + code = message.text.strip() + + try: + r = httpx.post( + f"{API_URL}/auth/verify_code", + json={"username": username, "code": code, "telegram_chat_id": message.chat.id}, + ) + if r.status_code == 200: + bot.reply_to(message, "✅ Аккаунт подтвержден!") + else: + bot.reply_to(message, f"❌ Ошибка: {r.json().get('detail')}") + except Exception as e: + bot.reply_to(message, "⚠️ Сервер недоступен. Детальная информация: " + str(e)) + + user_states.pop(message.chat.id, None) + +# ====== 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") + + update_json = await request.json() + update = types.Update.de_json(update_json) + bot.process_new_updates([update]) + return {"ok": True} diff --git a/docker-compose.yml b/docker-compose.yml index 5a13e5b..8511646 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,17 +15,17 @@ services: - mongodb command: ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "3000"] - telegram_bot: - container_name: telegram_bot - build: - context: . - dockerfile: Dockerfile - user: "${UID:-1000}:${GID:-1000}" - volumes: - - ./telegram_bot.py:/app/telegram_bot.py - env_file: - - .env - command: ["python", "telegram_bot.py"] + # telegram_bot: + # container_name: telegram_bot + # build: + # context: . + # dockerfile: Dockerfile + # user: "${UID:-1000}:${GID:-1000}" + # volumes: + # - ./telegram_bot.py:/app/telegram_bot.py + # env_file: + # - .env + # command: ["python", "telegram_bot.py"] mongodb: container_name: mongodb diff --git a/main.py b/main.py index 2d5105e..9fc1b17 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,50 @@ +from contextlib import asynccontextmanager +import os from fastapi import FastAPI from fastapi.staticfiles import StaticFiles +import httpx from app.api import news, users, skins, capes, meta, server, store, pranks, marketplace, bonuses, case from fastapi.middleware.cors import CORSMiddleware from app.core.config import CAPES_DIR, CAPES_STORE_DIR, SKINS_DIR +from app.webhooks import telegram app = FastAPI() + +###################### БОТ ###################### + +BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") +PUBLIC_WEBHOOK_URL = os.getenv("PUBLIC_WEBHOOK_URL") # https://minecraft.api.popa-popa.ru/telegram/webhook +WEBHOOK_SECRET = os.getenv("TELEGRAM_WEBHOOK_SECRET", "") + +@asynccontextmanager +async def lifespan(app: FastAPI): + # ===== STARTUP ===== + if BOT_TOKEN and PUBLIC_WEBHOOK_URL: + payload = {"url": PUBLIC_WEBHOOK_URL} + if WEBHOOK_SECRET: + payload["secret_token"] = WEBHOOK_SECRET + + async with httpx.AsyncClient(timeout=20) as client: + await client.post( + f"https://api.telegram.org/bot{BOT_TOKEN}/setWebhook", + json=payload, + ) + + yield + + # ===== SHUTDOWN ===== + async with httpx.AsyncClient(timeout=20) as client: + await client.post( + f"https://api.telegram.org/bot{BOT_TOKEN}/deleteWebhook" + ) + + +app = FastAPI(lifespan=lifespan) + +################################################## + app.include_router(meta.router) app.include_router(users.router) app.include_router(skins.router) @@ -18,6 +56,7 @@ app.include_router(marketplace.router) app.include_router(bonuses.router) app.include_router(news.router) app.include_router(case.router) +app.include_router(telegram.router) # Монтируем статику app.mount("/skins", StaticFiles(directory=str(SKINS_DIR)), name="skins")