118 lines
4.1 KiB
Python
118 lines
4.1 KiB
Python
"""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 - metrics
|
||
from helper_bot.utils.metrics import metrics, track_errors, track_time
|
||
|
||
# Local imports - utilities
|
||
from logs.custom_logger import logger
|
||
|
||
# Local imports - modular components
|
||
from .constants import ERROR_MESSAGES, FSM_STATES
|
||
from .decorators import error_handler
|
||
from .exceptions import UserNotFoundError
|
||
from .services import AdminReplyService
|
||
|
||
|
||
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.keyboards.keyboards import get_reply_keyboard_leave_chat
|
||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||
|
||
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()
|