mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
feat(multi-qq-platforms): 尝试适配多个适配器实例,支持填入多个QQ bot账号 (#42)
This commit is contained in:
+7
-4
@@ -33,10 +33,13 @@
|
|||||||
"hint": "是否在指定时间自动进行群聊分析,启用需要填写下面的机器人QQ号,并且确保群聊号在 enabled_groups 配置中,否则获取不到实例,不会自动分析"
|
"hint": "是否在指定时间自动进行群聊分析,启用需要填写下面的机器人QQ号,并且确保群聊号在 enabled_groups 配置中,否则获取不到实例,不会自动分析"
|
||||||
},
|
},
|
||||||
"bot_qq_id": {
|
"bot_qq_id": {
|
||||||
"type": "string",
|
"type": "list",
|
||||||
"description": "机器人QQ号",
|
"description": "机器人QQ号列表",
|
||||||
"default": "",
|
"default": [],
|
||||||
"hint": "用于自动分析的机器人QQ号,填写后可启用自动分析功能"
|
"hint": "用于自动分析的机器人QQ号,填写后可启用自动分析功能。支持配置多个QQ号,用于多机器人场景",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"enable_user_card": {
|
"enable_user_card": {
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class UserTitleAnalyzer(BaseAnalyzer):
|
|||||||
logger.warning(f"用户称号数据格式不完整,跳过: {title_data}")
|
logger.warning(f"用户称号数据格式不完整,跳过: {title_data}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 验证QQ号格式
|
# 验证QQ号格式(单个用户QQ号)
|
||||||
try:
|
try:
|
||||||
qq = int(qq)
|
qq = int(qq)
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
@@ -151,8 +151,8 @@ class UserTitleAnalyzer(BaseAnalyzer):
|
|||||||
准备好的用户数据字典
|
准备好的用户数据字典
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 获取机器人QQ号用于过滤
|
# 获取机器人QQ号列表用于过滤
|
||||||
bot_qq_id = self.config_manager.get_bot_qq_id()
|
bot_qq_ids = self.config_manager.get_bot_qq_id()
|
||||||
|
|
||||||
user_summaries = []
|
user_summaries = []
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ class UserTitleAnalyzer(BaseAnalyzer):
|
|||||||
|
|
||||||
for user_id, stats in user_analysis.items():
|
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}")
|
logger.debug(f"过滤掉机器人QQ号: {user_id}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ class UserAnalyzer:
|
|||||||
|
|
||||||
def analyze_users(self, messages: List[Dict]) -> Dict[str, Dict]:
|
def analyze_users(self, messages: List[Dict]) -> Dict[str, Dict]:
|
||||||
"""分析用户活跃度"""
|
"""分析用户活跃度"""
|
||||||
# 获取机器人QQ号用于过滤
|
# 获取机器人QQ号列表用于过滤
|
||||||
bot_qq_id = self.config_manager.get_bot_qq_id()
|
bot_qq_ids = self.config_manager.get_bot_qq_id()
|
||||||
|
|
||||||
user_stats = defaultdict(
|
user_stats = defaultdict(
|
||||||
lambda: {
|
lambda: {
|
||||||
@@ -36,7 +36,7 @@ class UserAnalyzer:
|
|||||||
user_id = str(sender.get("user_id", ""))
|
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
|
continue
|
||||||
|
|
||||||
nickname = InfoUtils.get_user_nickname(self.config_manager, sender)
|
nickname = InfoUtils.get_user_nickname(self.config_manager, sender)
|
||||||
@@ -81,13 +81,13 @@ class UserAnalyzer:
|
|||||||
self, user_analysis: Dict[str, Dict], limit: int = 10
|
self, user_analysis: Dict[str, Dict], limit: int = 10
|
||||||
) -> List[Dict]:
|
) -> List[Dict]:
|
||||||
"""获取最活跃的用户"""
|
"""获取最活跃的用户"""
|
||||||
# 获取机器人QQ号用于过滤
|
# 获取机器人QQ号列表用于过滤
|
||||||
bot_qq_id = self.config_manager.get_bot_qq_id()
|
bot_qq_ids = self.config_manager.get_bot_qq_id()
|
||||||
|
|
||||||
users = []
|
users = []
|
||||||
for user_id, stats in user_analysis.items():
|
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
|
continue
|
||||||
|
|
||||||
users.append(
|
users.append(
|
||||||
|
|||||||
+26
-12
@@ -13,6 +13,7 @@ class BotManager:
|
|||||||
self.config_manager = config_manager
|
self.config_manager = config_manager
|
||||||
self._bot_instance = None
|
self._bot_instance = None
|
||||||
self._bot_qq_id = None
|
self._bot_qq_id = None
|
||||||
|
self._bot_qq_ids = [] # 支持多个QQ号
|
||||||
self._context = None
|
self._context = None
|
||||||
self._is_initialized = False
|
self._is_initialized = False
|
||||||
|
|
||||||
@@ -30,10 +31,15 @@ class BotManager:
|
|||||||
if bot_qq_id:
|
if bot_qq_id:
|
||||||
self._bot_qq_id = str(bot_qq_id)
|
self._bot_qq_id = str(bot_qq_id)
|
||||||
|
|
||||||
def set_bot_qq_id(self, bot_qq_id: str):
|
def set_bot_qq_id(self, bot_qq_id):
|
||||||
"""设置bot QQ号"""
|
"""设置bot QQ号(支持单个或列表)"""
|
||||||
if bot_qq_id:
|
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_id = str(bot_qq_id)
|
||||||
|
self._bot_qq_ids = [str(bot_qq_id)]
|
||||||
|
|
||||||
def get_bot_instance(self):
|
def get_bot_instance(self):
|
||||||
"""获取当前bot实例"""
|
"""获取当前bot实例"""
|
||||||
@@ -45,7 +51,7 @@ class BotManager:
|
|||||||
|
|
||||||
def has_bot_qq_id(self) -> bool:
|
def has_bot_qq_id(self) -> bool:
|
||||||
"""检查是否有配置的bot QQ号"""
|
"""检查是否有配置的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:
|
def is_ready_for_auto_analysis(self) -> bool:
|
||||||
"""检查是否准备好进行自动分析"""
|
"""检查是否准备好进行自动分析"""
|
||||||
@@ -72,10 +78,10 @@ class BotManager:
|
|||||||
|
|
||||||
async def initialize_from_config(self):
|
async def initialize_from_config(self):
|
||||||
"""从配置初始化bot管理器"""
|
"""从配置初始化bot管理器"""
|
||||||
# 设置配置的bot QQ号
|
# 设置配置的bot QQ号列表
|
||||||
bot_qq_id = self.config_manager.get_bot_qq_id()
|
bot_qq_ids = self.config_manager.get_bot_qq_id()
|
||||||
if bot_qq_id:
|
if bot_qq_ids:
|
||||||
self.set_bot_qq_id(bot_qq_id)
|
self.set_bot_qq_id(bot_qq_ids)
|
||||||
|
|
||||||
# 自动发现bot实例
|
# 自动发现bot实例
|
||||||
await self.auto_discover_bot_instance()
|
await self.auto_discover_bot_instance()
|
||||||
@@ -110,7 +116,7 @@ class BotManager:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def _extract_bot_qq_id(self, bot_instance):
|
def _extract_bot_qq_id(self, bot_instance):
|
||||||
"""从bot实例中提取QQ号"""
|
"""从bot实例中提取QQ号(单个)"""
|
||||||
# 尝试多种方式获取bot QQ号
|
# 尝试多种方式获取bot QQ号
|
||||||
if hasattr(bot_instance, "self_id") and bot_instance.self_id:
|
if hasattr(bot_instance, "self_id") and bot_instance.self_id:
|
||||||
return str(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)
|
return self.has_bot_instance() and bool(group_id)
|
||||||
|
|
||||||
def should_filter_bot_message(self, sender_id: str) -> bool:
|
def should_filter_bot_message(self, sender_id: str) -> bool:
|
||||||
"""判断是否应该过滤bot自己的消息"""
|
"""判断是否应该过滤bot自己的消息(支持多个QQ号)"""
|
||||||
if not self._bot_qq_id:
|
if not self._bot_qq_ids and not self._bot_qq_id:
|
||||||
return False
|
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
|
||||||
|
|||||||
+3
-3
@@ -115,9 +115,9 @@ class ConfigManager:
|
|||||||
"pdf_output_dir", "data/plugins/astrbot-qq-group-daily-analysis/reports"
|
"pdf_output_dir", "data/plugins/astrbot-qq-group-daily-analysis/reports"
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_bot_qq_id(self) -> str:
|
def get_bot_qq_id(self) -> list:
|
||||||
"""获取bot QQ号"""
|
"""获取bot QQ号列表"""
|
||||||
return str(self.config.get("bot_qq_id", ""))
|
return self.config.get("bot_qq_id", [])
|
||||||
|
|
||||||
def get_pdf_filename_format(self) -> str:
|
def get_pdf_filename_format(self) -> str:
|
||||||
"""获取PDF文件名格式"""
|
"""获取PDF文件名格式"""
|
||||||
|
|||||||
@@ -19,11 +19,15 @@ class MessageHandler:
|
|||||||
self.activity_visualizer = ActivityVisualizer()
|
self.activity_visualizer = ActivityVisualizer()
|
||||||
self.bot_manager = bot_manager
|
self.bot_manager = bot_manager
|
||||||
|
|
||||||
async def set_bot_qq_id(self, bot_qq_id: str):
|
async def set_bot_qq_id(self, bot_qq_id):
|
||||||
"""设置机器人QQ号(保持向后兼容)"""
|
"""设置机器人QQ号(支持单个QQ号或QQ号列表)"""
|
||||||
try:
|
try:
|
||||||
if self.bot_manager:
|
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}")
|
logger.info(f"设置机器人QQ号: {bot_qq_id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"设置机器人QQ号失败: {e}")
|
logger.error(f"设置机器人QQ号失败: {e}")
|
||||||
@@ -33,7 +37,7 @@ class MessageHandler:
|
|||||||
self.bot_manager = bot_manager
|
self.bot_manager = bot_manager
|
||||||
|
|
||||||
def _extract_bot_qq_id_from_instance(self, bot_instance):
|
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:
|
if hasattr(bot_instance, "self_id") and bot_instance.self_id:
|
||||||
return str(bot_instance.self_id)
|
return str(bot_instance.self_id)
|
||||||
elif hasattr(bot_instance, "qq") and bot_instance.qq:
|
elif hasattr(bot_instance, "qq") and bot_instance.qq:
|
||||||
@@ -52,12 +56,13 @@ class MessageHandler:
|
|||||||
logger.error(f"群 {group_id} 参数无效")
|
logger.error(f"群 {group_id} 参数无效")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# 确保bot_manager有QQ号用于过滤
|
# 确保bot_manager有QQ号列表用于过滤
|
||||||
if self.bot_manager and not self.bot_manager.has_bot_qq_id():
|
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)
|
bot_qq_id = self._extract_bot_qq_id_from_instance(bot_instance)
|
||||||
if bot_qq_id:
|
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()
|
end_time = datetime.now()
|
||||||
|
|||||||
@@ -33,9 +33,13 @@ class AutoScheduler:
|
|||||||
"""设置bot实例(保持向后兼容)"""
|
"""设置bot实例(保持向后兼容)"""
|
||||||
self.bot_manager.set_bot_instance(bot_instance)
|
self.bot_manager.set_bot_instance(bot_instance)
|
||||||
|
|
||||||
def set_bot_qq_id(self, bot_qq_id: str):
|
def set_bot_qq_id(self, bot_qq_id):
|
||||||
"""设置bot QQ号(保持向后兼容)"""
|
"""设置bot QQ号(支持单个QQ号或QQ号列表)"""
|
||||||
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])
|
||||||
|
|
||||||
def _get_platform_id(self):
|
def _get_platform_id(self):
|
||||||
"""获取平台ID"""
|
"""获取平台ID"""
|
||||||
|
|||||||
@@ -27,7 +27,11 @@ class MessageAnalyzer:
|
|||||||
if self.bot_manager:
|
if self.bot_manager:
|
||||||
self.bot_manager.set_bot_instance(bot_instance)
|
self.bot_manager.set_bot_instance(bot_instance)
|
||||||
else:
|
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(
|
async def analyze_messages(
|
||||||
self, messages: List[Dict], group_id: str, unified_msg_origin: str = None
|
self, messages: List[Dict], group_id: str, unified_msg_origin: str = None
|
||||||
|
|||||||
Reference in New Issue
Block a user