From 0c5b945948ebf5113787103596f446be1c8405af Mon Sep 17 00:00:00 2001 From: SXP-Simon Date: Tue, 10 Mar 2026 12:12:31 +0800 Subject: [PATCH] =?UTF-8?q?fix(onebot):=20=E5=A2=9E=E5=BC=BA=E7=BE=A4?= =?UTF-8?q?=E7=9B=B8=E5=86=8C=E5=85=BC=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增强群相册识别:通过 API 名称列表遍历,支持多种扩展名(如 get_qun_album_list, get_group_album_list 等)。 - 提升响应解析鲁棒性:实现递归式键名探测,智能提取 album_list 或 data 嵌套结构中的相册数据。 - 规范参数类型:强制 group_id 为字符串格式,严格对齐 OpenAPI 文档要求。 --- README.md | 2 +- .../platform/adapters/onebot_adapter.py | 137 +++++++++--------- 2 files changed, 68 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 9e99d04..b960508 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # 群聊日常分析插件 -[![Plugin Version](https://img.shields.io/badge/Latest_Version-v4.8.4-blue.svg?style=for-the-badge&color=76bad9)](https://github.com/SXP-Simon/astrbot-qq-group-daily-analysis) +[![Plugin Version](https://img.shields.io/badge/Latest_Version-v4.8.5-blue.svg?style=for-the-badge&color=76bad9)](https://github.com/SXP-Simon/astrbot-qq-group-daily-analysis) [![AstrBot](https://img.shields.io/badge/AstrBot-Plugin-ff69b4?style=for-the-badge)](https://github.com/AstrBotDevs/AstrBot) [![License](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](LICENSE) [![](https://img.shields.io/badge/五彩斑斓的Bug群-Bug反馈群&水群-white?style=for-the-badge&color=76bad9&logo=qq&logoColor=76bad9)](https://qm.qq.com/q/oTzIrdDBIc) diff --git a/src/infrastructure/platform/adapters/onebot_adapter.py b/src/infrastructure/platform/adapters/onebot_adapter.py index 0a7b240..8457cd5 100644 --- a/src/infrastructure/platform/adapters/onebot_adapter.py +++ b/src/infrastructure/platform/adapters/onebot_adapter.py @@ -1128,7 +1128,6 @@ class OneBotAdapter(PlatformAdapter): """ try: # 如果没有 album_id,尝试获取该群的第一个相册作为默认目标 - # 注意:某些 API (如 upload_image_to_qun_album) 强制要求 album_id 且不能为空 if not album_id: albums = await self.get_group_album_list(group_id) if albums: @@ -1150,7 +1149,7 @@ class OneBotAdapter(PlatformAdapter): try: # 尝试 upload_image_to_qun_album params = { - "group_id": int(group_id), + "group_id": str(group_id), "file": image_path, "album_id": str(album_id or ""), } @@ -1171,17 +1170,16 @@ class OneBotAdapter(PlatformAdapter): logger.error(f"Base64 回退失败:无法读取图片文件 {image_path}") raise e1 - # 重新尝试两个可能的 API 名 - params = {} - try: - params = { - "group_id": int(group_id), - "file": b64_file, - "album_id": str(album_id or ""), - } - if album_name: - params["album_name"] = album_name + # 重新尝试多个可能的 API 名 + params = { + "group_id": str(group_id), + "file": b64_file, + "album_id": str(album_id or ""), + } + if album_name: + params["album_name"] = album_name + try: await self.bot.call_action("upload_image_to_qun_album", **params) logger.info( "Base64 回退模式 (upload_image_to_qun_album) 群相册上传成功" @@ -1189,9 +1187,17 @@ class OneBotAdapter(PlatformAdapter): return True except Exception as e2: logger.debug(f"Base64 模式 1 失败,尝试模式 2: {e2}") - await self.bot.call_action("upload_group_album", **params) - logger.info("Base64 回退模式 (upload_group_album) 群相册上传成功") - return True + try: + await self.bot.call_action("upload_group_album", **params) + logger.info( + "Base64 回退模式 (upload_group_album) 群相册上传成功" + ) + return True + except Exception as e3: + logger.debug(f"Base64 模式 2 失败,尝试模式 3: {e3}") + await self.bot.call_action("upload_qun_album", **params) + logger.info("Base64 回退模式 (upload_qun_album) 群相册上传成功") + return True except Exception as e: error_msg = str(e).lower() @@ -1210,66 +1216,57 @@ class OneBotAdapter(PlatformAdapter): group_id: str, ) -> list[dict]: """ - 获取群相册列表(NapCat 扩展 API)。 - - Args: - group_id: 目标群号 - - Returns: - list[dict]: 相册列表,每项可能包含 album_id / name 等字段。 - API 不可用时返回空列表。 + 获取群相册列表(兼容多种 OneBot 扩展实现)。 """ - try: - # 策略 1: 尝试 get_qun_album_list (参考 qun_album 插件) - try: - result = await self.bot.call_action( - "get_qun_album_list", - group_id=int(group_id), - ) - if result: - logger.debug(f"get_qun_album_list 成功: {result}") - if isinstance(result, list): - return result - if isinstance(result, dict): - return result.get("albums", []) or result.get("data", []) or [] - except Exception as e: - logger.debug(f"策略 1 get_qun_album_list 尝试失败: {e}") - # 策略 2: 尝试 get_group_album_list - try: - result = await self.bot.call_action( - "get_group_album_list", - group_id=int(group_id), + def extract_list(data: Any) -> list[dict]: + if not data: + return [] + if isinstance(data, list): + return data + if isinstance(data, dict): + # 探测常见键名 + lst = ( + data.get("albums") + or data.get("album_list") + or data.get("albumList") + or data.get("list") + or [] ) - if result: - logger.debug(f"get_group_album_list 成功: {result}") - if isinstance(result, list): - return result - if isinstance(result, dict): - return result.get("albums", []) or result.get("data", []) or [] - except Exception as e: - logger.debug(f"策略 2 get_group_album_list 尝试失败: {e}") - - # 策略 3: 尝试 get_group_albums - try: - result = await self.bot.call_action( - "get_group_albums", - group_id=int(group_id), - ) - if result: - logger.debug(f"get_group_albums 成功: {result}") - if isinstance(result, list): - return result - if isinstance(result, dict): - return result.get("albums", []) or result.get("data", []) or [] - except Exception as e: - logger.debug(f"策略 3 get_group_albums 尝试失败: {e}") - - return [] - except Exception as e: - logger.debug(f"获取群相册列表最终失败: {e}") + if isinstance(lst, list): + return lst + # 如果 'data' 键本身存在且为列表 + inner_data = data.get("data") + if isinstance(inner_data, list): + return inner_data + if isinstance(inner_data, dict): + return extract_list(inner_data) return [] + # 候选 API 名称 + actions = [ + "get_qun_album_list", + "get_group_album_list", + "get_group_albums", + "get_group_root_album_list", + ] + + for action in actions: + try: + result = await self.bot.call_action( + action, + group_id=str(group_id), # 对齐文档,使用 string 类型 + ) + if result: + albums = extract_list(result) + if albums: + logger.debug(f"{action} 成功获取到 {len(albums)} 个相册") + return albums + except Exception as e: + logger.debug(f"策略 {action} 尝试失败: {e}") + + return [] + async def find_album_id( self, group_id: str,