"""Main group handlers module for Telegram bot""" # Third-party imports from aiogram import Router, types from aiogram.fsm.context import FSMContext # Local imports - filters from database.async_db import AsyncBotDB from helper_bot.filters.main import ChatTypeFilter # Local imports - modular components from .constants import FSM_STATES, ERROR_MESSAGES from .services import AdminReplyService from .decorators import error_handler from .exceptions import UserNotFoundError # Local imports - utilities from logs.custom_logger import logger # Local imports - metrics from helper_bot.utils.metrics import ( metrics, track_time, track_errors ) class GroupHandlers: """Main handler class for group messages""" def __init__(self, db: AsyncBotDB, keyboard_markup: types.ReplyKeyboardMarkup): self.db = db self.keyboard_markup = keyboard_markup self.admin_reply_service = AdminReplyService(db) # Create router self.router = Router() # Register handlers self._register_handlers() def _register_handlers(self): """Register all message handlers""" self.router.message.register( self.handle_message, ChatTypeFilter(chat_type=["group", "supergroup"]) ) @error_handler @track_errors("group_handlers", "handle_message") @track_time("handle_message", "group_handlers") async def handle_message(self, message: types.Message, state: FSMContext, **kwargs): """Handle admin reply to user through group chat""" logger.info( f'Получено сообщение в группе {message.chat.title} (ID: {message.chat.id}) ' f'от пользователя {message.from_user.full_name} (ID: {message.from_user.id}): "{message.text}"' ) # Check if message is a reply if not message.reply_to_message: await message.answer(ERROR_MESSAGES["NO_REPLY_TO_MESSAGE"]) logger.warning( f'В группе {message.chat.title} (ID: {message.chat.id}) ' f'админ не выделил сообщение для ответа.' ) return message_id = message.reply_to_message.message_id reply_text = message.text try: # Get user ID for reply chat_id = await self.admin_reply_service.get_user_id_for_reply(message_id) # Send reply to user await self.admin_reply_service.send_reply_to_user( chat_id, message, reply_text, self.keyboard_markup ) # Set state await state.set_state(FSM_STATES["CHAT"]) except UserNotFoundError: await message.answer(ERROR_MESSAGES["USER_NOT_FOUND"]) logger.error( f'Ошибка при поиске пользователя в базе для ответа на сообщение: {reply_text} ' f'в группе {message.chat.title} (ID сообщения: {message.message_id})' ) # Factory function to create handlers with dependencies def create_group_handlers(db: AsyncBotDB, keyboard_markup: types.ReplyKeyboardMarkup) -> GroupHandlers: """Create group handlers instance with dependencies""" return GroupHandlers(db, keyboard_markup) # Legacy router for backward compatibility group_router = Router() # Initialize with global dependencies (for backward compatibility) def init_legacy_router(): """Initialize legacy router with global dependencies""" global group_router from helper_bot.utils.base_dependency_factory import get_global_instance from helper_bot.keyboards.keyboards import get_reply_keyboard_leave_chat bdf = get_global_instance() #TODO: поменять архитектуру и подключить правильный BotDB db = bdf.get_db() keyboard_markup = get_reply_keyboard_leave_chat() handlers = create_group_handlers(db, keyboard_markup) group_router = handlers.router # Initialize legacy router init_legacy_router()