""" Хэндлеры для управления сообщениями администратором """ import logging from aiogram import Router, F, Bot from aiogram.types import Message, CallbackQuery from aiogram.filters import Command from ..core.config import ADMIN_IDS from ..core.database import async_session_maker from ..core.chat_services import ChatMessageService logger = logging.getLogger(__name__) message_admin_router = Router(name="message_admin") def is_admin(user_id: int) -> bool: """Проверка, является ли пользователь администратором""" return user_id in ADMIN_IDS @message_admin_router.message(Command("delete")) async def delete_replied_message(message: Message): """ Удаление сообщения по команде /delete Работает только если команда является ответом на сообщение бота """ if not is_admin(message.from_user.id): await message.answer("❌ Недостаточно прав") return if not message.reply_to_message: await message.answer("⚠️ Ответьте на сообщение бота командой /delete чтобы удалить его") return if message.reply_to_message.from_user.id != message.bot.id: await message.answer("⚠️ Можно удалять только сообщения бота") return try: # Удаляем сообщение бота await message.reply_to_message.delete() # Удаляем команду await message.delete() logger.info(f"Администратор {message.from_user.id} удалил сообщение {message.reply_to_message.message_id}") except Exception as e: logger.error(f"Ошибка при удалении сообщения: {e}") await message.answer(f"❌ Не удалось удалить сообщение: {str(e)}") @message_admin_router.callback_query(F.data == "delete_message") async def delete_message_callback(callback: CallbackQuery): """ Удаление сообщения по нажатию кнопки """ if not is_admin(callback.from_user.id): await callback.answer("❌ Недостаточно прав", show_alert=True) return try: await callback.message.delete() await callback.answer("✅ Сообщение удалено") logger.info(f"Администратор {callback.from_user.id} удалил сообщение через кнопку") except Exception as e: logger.error(f"Ошибка при удалении сообщения через кнопку: {e}") await callback.answer(f"❌ Ошибка: {str(e)}", show_alert=True) # Функция-фильтр для проверки триггерных слов def is_delete_trigger(message: Message) -> bool: """Проверяет, является ли сообщение триггером для удаления""" if not message.text: return False text_lower = message.text.lower().strip() triggers = ["удалить", "delete", "del", "🗑️", "🗑", "❌"] return any(trigger in text_lower for trigger in triggers) @message_admin_router.message(F.reply_to_message, is_delete_trigger) async def quick_delete_replied_message(message: Message): """ Быстрое удаление сообщения по reply с триггерными словами или emoji Работает для админов при ответе на любое сообщение Триггеры: - "удалить", "delete", "del" - 🗑️ (мусорная корзина) - ❌ (крестик) Удаляет сообщение у всех получателей broadcast рассылки """ if not is_admin(message.from_user.id): return # Не админ - пропускаем try: replied_msg = message.reply_to_message deleted_count = 0 # Пытаемся найти сообщение в БД по telegram_message_id async with async_session_maker() as session: chat_message = await ChatMessageService.get_message_by_telegram_id( session, telegram_message_id=replied_msg.message_id ) # Если нашли broadcast сообщение - удаляем у всех получателей if chat_message and chat_message.forwarded_message_ids: bot = message.bot for user_telegram_id, forwarded_msg_id in chat_message.forwarded_message_ids.items(): try: await bot.delete_message( chat_id=int(user_telegram_id), message_id=forwarded_msg_id ) deleted_count += 1 except Exception as e: logger.warning(f"Не удалось удалить сообщение у {user_telegram_id}: {e}") # Помечаем как удалённое в БД await ChatMessageService.delete_message( session, message_id=chat_message.id, deleted_by=message.from_user.id ) logger.info( f"Администратор {message.from_user.id} удалил broadcast сообщение " f"{replied_msg.message_id} у {deleted_count} получателей" ) # Удаляем исходное сообщение (на которое ответили) await replied_msg.delete() # Удаляем команду админа await message.delete() # Если было broadcast удаление - показываем статистику if deleted_count > 0: status_msg = await message.answer( f"✅ Сообщение удалено у {deleted_count} получателей", reply_to_message_id=None ) # Удаляем статус через 3 секунды import asyncio await asyncio.sleep(3) try: await status_msg.delete() except: pass except Exception as e: logger.error(f"Ошибка при быстром удалении сообщения: {e}") try: await message.answer( f"❌ Не удалось удалить: {str(e)}", reply_to_message_id=message.message_id ) except: pass