diff --git a/.bot.pid b/.bot.pid index f75cdb9..453b8ea 100644 --- a/.bot.pid +++ b/.bot.pid @@ -1 +1 @@ -969266 +983032 diff --git a/src/handlers/chat_handlers.py b/src/handlers/chat_handlers.py index b667935..000813d 100644 --- a/src/handlers/chat_handlers.py +++ b/src/handlers/chat_handlers.py @@ -104,39 +104,43 @@ 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('/'): - # Список команд, которые НЕ нужно пересылать - # (Базовые команды /start, /help уже обработаны раньше в main.py) - user_commands = ['/my_code', '/my_accounts'] + # Список известных команд + user_commands = ['/my_code', '/my_accounts', '/chat'] admin_commands = [ '/add_account', '/remove_account', '/verify_winner', '/winner_status', '/user_info', - '/check_unclaimed', '/redraw', + '/check_unclaimed', '/redraw', '/admin', '/delete', '/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: + # Если это известная команда - пропускаем (будет обработана другими обработчиками) + if command in user_commands or command in admin_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, @@ -147,63 +151,35 @@ 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("❌ Пользователь не найден") + await message.answer("❌ Вы не зарегистрированы. Используйте /start") return - # Обрабатываем в зависимости от режима - 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("❌ Не удалось переслать сообщение") + # 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}" + ) @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, @@ -215,50 +191,38 @@ 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] - 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("✅ Фото переслано в канал") + # Рассылаем всем + 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}" + ) @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, @@ -270,47 +234,35 @@ 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 - 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("✅ Видео переслано в канал") + # Рассылаем всем + 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}" + ) @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, @@ -322,47 +274,34 @@ 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 - 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("✅ Документ переслан в канал") + 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}" + ) @router.message(F.animation) async def handle_animation_message(message: Message): - """Обработчик GIF анимаций""" + """Обработчик GIF анимаций - глобальный чат (broadcast всем)""" async with async_session_maker() as session: can_send, reason = await ChatPermissionService.can_send_message( session, @@ -374,47 +313,34 @@ 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 - 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("✅ Анимация переслана в канал") + 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}" + ) @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, @@ -426,45 +352,33 @@ 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 - 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("✅ Стикер переслан в канал") + 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}" + ) @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, @@ -476,37 +390,25 @@ 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 - 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("✅ Голосовое сообщение переслано в канал") + 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}" + )