60 lines
2.7 KiB
Python
60 lines
2.7 KiB
Python
from typing import Callable, Awaitable, Any, Dict, Optional
|
||
|
||
from aiogram import BaseMiddleware
|
||
from aiogram.filters.command import CommandObject
|
||
from aiogram.types import TelegramObject, Message
|
||
|
||
from middleware.loggers import logger
|
||
|
||
|
||
class ReferralMiddleware(BaseMiddleware):
|
||
"""
|
||
Middleware для перехвата и обработки реферальных ссылок (?start=...).
|
||
|
||
Основные задачи:
|
||
- Отслеживание перехода по deep-link (например, /start ref123)
|
||
- Централизованное логирование
|
||
- Возможность передачи кода дальше в хендлеры
|
||
- Подготовка к сохранению кода в базу данных
|
||
"""
|
||
|
||
async def __call__(
|
||
self,
|
||
handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
|
||
event: TelegramObject,
|
||
data: Dict[str, Any],
|
||
) -> Any:
|
||
"""
|
||
Перехватывает входящие сообщения и извлекает deep-link аргумент,
|
||
если пользователь зашёл по реферальной ссылке.
|
||
|
||
Args:
|
||
handler: Следующий обработчик в цепочке middleware
|
||
event: Входящее событие (Message, CallbackQuery и др.)
|
||
data: Контекстные данные, доступные хендлеру
|
||
|
||
Returns:
|
||
Результат работы следующего обработчика
|
||
"""
|
||
# Проверяем, что событие — это именно сообщение
|
||
if isinstance(event, Message):
|
||
# Извлекаем объект команды (если был установлен фильтр CommandStart)
|
||
command: Optional[CommandObject] = data.get("command")
|
||
|
||
# Проверяем, что это именно команда /start с аргументом
|
||
if command and command.command.casefold() == "start" and command.args:
|
||
ref_code: str = command.args
|
||
user_id: int = event.from_user.id
|
||
username: Optional[str] = event.from_user.username
|
||
|
||
# 👉 Здесь можно сохранить код в БД
|
||
logger.debug(
|
||
f"[Referral] user={user_id}, username={username}, ref={ref_code}"
|
||
)
|
||
|
||
# Пробрасываем реф-код в data, чтобы использовать в хендлере
|
||
data["ref_code"] = ref_code
|
||
|
||
# Передаём управление дальше
|
||
return await handler(event, data)
|