diff --git a/_conf_schema.json b/_conf_schema.json index 8ecd019..f28c458 100644 --- a/_conf_schema.json +++ b/_conf_schema.json @@ -33,10 +33,13 @@ "hint": "是否在指定时间自动进行群聊分析,启用需要填写下面的机器人QQ号,并且确保群聊号在 enabled_groups 配置中,否则获取不到实例,不会自动分析" }, "bot_qq_id": { - "type": "string", - "description": "机器人QQ号", - "default": "", - "hint": "用于自动分析的机器人QQ号,填写后可启用自动分析功能" + "type": "list", + "description": "机器人QQ号列表", + "default": [], + "hint": "用于自动分析的机器人QQ号,填写后可启用自动分析功能。支持配置多个QQ号,用于多机器人场景", + "items": { + "type": "string" + } }, "enable_user_card": { "type": "bool", diff --git a/src/analysis/analyzers/user_title_analyzer.py b/src/analysis/analyzers/user_title_analyzer.py index e16e149..a38da54 100644 --- a/src/analysis/analyzers/user_title_analyzer.py +++ b/src/analysis/analyzers/user_title_analyzer.py @@ -119,7 +119,7 @@ class UserTitleAnalyzer(BaseAnalyzer): logger.warning(f"用户称号数据格式不完整,跳过: {title_data}") continue - # 验证QQ号格式 + # 验证QQ号格式(单个用户QQ号) try: qq = int(qq) except (ValueError, TypeError): @@ -151,8 +151,8 @@ class UserTitleAnalyzer(BaseAnalyzer): 准备好的用户数据字典 """ try: - # 获取机器人QQ号用于过滤 - bot_qq_id = self.config_manager.get_bot_qq_id() + # 获取机器人QQ号列表用于过滤 + bot_qq_ids = self.config_manager.get_bot_qq_id() user_summaries = [] @@ -173,7 +173,7 @@ class UserTitleAnalyzer(BaseAnalyzer): for user_id, stats in user_analysis.items(): # 过滤机器人自己的消息 - if bot_qq_id and str(user_id) == str(bot_qq_id): + if bot_qq_ids and str(user_id) in [str(qq) for qq in bot_qq_ids]: logger.debug(f"过滤掉机器人QQ号: {user_id}") continue diff --git a/src/analysis/statistics.py b/src/analysis/statistics.py index 937478c..a2d1e0e 100644 --- a/src/analysis/statistics.py +++ b/src/analysis/statistics.py @@ -17,8 +17,8 @@ class UserAnalyzer: def analyze_users(self, messages: List[Dict]) -> Dict[str, Dict]: """分析用户活跃度""" - # 获取机器人QQ号用于过滤 - bot_qq_id = self.config_manager.get_bot_qq_id() + # 获取机器人QQ号列表用于过滤 + bot_qq_ids = self.config_manager.get_bot_qq_id() user_stats = defaultdict( lambda: { @@ -36,7 +36,7 @@ class UserAnalyzer: user_id = str(sender.get("user_id", "")) # 跳过机器人自己的消息,避免进入统计 - if bot_qq_id and user_id == str(bot_qq_id): + if bot_qq_ids and user_id in [str(qq) for qq in bot_qq_ids]: continue nickname = InfoUtils.get_user_nickname(self.config_manager, sender) @@ -81,13 +81,13 @@ class UserAnalyzer: self, user_analysis: Dict[str, Dict], limit: int = 10 ) -> List[Dict]: """获取最活跃的用户""" - # 获取机器人QQ号用于过滤 - bot_qq_id = self.config_manager.get_bot_qq_id() + # 获取机器人QQ号列表用于过滤 + bot_qq_ids = self.config_manager.get_bot_qq_id() users = [] for user_id, stats in user_analysis.items(): # 过滤机器人自己 - if bot_qq_id and str(user_id) == str(bot_qq_id): + if bot_qq_ids and str(user_id) in [str(qq) for qq in bot_qq_ids]: continue users.append( diff --git a/src/core/bot_manager.py b/src/core/bot_manager.py index 5340121..8aaa9dc 100644 --- a/src/core/bot_manager.py +++ b/src/core/bot_manager.py @@ -13,6 +13,7 @@ class BotManager: self.config_manager = config_manager self._bot_instance = None self._bot_qq_id = None + self._bot_qq_ids = [] # 支持多个QQ号 self._context = None self._is_initialized = False @@ -30,10 +31,15 @@ class BotManager: if bot_qq_id: self._bot_qq_id = str(bot_qq_id) - def set_bot_qq_id(self, bot_qq_id: str): - """设置bot QQ号""" - if bot_qq_id: + def set_bot_qq_id(self, bot_qq_id): + """设置bot QQ号(支持单个或列表)""" + if isinstance(bot_qq_id, list): + self._bot_qq_ids = [str(qq) for qq in bot_qq_id if qq] + if self._bot_qq_ids: + self._bot_qq_id = self._bot_qq_ids[0] # 保持向后兼容 + elif bot_qq_id: self._bot_qq_id = str(bot_qq_id) + self._bot_qq_ids = [str(bot_qq_id)] def get_bot_instance(self): """获取当前bot实例""" @@ -45,7 +51,7 @@ class BotManager: def has_bot_qq_id(self) -> bool: """检查是否有配置的bot QQ号""" - return self._bot_qq_id is not None + return bool(self._bot_qq_ids) or self._bot_qq_id is not None def is_ready_for_auto_analysis(self) -> bool: """检查是否准备好进行自动分析""" @@ -72,10 +78,10 @@ class BotManager: async def initialize_from_config(self): """从配置初始化bot管理器""" - # 设置配置的bot QQ号 - bot_qq_id = self.config_manager.get_bot_qq_id() - if bot_qq_id: - self.set_bot_qq_id(bot_qq_id) + # 设置配置的bot QQ号列表 + bot_qq_ids = self.config_manager.get_bot_qq_id() + if bot_qq_ids: + self.set_bot_qq_id(bot_qq_ids) # 自动发现bot实例 await self.auto_discover_bot_instance() @@ -110,7 +116,7 @@ class BotManager: return False def _extract_bot_qq_id(self, bot_instance): - """从bot实例中提取QQ号""" + """从bot实例中提取QQ号(单个)""" # 尝试多种方式获取bot QQ号 if hasattr(bot_instance, "self_id") and bot_instance.self_id: return str(bot_instance.self_id) @@ -125,7 +131,15 @@ class BotManager: return self.has_bot_instance() and bool(group_id) def should_filter_bot_message(self, sender_id: str) -> bool: - """判断是否应该过滤bot自己的消息""" - if not self._bot_qq_id: + """判断是否应该过滤bot自己的消息(支持多个QQ号)""" + if not self._bot_qq_ids and not self._bot_qq_id: return False - return str(sender_id) == self._bot_qq_id + + sender_id_str = str(sender_id) + # 检查是否在QQ号列表中 + if self._bot_qq_ids and sender_id_str in self._bot_qq_ids: + return True + # 向后兼容:检查单个QQ号 + if self._bot_qq_id and sender_id_str == self._bot_qq_id: + return True + return False diff --git a/src/core/config.py b/src/core/config.py index 88f0dc1..4b2cdd7 100644 --- a/src/core/config.py +++ b/src/core/config.py @@ -115,9 +115,9 @@ class ConfigManager: "pdf_output_dir", "data/plugins/astrbot-qq-group-daily-analysis/reports" ) - def get_bot_qq_id(self) -> str: - """获取bot QQ号""" - return str(self.config.get("bot_qq_id", "")) + def get_bot_qq_id(self) -> list: + """获取bot QQ号列表""" + return self.config.get("bot_qq_id", []) def get_pdf_filename_format(self) -> str: """获取PDF文件名格式""" diff --git a/src/core/message_handler.py b/src/core/message_handler.py index 5f6e3c1..b016535 100644 --- a/src/core/message_handler.py +++ b/src/core/message_handler.py @@ -19,11 +19,15 @@ class MessageHandler: self.activity_visualizer = ActivityVisualizer() self.bot_manager = bot_manager - async def set_bot_qq_id(self, bot_qq_id: str): - """设置机器人QQ号(保持向后兼容)""" + async def set_bot_qq_id(self, bot_qq_id): + """设置机器人QQ号(支持单个QQ号或QQ号列表)""" try: if self.bot_manager: - self.bot_manager.set_bot_qq_id(bot_qq_id) + # 确保传入的是列表,保持统一处理 + if isinstance(bot_qq_id, list): + self.bot_manager.set_bot_qq_id(bot_qq_id) + elif bot_qq_id: + self.bot_manager.set_bot_qq_id([bot_qq_id]) logger.info(f"设置机器人QQ号: {bot_qq_id}") except Exception as e: logger.error(f"设置机器人QQ号失败: {e}") @@ -33,7 +37,7 @@ class MessageHandler: self.bot_manager = bot_manager def _extract_bot_qq_id_from_instance(self, bot_instance): - """从bot实例中提取QQ号""" + """从bot实例中提取QQ号(单个)""" if hasattr(bot_instance, "self_id") and bot_instance.self_id: return str(bot_instance.self_id) elif hasattr(bot_instance, "qq") and bot_instance.qq: @@ -52,12 +56,13 @@ class MessageHandler: logger.error(f"群 {group_id} 参数无效") return [] - # 确保bot_manager有QQ号用于过滤 + # 确保bot_manager有QQ号列表用于过滤 if self.bot_manager and not self.bot_manager.has_bot_qq_id(): - # 尝试从bot_instance提取QQ号 + # 尝试从bot_instance提取QQ号并设置为列表 bot_qq_id = self._extract_bot_qq_id_from_instance(bot_instance) if bot_qq_id: - self.bot_manager.set_bot_qq_id(bot_qq_id) + # 将单个QQ号转换为列表,保持统一处理 + self.bot_manager.set_bot_qq_id([bot_qq_id]) # 计算时间范围 end_time = datetime.now() diff --git a/src/scheduler/auto_scheduler.py b/src/scheduler/auto_scheduler.py index 121e1a9..0f83413 100644 --- a/src/scheduler/auto_scheduler.py +++ b/src/scheduler/auto_scheduler.py @@ -33,9 +33,13 @@ class AutoScheduler: """设置bot实例(保持向后兼容)""" self.bot_manager.set_bot_instance(bot_instance) - def set_bot_qq_id(self, bot_qq_id: str): - """设置bot QQ号(保持向后兼容)""" - self.bot_manager.set_bot_qq_id(bot_qq_id) + def set_bot_qq_id(self, bot_qq_id): + """设置bot QQ号(支持单个QQ号或QQ号列表)""" + # 确保传入的是列表,保持统一处理 + if isinstance(bot_qq_id, list): + self.bot_manager.set_bot_qq_id(bot_qq_id) + elif bot_qq_id: + self.bot_manager.set_bot_qq_id([bot_qq_id]) def _get_platform_id(self): """获取平台ID""" diff --git a/src/utils/helpers.py b/src/utils/helpers.py index a645902..5e68964 100644 --- a/src/utils/helpers.py +++ b/src/utils/helpers.py @@ -27,7 +27,11 @@ class MessageAnalyzer: if self.bot_manager: self.bot_manager.set_bot_instance(bot_instance) else: - await self.message_handler.set_bot_qq_id(bot_instance) + # 从bot实例提取QQ号并设置为列表 + bot_qq_id = self._extract_bot_qq_id_from_instance(bot_instance) + if bot_qq_id: + # 将单个QQ号转换为列表,保持统一处理 + await self.message_handler.set_bot_qq_id([bot_qq_id]) async def analyze_messages( self, messages: List[Dict], group_id: str, unified_msg_origin: str = None