Files
Telegram-bot-old/handlers/start.py
2025-12-02 14:28:03 +03:00

194 lines
7.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from aiogram import Router, types
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery
import logging
from instences.config import BASE_URL_FASTAPI
import aiohttp
from keyboard.keyboards import main_keyboard
from aiogram.enums.parse_mode import ParseMode
from .referrals import _build_referral_text
router = Router()
logger = logging.getLogger(__name__)
async def call_api(method, endpoint, data=None):
"""
Выполняет HTTP-запрос к FastAPI.
:param method: HTTP метод (GET, POST, и т.д.)
:param endpoint: конечная точка API
:param data: тело запроса (если необходимо)
:return: JSON-ответ или "ERROR" при неуспехе
"""
url = f"{BASE_URL_FASTAPI}{endpoint}"
logger.info(f"Инициализация запроса: {method} {url} с данными {data}")
try:
async with aiohttp.ClientSession() as session:
async with session.request(method, url, json=data) as response:
logger.info(
f"Получен ответ от {url}: статус {response.status}"
)
if response.status in {200, 201}:
result = await response.json()
logger.debug(f"Ответ JSON: {result}")
return result
if response.status == 404:
logger.debug(f"Код {response.status}, возвращаю ничего")
return None
logger.error(
f"Ошибка в запросе: статус {response.status}, причина {response.reason}"
)
return "ERROR"
except Exception as e:
logger.exception(f"Исключение при выполнении запроса к {url}: {e}")
return "ERROR"
def _welcome_text(username: str | None) -> str:
"""
Текст приветствия в /start и в главном меню.
Имя пока не используем — оставляем сигнатуру на будущее.
"""
return "🥚 Lark Security\n\nВыберите действие из меню ниже."
def _parse_referrer_id(message: Message) -> int | None:
"""
Достаём ref_<telegram_id> из /start.
Примеры:
/start
/start ref_123456789
"""
text = message.text or ""
parts = text.split(maxsplit=1)
if len(parts) < 2:
return None
arg = parts[1].strip()
if not arg.startswith("ref_"):
return None
raw_id = arg[4:]
if not raw_id.isdigit():
return None
try:
return int(raw_id)
except ValueError:
return None
@router.message(Command("start"))
async def start_command(message: Message):
"""
Обработчик команды /start.
Добавлена обработка реферального payload'а ref_<telegram_id>.
"""
logger.info(
f"Получена команда /start от пользователя: "
f"{message.from_user.id} ({message.from_user.username}) | text='{message.text}'"
)
user_id = message.from_user.id
referrer_id = _parse_referrer_id(message)
try:
# 1. Проверяем/создаём пользователя в базе
user_data = await call_api("GET", f"/user/{user_id}")
if not user_data:
logger.debug(
"Пользователь не найден в базе, создаем новую запись."
)
await call_api(
"POST",
"/user/create",
{"telegram_id": user_id},
)
# 2. Если есть реферер и он не сам пользователь — отправляем инфу в бекенд
if referrer_id and referrer_id != user_id:
payload = {
"referrer_id": referrer_id,
"telegram_id": user_id,
}
logger.info(
f"Отправка данных о реферале в бекенд: {payload}"
)
result = await call_api(
"POST",
"/user/referrals/track",
payload,
)
if result == "ERROR":
logger.error(
f"Не удалось зафиксировать реферала в бекенде: {payload}"
)
elif referrer_id == user_id:
logger.info(
"Обнаружена попытка самореферала, запрос в бекенд не отправляем."
)
# 3. Приветственное сообщение и главное меню
logger.debug("Отправка приветственного сообщения пользователю.")
await message.answer(
_welcome_text(message.from_user.username),
reply_markup=main_keyboard(),
)
logger.info("Приветственное сообщение отправлено.")
except Exception as e:
logger.exception(
f"Ошибка при обработке команды /start для пользователя "
f"{user_id}: {e}"
)
await message.answer("Произошла ошибка. Попробуйте позже.")
@router.message(Command("referrals"))
async def referrals_menu_command(message: Message):
"""
Команда /referrals из бокового меню Telegram.
Показывает текст реферальной программы.
"""
logger.info(
f"Получена команда /referrals от пользователя: "
f"{message.from_user.id} ({message.from_user.username})"
)
try:
text = await _build_referral_text(message.bot, message.from_user.id)
await message.answer(text, parse_mode=ParseMode.HTML)
logger.info("Реферальная программа отправлена пользователю.")
except Exception as e:
logger.exception(
f"Ошибка при обработке команды /referrals для пользователя "
f"{message.from_user.id}: {e}"
)
await message.answer("Произошла ошибка. Попробуйте позже.")
@router.callback_query(lambda callback: callback.data == "base")
async def start_callback_handler(callback: CallbackQuery):
"""
Обработчик callback_query с data="base".
Возвращает пользователя в главное меню.
"""
try:
user_data = await call_api("GET", f"/user/{callback.from_user.id}")
if not user_data:
await call_api(
"POST",
"/user/create",
{"telegram_id": callback.from_user.id},
)
await callback.message.edit_text(
_welcome_text(callback.from_user.username),
reply_markup=main_keyboard(),
)
except Exception as e:
logger.exception(f"Ошибка при обработке callback с data='base': {e}")
await callback.message.answer("Произошла ошибка. Попробуйте позже.")
finally:
await callback.answer()