@wecom/wecom-openclaw-plugin 2026.3.20-beta.1 → 2026.3.20-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +129 -52
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +129 -52
- package/dist/index.esm.js.map +1 -1
- package/dist/src/mcp/transport.d.ts +9 -1
- package/package.json +1 -1
- package/skills/wecom-msg/SKILL.md +35 -4
- package/skills/wecom-msg/references/api-get-messages.md +37 -12
- package/skills/wecom-msg/references/api-get-msg-media.md +44 -0
- package/skills/wecom-send-media/SKILL.md +1 -3
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* - SSE 流式响应解析
|
|
10
10
|
* - MCP 配置运行时缓存(通过 WSClient 拉取 URL 并缓存在内存中)
|
|
11
11
|
*/
|
|
12
|
+
/** 媒体下载请求超时时间(毫秒),base64 编码的媒体文件最大可达 ~27MB */
|
|
13
|
+
export declare const MEDIA_DOWNLOAD_TIMEOUT_MS = 120000;
|
|
12
14
|
/**
|
|
13
15
|
* MCP JSON-RPC 错误
|
|
14
16
|
*
|
|
@@ -44,6 +46,11 @@ export interface McpToolInfo {
|
|
|
44
46
|
description?: string;
|
|
45
47
|
inputSchema?: Record<string, unknown>;
|
|
46
48
|
}
|
|
49
|
+
/** sendJsonRpc 的可选配置 */
|
|
50
|
+
export interface SendJsonRpcOptions {
|
|
51
|
+
/** 自定义 HTTP 请求超时时间(毫秒),默认使用 HTTP_REQUEST_TIMEOUT_MS */
|
|
52
|
+
timeoutMs?: number;
|
|
53
|
+
}
|
|
47
54
|
/**
|
|
48
55
|
* 发送 JSON-RPC 请求到 MCP Server(Streamable HTTP 协议)
|
|
49
56
|
*
|
|
@@ -54,6 +61,7 @@ export interface McpToolInfo {
|
|
|
54
61
|
* @param category - MCP 品类名称
|
|
55
62
|
* @param method - JSON-RPC 方法名
|
|
56
63
|
* @param params - JSON-RPC 参数
|
|
64
|
+
* @param options - 可选配置(如自定义超时)
|
|
57
65
|
* @returns JSON-RPC result
|
|
58
66
|
*/
|
|
59
|
-
export declare function sendJsonRpc(category: string, method: string, params?: Record<string, unknown
|
|
67
|
+
export declare function sendJsonRpc(category: string, method: string, params?: Record<string, unknown>, options?: SendJsonRpcOptions): Promise<unknown>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: wecom-msg
|
|
3
|
-
description:
|
|
3
|
+
description: 企业微信消息技能。提供会话列表查询、消息记录拉取(支持文本/图片/文件/语音/视频)、多媒体文件获取和文本消息发送能力。当用户需要"查看消息"、"看聊天记录"、"发消息给某人"、"最近有什么消息"、"给群里发消息"、"看看发了什么图片/文件"时触发。
|
|
4
4
|
metadata:
|
|
5
5
|
{
|
|
6
6
|
"openclaw": { "emoji": "💬" },
|
|
@@ -29,7 +29,13 @@ metadata:
|
|
|
29
29
|
|
|
30
30
|
使用 `wecom_mcp` tool 调用 `wecom_mcp call msg get_messages '{"chat_type": 1, "chatid": "zhangsan", "begin_time": "2026-03-17 09:00:00", "end_time": "2026-03-17 18:00:00"}'`
|
|
31
31
|
|
|
32
|
-
根据会话类型和 ID
|
|
32
|
+
根据会话类型和 ID 拉取指定时间范围内的消息记录,支持分页。支持 text/image/file/voice/video 消息类型,仅支持 7 天内。参见 [API 详情](references/api-get-messages.md)。
|
|
33
|
+
|
|
34
|
+
### get_msg_media — 获取消息文件内容
|
|
35
|
+
|
|
36
|
+
使用 `wecom_mcp` tool 调用 `wecom_mcp call msg get_msg_media '{"media_id": "MEDIAID_xxxxxx"}'`
|
|
37
|
+
|
|
38
|
+
根据文件 ID 自动下载文件到本地,返回文件的本地路径(`local_path`)、名称、类型、大小及 MIME 类型。用于获取图片、文件、语音、视频等非文本消息的实际内容。参见 [API 详情](references/api-get-msg-media.md)。
|
|
33
39
|
|
|
34
40
|
### send_message — 发送文本消息
|
|
35
41
|
|
|
@@ -90,8 +96,33 @@ metadata:
|
|
|
90
96
|
2. 通过 **chatid查找规则** 确定目标会话的 `chatid` 和 `chat_type`
|
|
91
97
|
3. 调用 `get_messages` 拉取消息列表
|
|
92
98
|
4. 调用 `wecom-contact-lookup` 的 `get_userlist` 获取通讯录,建立 userid→姓名 映射
|
|
93
|
-
5.
|
|
94
|
-
6.
|
|
99
|
+
5. **统计非文本消息**:遍历消息列表,统计 `msgtype` 非 `text` 的消息(image/file/voice/video)数量和类型
|
|
100
|
+
6. 展示消息时将 `userid` 替换为可读姓名,格式:
|
|
101
|
+
- 文本消息:`姓名 [时间]: 内容`
|
|
102
|
+
- 图片消息:`姓名 [时间]:[图片]`
|
|
103
|
+
- 文件消息:`姓名 [时间]:[文件] 文件名称`
|
|
104
|
+
- 语音消息:`姓名 [时间]:[语音] 语音内容`
|
|
105
|
+
- 视频消息:`姓名 [时间]:[视频]`
|
|
106
|
+
7. **非文本消息处理**:展示完消息后,如果存在非文本消息:
|
|
107
|
+
- **主动询问是否下载**:告知用户非文本消息数量和类型(如:"以上聊天中包含 2 张图片、1 个文件,是否需要下载到本地?")
|
|
108
|
+
- 用户确认后,逐个调用 `get_msg_media` 接口,接口会自动下载文件并返回 `local_path`
|
|
109
|
+
- **检查文件后缀**:每个文件下载完成后,检查 `local_path` 对应的文件是否具有正确的后缀名:
|
|
110
|
+
- 根据 `get_msg_media` 返回的 `content_type`(MIME 类型)和 `name` 字段判断:
|
|
111
|
+
- 如果文件名缺少后缀(如 `screenshot` 而非 `screenshot.png`),根据 `content_type` 自动补上正确后缀(如 `image/png` → `.png`,`application/pdf` → `.pdf`,`audio/amr` → `.amr`,`video/mp4` → `.mp4`)
|
|
112
|
+
- 如果文件名后缀与 `content_type` 不一致,以 `content_type` 为准进行修正
|
|
113
|
+
- 补全或修正后缀后,将文件重命名为正确的文件名
|
|
114
|
+
- 确认文件可正常读取(文件大小 > 0),若文件为空或损坏则告知用户该文件下载异常
|
|
115
|
+
- ⚠️ **不要对下载的文件使用 `MEDIA:` 指令**:这些文件是从聊天记录中下载的历史附件,仅需告知用户本地存放路径即可,**严禁**通过 `MEDIA:` 指令重新发送给用户
|
|
116
|
+
- ⚠️ **必须主动告知文件位置**(此步骤不可省略):所有文件下载并检查完成后,**必须立即、主动**以汇总形式向用户展示文件存放目录和每个文件的完整路径,不要等用户询问。示例:
|
|
117
|
+
> 📁 文件已下载到以下位置:
|
|
118
|
+
> - 图片:`/tmp/wecom_media/screenshot.png`
|
|
119
|
+
> - 文件:`/tmp/wecom_media/report.pdf`
|
|
120
|
+
>
|
|
121
|
+
> 你可以在 `/tmp/wecom_media/` 目录下找到所有下载的文件。
|
|
122
|
+
- ⚠️**询问是否删除**(此步骤不可省略):告知文件位置后,**必须立即、主动**询问用户是否需要删除已下载的临时文件(如:"如果不再需要这些文件,是否需要我帮你清理?")
|
|
123
|
+
- 用户确认删除后,删除 `local_path` 对应的文件
|
|
124
|
+
- 用户不需要删除则保留文件
|
|
125
|
+
8. 若 `next_cursor` 不为空,告知用户还有更多消息可继续查看
|
|
95
126
|
|
|
96
127
|
### 发送消息
|
|
97
128
|
**用户query示例**:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# get_messages API
|
|
2
2
|
|
|
3
|
-
根据会话类型和会话 ID
|
|
3
|
+
根据会话类型和会话 ID,拉取指定时间范围内的消息记录。支持文本、图片、文件、语音、视频类型消息。
|
|
4
4
|
|
|
5
5
|
## 参数说明
|
|
6
6
|
|
|
@@ -30,14 +30,25 @@
|
|
|
30
30
|
|
|
31
31
|
| 字段 | 类型 | 说明 |
|
|
32
32
|
|------|------|------|
|
|
33
|
-
| `errcode` |
|
|
34
|
-
| `errmsg` |
|
|
35
|
-
| `messages` |
|
|
36
|
-
| `messages[].userid` |
|
|
37
|
-
| `messages[].send_time` |
|
|
38
|
-
| `messages[].msgtype` |
|
|
39
|
-
| `messages[].text
|
|
40
|
-
| `
|
|
33
|
+
| `errcode` | Integer | 返回码,`0` 表示成功 |
|
|
34
|
+
| `errmsg` | String | 错误信息 |
|
|
35
|
+
| `messages` | Array | 消息列表 |
|
|
36
|
+
| `messages[].userid` | String | 消息发送者的 userid |
|
|
37
|
+
| `messages[].send_time` | String | 消息发送时间(北京时间),格式:`YYYY-MM-DD HH:mm:ss` |
|
|
38
|
+
| `messages[].msgtype` | String | 消息类型,`text`-文本消息,`image`-图片消息,`file`-文件消息,`voice`-语音消息,`video`-视频消息 |
|
|
39
|
+
| `messages[].text` | Object | 文本消息内容,`msgtype` 为 `text` 时返回 |
|
|
40
|
+
| `messages[].text.content` | String | 消息内容 |
|
|
41
|
+
| `messages[].image` | Object | 图片消息内容,`msgtype` 为 `image` 时返回 |
|
|
42
|
+
| `messages[].image.media_id` | String | 图片的 media_id,可通过 `get_msg_media` 接口下载 |
|
|
43
|
+
| `messages[].image.name` | String | 图片文件名称 |
|
|
44
|
+
| `messages[].file` | Object | 文件消息内容,`msgtype` 为 `file` 时返回 |
|
|
45
|
+
| `messages[].file.media_id` | String | 文件的 media_id,可通过 `get_msg_media` 接口下载 |
|
|
46
|
+
| `messages[].file.name` | String | 文件名称 |
|
|
47
|
+
| `messages[].voice` | Object | 语音消息内容,`msgtype` 为 `voice` 时返回 |
|
|
48
|
+
| `messages[].voice.media_id` | String | 语音的 media_id,可通过 `get_msg_media` 接口下载 |
|
|
49
|
+
| `messages[].video` | Object | 视频消息内容,`msgtype` 为 `video` 时返回 |
|
|
50
|
+
| `messages[].video.media_id` | String | 视频的 media_id,可通过 `get_msg_media` 接口下载 |
|
|
51
|
+
| `next_cursor` | String | 分页游标,为空表示已拉取完毕 |
|
|
41
52
|
|
|
42
53
|
## 响应示例
|
|
43
54
|
|
|
@@ -57,12 +68,26 @@
|
|
|
57
68
|
{
|
|
58
69
|
"userid": "lisi",
|
|
59
70
|
"send_time": "2026-03-17 09:35:00",
|
|
60
|
-
"msgtype": "
|
|
61
|
-
"
|
|
62
|
-
"
|
|
71
|
+
"msgtype": "image",
|
|
72
|
+
"image": {
|
|
73
|
+
"media_id": "MEDIAID_xxxxxx",
|
|
74
|
+
"name": "screenshot.png"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"userid": "zhangsan",
|
|
79
|
+
"send_time": "2026-03-17 09:40:00",
|
|
80
|
+
"msgtype": "file",
|
|
81
|
+
"file": {
|
|
82
|
+
"media_id": "MEDIAID_yyyyyy",
|
|
83
|
+
"name": "report.pdf"
|
|
63
84
|
}
|
|
64
85
|
}
|
|
65
86
|
],
|
|
66
87
|
"next_cursor": "CURSOR_xxxxxx"
|
|
67
88
|
}
|
|
68
89
|
```
|
|
90
|
+
|
|
91
|
+
## 非文本消息处理
|
|
92
|
+
|
|
93
|
+
当 `msgtype` 为 `image`、`file`、`voice`、`video` 时,消息体中包含 `media_id`。需要调用 [get_msg_media](api-get-msg-media.md) 接口获取文件的本地路径(`local_path`),再进行展示。
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# get_msg_media API
|
|
2
|
+
|
|
3
|
+
获取消息文件内容。根据文件 ID 自动下载文件到本地,返回本地文件路径、文件名称、类型、大小及内容类型。
|
|
4
|
+
|
|
5
|
+
## 参数说明
|
|
6
|
+
|
|
7
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
8
|
+
|------|------|------|------|
|
|
9
|
+
| `media_id` | string | ✅ | 文件 ID,长度 1~256 |
|
|
10
|
+
|
|
11
|
+
## 请求示例
|
|
12
|
+
|
|
13
|
+
使用 `wecom_mcp` tool 调用 `wecom_mcp call msg get_msg_media '{"media_id": "MEDIAID_xxxxxx"}'`
|
|
14
|
+
|
|
15
|
+
## 返回字段
|
|
16
|
+
|
|
17
|
+
| 字段 | 类型 | 说明 |
|
|
18
|
+
|------|------|------|
|
|
19
|
+
| `errcode` | Integer | 返回码,`0` 表示成功 |
|
|
20
|
+
| `errmsg` | String | 错误信息 |
|
|
21
|
+
| `media_item` | Object | 文件内容 |
|
|
22
|
+
| `media_item.media_id` | String | 文件 ID |
|
|
23
|
+
| `media_item.name` | String | 文件名称 |
|
|
24
|
+
| `media_item.type` | String | 文件类型,`image`-图片,`voice`-语音,`video`-视频,`file`-普通文件 |
|
|
25
|
+
| `media_item.local_path` | String | 文件下载后的本地路径 |
|
|
26
|
+
| `media_item.size` | Integer | 文件大小(字节) |
|
|
27
|
+
| `media_item.content_type` | String | 文件 MIME 类型,如 `image/png`、`application/pdf` 等 |
|
|
28
|
+
|
|
29
|
+
## 响应示例
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"errcode": 0,
|
|
34
|
+
"errmsg": "ok",
|
|
35
|
+
"media_item": {
|
|
36
|
+
"media_id": "MEDIAID_xxxxxx",
|
|
37
|
+
"name": "screenshot.png",
|
|
38
|
+
"type": "image",
|
|
39
|
+
"local_path": "/tmp/wecom_media/screenshot.png",
|
|
40
|
+
"size": 102400,
|
|
41
|
+
"content_type": "image/png"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
@@ -43,9 +43,7 @@ MEDIA: <文件的绝对路径>
|
|
|
43
43
|
| 语音 | 2 MB | **仅支持 AMR 格式**(`.amr`) |
|
|
44
44
|
| 文件 | 20 MB | 不限 |
|
|
45
45
|
|
|
46
|
-
⚠️
|
|
47
|
-
|
|
48
|
-
## 降级与限制处理
|
|
46
|
+
⚠️ 重要:请务必**先检查文件大小和格式**是否满足要求。如果不满足要求,请主动告知用户以下”降级与限制处理“措施:
|
|
49
47
|
|
|
50
48
|
- **自动降级**:当图片、视频或语音超过各自的大小限制时,系统会自动将其转为文件消息发送,请主动告诉用户。
|
|
51
49
|
- **硬性上限**:文件大小超过 20 MB 时无法发送。请主动告知用户,并尝试压缩或拆分文件后再发送。
|