- Removed the metrics scheduler functionality from the bot, transitioning to real-time metrics updates via middleware. - Enhanced logging for metrics operations across various handlers to improve monitoring and debugging capabilities. - Integrated metrics tracking for user activities and database errors, providing better insights into bot performance. - Cleaned up code by removing obsolete comments and unused imports, improving overall readability and maintainability.
118 lines
4.2 KiB
Python
118 lines
4.2 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 - 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()
|