DispelEvilBot/bot/services/alerts.py

93 lines
3.7 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.

"""Уведомления в чат логов (``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_kick(
bot: Bot,
*,
actor_username: str | None,
actor_id: int,
username: str | None,
user_id: int,
chat_title: str,
) -> bool:
"""Уведомление об исключении участника: кто и кого выгнал."""
context = {
"actor": user_tag(actor_username, actor_id),
"username": user_tag(username, user_id),
"chat_title": chat_title,
}
return await notify_alert(bot, render(alerts_text.MSG_KICK, 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))