"""Уведомления в чат логов (``ALERT_CHAT_ID``). Единая точка отправки служебных сообщений бота: вход/выход участников, успешные очищения, пинг «бот живой». Уведомления **необязательные**: если чат не задан (``ALERT_CHAT_ID=0``) или отправка не удалась — это только запись в лог, обработка не прерывается. """ from __future__ import annotations import logging from typing import TYPE_CHECKING from common.config import get_settings from common.texts import alerts as alerts_text from common.texts.render import render if TYPE_CHECKING: from aiogram import Bot from aiogram.types import Message from common.models import PurificationResult logger = logging.getLogger(__name__) def user_tag(username: str | None, user_id: int) -> str: """Представление пользователя для служебного сообщения (``@username`` или id).""" return f"@{username}" if username else str(user_id) async def notify_alert(bot: Bot, text: str, *, forward: Message | None = None) -> bool: """Отправить текст в чат логов (при необходимости — с пересылкой сообщения). Возвращает ``False``, если чат логов не задан или отправка не удалась. """ settings = get_settings() if not settings.alert_chat_id: return False try: await bot.send_message(chat_id=settings.alert_chat_id, text=text) if forward is not None: await bot.forward_message( chat_id=settings.alert_chat_id, from_chat_id=forward.chat.id, message_id=forward.message_id, ) except Exception: # уведомление не должно ломать обработку logger.exception("Не удалось отправить уведомление в чат логов") return False return True async def notify_join(bot: Bot, *, username: str | None, user_id: int, chat_title: str) -> bool: """Уведомление о входе участника в чат.""" context = {"username": user_tag(username, user_id), "chat_title": chat_title} return await notify_alert(bot, render(alerts_text.MSG_JOIN, context)) async def notify_leave(bot: Bot, *, username: str | None, user_id: int, chat_title: str) -> bool: """Уведомление о выходе участника из чата.""" context = {"username": user_tag(username, user_id), "chat_title": chat_title} return await notify_alert(bot, render(alerts_text.MSG_LEAVE, context)) async def notify_purification(bot: Bot, *, username: str | None, user_id: int, result: PurificationResult) -> bool: """Уведомление об успешном очищении.""" context = { "username": user_tag(username, user_id), "exp_add": result.exp_add, "money_add": result.money_add, } return await notify_alert(bot, render(alerts_text.MSG_PURIFICATION, context))