67 lines
2.3 KiB
Python
67 lines
2.3 KiB
Python
"""Middleware аналитики: события ``message`` и ``command`` приходят с транспорта."""
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
from collections.abc import Awaitable, Callable
|
||
from typing import Any
|
||
|
||
from aiogram import BaseMiddleware
|
||
from aiogram.types import Message, TelegramObject
|
||
|
||
from common.analytics import EventType, record, remember_user
|
||
from common.analytics.messages import describe_command, describe_message
|
||
from common.config import get_settings
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
class AnalyticsMiddleware(BaseMiddleware):
|
||
"""Логирует сообщения и команды основного чата.
|
||
|
||
Текст сообщения не сохраняется — только метаданные (см. ``docs/events.md``).
|
||
Аналитика не должна мешать обработке: любые сбои логируются и глушатся.
|
||
"""
|
||
|
||
async def __call__(
|
||
self,
|
||
handler: Callable[[TelegramObject, dict[str, Any]], Awaitable[Any]],
|
||
event: TelegramObject,
|
||
data: dict[str, Any],
|
||
) -> Any:
|
||
if isinstance(event, Message):
|
||
self._log_message(event)
|
||
return await handler(event, data)
|
||
|
||
@staticmethod
|
||
def _log_message(message: Message) -> None:
|
||
user = message.from_user
|
||
if user is None or user.is_bot:
|
||
return
|
||
if message.chat.id != get_settings().chat_id:
|
||
return
|
||
|
||
try:
|
||
remember_user(user.id, user.username)
|
||
record(
|
||
EventType.MESSAGE,
|
||
user_id=user.id,
|
||
username=user.username,
|
||
chat_id=message.chat.id,
|
||
payload=describe_message(message),
|
||
)
|
||
command = describe_command(message)
|
||
if command is not None:
|
||
record(
|
||
EventType.COMMAND,
|
||
user_id=user.id,
|
||
username=user.username,
|
||
chat_id=message.chat.id,
|
||
payload=command,
|
||
)
|
||
except Exception: # аналитика не должна ломать обработку сообщения
|
||
logger.exception("Не удалось записать события сообщения в аналитику")
|
||
|
||
|
||
__all__ = ["AnalyticsMiddleware"]
|