From 9e07b768f5283b53a0f39e21ebb7fa982cb9ba91 Mon Sep 17 00:00:00 2001 From: "Andrew K. Choi" Date: Mon, 17 Nov 2025 11:21:00 +0900 Subject: [PATCH] =?UTF-8?q?Revert=20"feat:=20=D0=B3=D0=BB=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D1=87=D0=B0=D1=82=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D1=83=D0=BC=D0=BE=D0=BB=D1=87=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8E"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 9a06d460e552656fca041f0b88f8599f91534e8d. --- src/handlers/chat_handlers.py | 410 +++++++++++++++++++++------------- 1 file changed, 254 insertions(+), 156 deletions(-) diff --git a/src/handlers/chat_handlers.py b/src/handlers/chat_handlers.py index 000813d..b667935 100644 --- a/src/handlers/chat_handlers.py +++ b/src/handlers/chat_handlers.py @@ -104,43 +104,39 @@ async def forward_to_channel(message: Message, channel_id: str) -> tuple[bool, O @router.message(F.text) async def handle_text_message(message: Message): - """ - Обработчик текстовых сообщений - глобальный чат (broadcast всем) - Сообщения автоматически рассылаются всем пользователям, кроме: - - Команд (начинаются с /) - - Паттернов счетов для админов (обрабатываются в account_handlers) - """ - # 1. Проверяем является ли это командой + """Обработчик текстовых сообщений""" + # Проверяем является ли это командой if message.text and message.text.startswith('/'): - # Список известных команд - user_commands = ['/my_code', '/my_accounts', '/chat'] + # Список команд, которые НЕ нужно пересылать + # (Базовые команды /start, /help уже обработаны раньше в main.py) + user_commands = ['/my_code', '/my_accounts'] admin_commands = [ '/add_account', '/remove_account', '/verify_winner', '/winner_status', '/user_info', - '/check_unclaimed', '/redraw', '/admin', '/delete', + '/check_unclaimed', '/redraw', '/chat_mode', '/set_forward', '/global_ban', '/ban', '/unban', '/banlist', '/delete_msg', '/chat_stats' ] # Извлекаем команду (первое слово) command = message.text.split()[0] if message.text else '' - # Если это известная команда - пропускаем (будет обработана другими обработчиками) - if command in user_commands or command in admin_commands: + # Если это пользовательская команда - пропускаем, она будет обработана другими обработчиками + if command in user_commands: return - # Неизвестная команда - тоже не рассылаем + # Если это админская команда + if command in admin_commands: + # Проверяем права админа + if not is_admin(message.from_user.id): + await message.answer("❌ У вас нет прав для выполнения этой команды") + return + # Если админ - команда будет обработана другими обработчиками, пропускаем пересылку + return + + # Если неизвестная команда - тоже не пересылаем return - # 2. Для админов - проверяем на паттерн счетов - if is_admin(message.from_user.id): - from ..utils.account_utils import parse_accounts_from_message - - accounts = parse_accounts_from_message(message.text) - if accounts: - # Это сообщение с счетами - пропускаем, обработает account_handlers - return - - # 3. Проверяем права на отправку в чат async with async_session_maker() as session: + # Проверяем права на отправку can_send, reason = await ChatPermissionService.can_send_message( session, message.from_user.id, @@ -151,35 +147,63 @@ async def handle_text_message(message: Message): await message.answer(f"❌ {reason}") return + # Получаем настройки чата + settings = await ChatSettingsService.get_or_create_settings(session) + # Получаем пользователя user = await UserService.get_user_by_telegram_id(session, message.from_user.id) if not user: - await message.answer("❌ Вы не зарегистрированы. Используйте /start") + await message.answer("❌ Пользователь не найден") return - # 4. Рассылаем сообщение всем (broadcast) - forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) - - # Сохраняем сообщение в историю - await ChatMessageService.save_message( - session, - user_id=user.id, - telegram_message_id=message.message_id, - message_type='text', - text=message.text, - forwarded_ids=forwarded_ids - ) - - await message.answer( - f"✅ Сообщение разослано!\n" - f"📤 Доставлено: {success}\n" - f"❌ Не доставлено: {fail}" - ) + # Обрабатываем в зависимости от режима + if settings.mode == 'broadcast': + # Режим рассылки с планировщиком + forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) + + # Сохраняем сообщение в историю + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='text', + text=message.text, + forwarded_ids=forwarded_ids + ) + + await message.answer( + f"✅ Сообщение разослано!\n" + f"📤 Доставлено: {success}\n" + f"❌ Не доставлено: {fail}" + ) + + elif settings.mode == 'forward': + # Режим пересылки в канал + if not settings.forward_chat_id: + await message.answer("❌ Канал для пересылки не настроен") + return + + success, channel_msg_id = await forward_to_channel(message, settings.forward_chat_id) + + if success: + # Сохраняем сообщение в историю + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='text', + text=message.text, + forwarded_ids={'channel': channel_msg_id} if channel_msg_id else None + ) + + await message.answer("✅ Сообщение переслано в канал") + else: + await message.answer("❌ Не удалось переслать сообщение") @router.message(F.photo) async def handle_photo_message(message: Message): - """Обработчик фото - глобальный чат (broadcast всем)""" + """Обработчик фото""" async with async_session_maker() as session: can_send, reason = await ChatPermissionService.can_send_message( session, @@ -191,38 +215,50 @@ async def handle_photo_message(message: Message): await message.answer(f"❌ {reason}") return + settings = await ChatSettingsService.get_or_create_settings(session) user = await UserService.get_user_by_telegram_id(session, message.from_user.id) if not user: - await message.answer("❌ Вы не зарегистрированы. Используйте /start") return # Получаем file_id самого большого фото photo = message.photo[-1] - # Рассылаем всем - forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) - - await ChatMessageService.save_message( - session, - user_id=user.id, - telegram_message_id=message.message_id, - message_type='photo', - text=message.caption, - file_id=photo.file_id, - forwarded_ids=forwarded_ids - ) - - await message.answer( - f"✅ Фото разослано!\n" - f"📤 Доставлено: {success}\n" - f"❌ Не доставлено: {fail}" - ) + if settings.mode == 'broadcast': + forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) + + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='photo', + text=message.caption, + file_id=photo.file_id, + forwarded_ids=forwarded_ids + ) + + await message.answer(f"✅ Фото разослано: {success} получателей") + + elif settings.mode == 'forward': + if settings.forward_chat_id: + success, channel_msg_id = await forward_to_channel(message, settings.forward_chat_id) + + if success: + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='photo', + text=message.caption, + file_id=photo.file_id, + forwarded_ids={'channel': channel_msg_id} if channel_msg_id else None + ) + await message.answer("✅ Фото переслано в канал") @router.message(F.video) async def handle_video_message(message: Message): - """Обработчик видео - глобальный чат (broadcast всем)""" + """Обработчик видео""" async with async_session_maker() as session: can_send, reason = await ChatPermissionService.can_send_message( session, @@ -234,35 +270,47 @@ async def handle_video_message(message: Message): await message.answer(f"❌ {reason}") return + settings = await ChatSettingsService.get_or_create_settings(session) user = await UserService.get_user_by_telegram_id(session, message.from_user.id) if not user: - await message.answer("❌ Вы не зарегистрированы. Используйте /start") return - # Рассылаем всем - forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) - - await ChatMessageService.save_message( - session, - user_id=user.id, - telegram_message_id=message.message_id, - message_type='video', - text=message.caption, - file_id=message.video.file_id, - forwarded_ids=forwarded_ids - ) - - await message.answer( - f"✅ Видео разослано!\n" - f"📤 Доставлено: {success}\n" - f"❌ Не доставлено: {fail}" - ) + if settings.mode == 'broadcast': + forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) + + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='video', + text=message.caption, + file_id=message.video.file_id, + forwarded_ids=forwarded_ids + ) + + await message.answer(f"✅ Видео разослано: {success} получателей") + + elif settings.mode == 'forward': + if settings.forward_chat_id: + success, channel_msg_id = await forward_to_channel(message, settings.forward_chat_id) + + if success: + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='video', + text=message.caption, + file_id=message.video.file_id, + forwarded_ids={'channel': channel_msg_id} if channel_msg_id else None + ) + await message.answer("✅ Видео переслано в канал") @router.message(F.document) async def handle_document_message(message: Message): - """Обработчик документов - глобальный чат (broadcast всем)""" + """Обработчик документов""" async with async_session_maker() as session: can_send, reason = await ChatPermissionService.can_send_message( session, @@ -274,34 +322,47 @@ async def handle_document_message(message: Message): await message.answer(f"❌ {reason}") return + settings = await ChatSettingsService.get_or_create_settings(session) user = await UserService.get_user_by_telegram_id(session, message.from_user.id) if not user: - await message.answer("❌ Вы не зарегистрированы. Используйте /start") return - forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) - - await ChatMessageService.save_message( - session, - user_id=user.id, - telegram_message_id=message.message_id, - message_type='document', - text=message.caption, - file_id=message.document.file_id, - forwarded_ids=forwarded_ids - ) - - await message.answer( - f"✅ Документ разослан!\n" - f"📤 Доставлено: {success}\n" - f"❌ Не доставлено: {fail}" - ) + if settings.mode == 'broadcast': + forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) + + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='document', + text=message.caption, + file_id=message.document.file_id, + forwarded_ids=forwarded_ids + ) + + await message.answer(f"✅ Документ разослан: {success} получателей") + + elif settings.mode == 'forward': + if settings.forward_chat_id: + success, channel_msg_id = await forward_to_channel(message, settings.forward_chat_id) + + if success: + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='document', + text=message.caption, + file_id=message.document.file_id, + forwarded_ids={'channel': channel_msg_id} if channel_msg_id else None + ) + await message.answer("✅ Документ переслан в канал") @router.message(F.animation) async def handle_animation_message(message: Message): - """Обработчик GIF анимаций - глобальный чат (broadcast всем)""" + """Обработчик GIF анимаций""" async with async_session_maker() as session: can_send, reason = await ChatPermissionService.can_send_message( session, @@ -313,34 +374,47 @@ async def handle_animation_message(message: Message): await message.answer(f"❌ {reason}") return + settings = await ChatSettingsService.get_or_create_settings(session) user = await UserService.get_user_by_telegram_id(session, message.from_user.id) if not user: - await message.answer("❌ Вы не зарегистрированы. Используйте /start") return - forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) - - await ChatMessageService.save_message( - session, - user_id=user.id, - telegram_message_id=message.message_id, - message_type='animation', - text=message.caption, - file_id=message.animation.file_id, - forwarded_ids=forwarded_ids - ) - - await message.answer( - f"✅ Анимация разослана!\n" - f"📤 Доставлено: {success}\n" - f"❌ Не доставлено: {fail}" - ) + if settings.mode == 'broadcast': + forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) + + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='animation', + text=message.caption, + file_id=message.animation.file_id, + forwarded_ids=forwarded_ids + ) + + await message.answer(f"✅ Анимация разослана: {success} получателей") + + elif settings.mode == 'forward': + if settings.forward_chat_id: + success, channel_msg_id = await forward_to_channel(message, settings.forward_chat_id) + + if success: + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='animation', + text=message.caption, + file_id=message.animation.file_id, + forwarded_ids={'channel': channel_msg_id} if channel_msg_id else None + ) + await message.answer("✅ Анимация переслана в канал") @router.message(F.sticker) async def handle_sticker_message(message: Message): - """Обработчик стикеров - глобальный чат (broadcast всем)""" + """Обработчик стикеров""" async with async_session_maker() as session: can_send, reason = await ChatPermissionService.can_send_message( session, @@ -352,33 +426,45 @@ async def handle_sticker_message(message: Message): await message.answer(f"❌ {reason}") return + settings = await ChatSettingsService.get_or_create_settings(session) user = await UserService.get_user_by_telegram_id(session, message.from_user.id) if not user: - await message.answer("❌ Вы не зарегистрированы. Используйте /start") return - forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) - - await ChatMessageService.save_message( - session, - user_id=user.id, - telegram_message_id=message.message_id, - message_type='sticker', - file_id=message.sticker.file_id, - forwarded_ids=forwarded_ids - ) - - await message.answer( - f"✅ Стикер разослан!\n" - f"📤 Доставлено: {success}\n" - f"❌ Не доставлено: {fail}" - ) + if settings.mode == 'broadcast': + forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) + + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='sticker', + file_id=message.sticker.file_id, + forwarded_ids=forwarded_ids + ) + + await message.answer(f"✅ Стикер разослан: {success} получателей") + + elif settings.mode == 'forward': + if settings.forward_chat_id: + success, channel_msg_id = await forward_to_channel(message, settings.forward_chat_id) + + if success: + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='sticker', + file_id=message.sticker.file_id, + forwarded_ids={'channel': channel_msg_id} if channel_msg_id else None + ) + await message.answer("✅ Стикер переслан в канал") @router.message(F.voice) async def handle_voice_message(message: Message): - """Обработчик голосовых сообщений - глобальный чат (broadcast всем)""" + """Обработчик голосовых сообщений""" async with async_session_maker() as session: can_send, reason = await ChatPermissionService.can_send_message( session, @@ -390,25 +476,37 @@ async def handle_voice_message(message: Message): await message.answer(f"❌ {reason}") return + settings = await ChatSettingsService.get_or_create_settings(session) user = await UserService.get_user_by_telegram_id(session, message.from_user.id) if not user: - await message.answer("❌ Вы не зарегистрированы. Используйте /start") return - forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) - - await ChatMessageService.save_message( - session, - user_id=user.id, - telegram_message_id=message.message_id, - message_type='voice', - file_id=message.voice.file_id, - forwarded_ids=forwarded_ids - ) - - await message.answer( - f"✅ Голосовое сообщение разослано!\n" - f"📤 Доставлено: {success}\n" - f"❌ Не доставлено: {fail}" - ) + if settings.mode == 'broadcast': + forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id) + + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='voice', + file_id=message.voice.file_id, + forwarded_ids=forwarded_ids + ) + + await message.answer(f"✅ Голосовое сообщение разослано: {success} получателей") + + elif settings.mode == 'forward': + if settings.forward_chat_id: + success, channel_msg_id = await forward_to_channel(message, settings.forward_chat_id) + + if success: + await ChatMessageService.save_message( + session, + user_id=user.id, + telegram_message_id=message.message_id, + message_type='voice', + file_id=message.voice.file_id, + forwarded_ids={'channel': channel_msg_id} if channel_msg_id else None + ) + await message.answer("✅ Голосовое сообщение переслано в канал")