feature/chat-system #2

Merged
trevor merged 28 commits from feature/chat-system into master 2025-11-17 06:05:49 +00:00
35 changed files with 11571 additions and 415 deletions
Showing only changes of commit 84adcce57b - Show all commits

View File

@@ -1 +1 @@
1011501
1014690

View File

@@ -185,6 +185,23 @@ class ChatMessageService:
)
return result.scalar_one_or_none()
@staticmethod
async def get_message_by_telegram_id(
session: AsyncSession,
telegram_message_id: int,
user_id: Optional[int] = None
) -> Optional[ChatMessage]:
"""Получить сообщение по telegram_message_id"""
query = select(ChatMessage).where(
ChatMessage.telegram_message_id == telegram_message_id
)
if user_id:
query = query.where(ChatMessage.user_id == user_id)
result = await session.execute(query)
return result.scalar_one_or_none()
@staticmethod
async def get_user_messages(
session: AsyncSession,

View File

@@ -2,11 +2,13 @@
Хэндлеры для управления сообщениями администратором
"""
import logging
from aiogram import Router, F
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__)
@@ -86,16 +88,75 @@ async def quick_delete_replied_message(message: Message):
- "удалить", "delete", "del"
- 🗑️ (мусорная корзина)
- ❌ (крестик)
Удаляет сообщение у всех получателей broadcast рассылки
"""
if not is_admin(message.from_user.id):
return # Не админ - пропускаем
try:
# Удаляем сообщение на которое ответили
await message.reply_to_message.delete()
# Удаляем команду
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()
logger.info(f"Администратор {message.from_user.id} быстро удалил сообщение {message.reply_to_message.message_id}")
# Если было 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}")
await message.answer(f"Не удалось удалить: {str(e)}", reply_to_message_id=message.message_id)
try:
await message.answer(
f"Не удалось удалить: {str(e)}",
reply_to_message_id=message.message_id
)
except:
pass