Уведомления о спаме
This commit is contained in:
118
bot/handlers/commands/users/notifications.py
Normal file
118
bot/handlers/commands/users/notifications.py
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
"""
|
||||||
|
Обработчики callback-кнопок уведомлений о спаме
|
||||||
|
"""
|
||||||
|
from aiogram import Router, F
|
||||||
|
from aiogram.types import CallbackQuery
|
||||||
|
from aiogram.exceptions import TelegramBadRequest
|
||||||
|
|
||||||
|
from bot.filters.admin import IsAdmin
|
||||||
|
from database import get_manager
|
||||||
|
from middleware.loggers import logger
|
||||||
|
|
||||||
|
__all__ = ("router",)
|
||||||
|
|
||||||
|
router: Router = Router(name="spam_notifications_router")
|
||||||
|
|
||||||
|
|
||||||
|
# ================= ЗАКРЫТИЕ УВЕДОМЛЕНИЯ =================
|
||||||
|
|
||||||
|
@router.callback_query(F.data == "spam_close", IsAdmin())
|
||||||
|
async def spam_close_callback(callback: CallbackQuery) -> None:
|
||||||
|
"""
|
||||||
|
Закрывает (удаляет) уведомление о спаме.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
await callback.message.delete()
|
||||||
|
await callback.answer("✅ Уведомление закрыто")
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
f"Уведомление о спаме закрыто админом {callback.from_user.id}",
|
||||||
|
log_type="SPAM_NOTIFICATION"
|
||||||
|
)
|
||||||
|
|
||||||
|
except TelegramBadRequest as e:
|
||||||
|
logger.error(f"Ошибка удаления уведомления: {e}", log_type="ERROR")
|
||||||
|
await callback.answer("❌ Не удалось удалить уведомление", show_alert=True)
|
||||||
|
|
||||||
|
|
||||||
|
# ================= БАН ПОЛЬЗОВАТЕЛЯ =================
|
||||||
|
|
||||||
|
@router.callback_query(F.data.startswith("spam_ban:"), IsAdmin())
|
||||||
|
async def spam_ban_callback(callback: CallbackQuery) -> None:
|
||||||
|
"""
|
||||||
|
Банит пользователя прямо из уведомления.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Парсим данные: spam_ban:user_id:chat_id
|
||||||
|
parts = callback.data.split(":")
|
||||||
|
user_id = int(parts[1])
|
||||||
|
chat_id = int(parts[2])
|
||||||
|
|
||||||
|
# Баним пользователя
|
||||||
|
try:
|
||||||
|
await callback.bot.ban_chat_member(
|
||||||
|
chat_id=chat_id,
|
||||||
|
user_id=user_id
|
||||||
|
)
|
||||||
|
|
||||||
|
# Обновляем сообщение
|
||||||
|
updated_text = callback.message.text + f"\n\n🔨 <b>Пользователь забанен</b> (@{callback.from_user.username or callback.from_user.id})"
|
||||||
|
|
||||||
|
# Убираем кнопки
|
||||||
|
await callback.message.edit_text(
|
||||||
|
text=updated_text,
|
||||||
|
parse_mode="HTML"
|
||||||
|
)
|
||||||
|
|
||||||
|
await callback.answer("✅ Пользователь забанен", show_alert=True)
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"Пользователь {user_id} забанен админом {callback.from_user.id} через уведомление о спаме",
|
||||||
|
log_type="SPAM_BAN"
|
||||||
|
)
|
||||||
|
|
||||||
|
except TelegramBadRequest as e:
|
||||||
|
await callback.answer(f"❌ Ошибка бана: {str(e)}", show_alert=True)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Ошибка обработки бана из уведомления: {e}", log_type="ERROR")
|
||||||
|
await callback.answer("❌ Ошибка выполнения", show_alert=True)
|
||||||
|
|
||||||
|
|
||||||
|
# ================= СТАТИСТИКА ПОЛЬЗОВАТЕЛЯ =================
|
||||||
|
|
||||||
|
@router.callback_query(F.data.startswith("spam_stats:"), IsAdmin())
|
||||||
|
async def spam_stats_callback(callback: CallbackQuery) -> None:
|
||||||
|
"""
|
||||||
|
Показывает статистику пользователя.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Парсим данные: spam_stats:user_id
|
||||||
|
parts = callback.data.split(":")
|
||||||
|
user_id = int(parts[1])
|
||||||
|
|
||||||
|
manager = get_manager()
|
||||||
|
|
||||||
|
# Получаем статистику
|
||||||
|
spam_count = await manager.get_user_spam_count(user_id)
|
||||||
|
recent_spam = await manager.get_spam_stats(limit=5, user_id=user_id)
|
||||||
|
|
||||||
|
# Формируем текст
|
||||||
|
text = f"📊 <b>Статистика пользователя</b>\n\n"
|
||||||
|
text += f"🆔 ID: <code>{user_id}</code>\n"
|
||||||
|
text += f"🗑 Удалено сообщений: <code>{spam_count}</code>\n\n"
|
||||||
|
|
||||||
|
if recent_spam:
|
||||||
|
text += f"📝 <b>Последние нарушения:</b>\n"
|
||||||
|
for idx, stat in enumerate(recent_spam, 1):
|
||||||
|
matched_word = stat.matched_word or "неизвестно"
|
||||||
|
match_type = stat.match_type or "unknown"
|
||||||
|
text += f"{idx}. <code>{matched_word}</code> ({match_type})\n"
|
||||||
|
else:
|
||||||
|
text += "✅ <i>Нет нарушений</i>"
|
||||||
|
|
||||||
|
await callback.answer(text, show_alert=True)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Ошибка получения статистики из уведомления: {e}", log_type="ERROR")
|
||||||
|
await callback.answer("❌ Ошибка получения статистики", show_alert=True)
|
||||||
Reference in New Issue
Block a user