75 lines
3.2 KiB
Python
75 lines
3.2 KiB
Python
"""Уведомления в чат логов (``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))
|