@yanhaidao/wecom 2.3.3 → 2.3.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/.github/workflows/release.yml +69 -1
- package/README.md +2 -0
- package/changelog/v2.3.4.md +20 -0
- package/compat-single-account.md +1 -1
- package/index.test.ts +34 -0
- package/index.ts +11 -3
- package/package.json +1 -1
- package/src/types/constants.ts +2 -2
|
@@ -4,6 +4,7 @@ on:
|
|
|
4
4
|
push:
|
|
5
5
|
tags:
|
|
6
6
|
- 'v*'
|
|
7
|
+
- 'wecom-v*'
|
|
7
8
|
|
|
8
9
|
jobs:
|
|
9
10
|
publish:
|
|
@@ -34,6 +35,51 @@ jobs:
|
|
|
34
35
|
run: |
|
|
35
36
|
npm i -g npm@^11.5.1
|
|
36
37
|
npm -v
|
|
38
|
+
npm config delete always-auth || true
|
|
39
|
+
|
|
40
|
+
- name: Resolve release metadata
|
|
41
|
+
id: meta
|
|
42
|
+
run: |
|
|
43
|
+
set -euo pipefail
|
|
44
|
+
TAG="${GITHUB_REF_NAME}"
|
|
45
|
+
if [[ "${TAG}" == wecom-v* ]]; then
|
|
46
|
+
VERSION="${TAG#wecom-v}"
|
|
47
|
+
elif [[ "${TAG}" == v* ]]; then
|
|
48
|
+
VERSION="${TAG#v}"
|
|
49
|
+
else
|
|
50
|
+
echo "::error::Unsupported tag format: ${TAG}. Use v<version> or wecom-v<version>."
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
PKG_NAME="$(node -p "require('./package.json').name")"
|
|
54
|
+
PKG_VERSION="$(node -p "require('./package.json').version")"
|
|
55
|
+
|
|
56
|
+
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
|
|
57
|
+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
58
|
+
echo "pkg_name=${PKG_NAME}" >> "$GITHUB_OUTPUT"
|
|
59
|
+
echo "pkg_version=${PKG_VERSION}" >> "$GITHUB_OUTPUT"
|
|
60
|
+
|
|
61
|
+
echo "tag=${TAG}"
|
|
62
|
+
echo "version_from_tag=${VERSION}"
|
|
63
|
+
echo "package=${PKG_NAME}@${PKG_VERSION}"
|
|
64
|
+
|
|
65
|
+
if [ "${VERSION}" != "${PKG_VERSION}" ]; then
|
|
66
|
+
echo "::error::Tag version (${VERSION}) does not match package.json version (${PKG_VERSION})."
|
|
67
|
+
exit 1
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
- name: Check npm version already published
|
|
71
|
+
id: npm_check
|
|
72
|
+
run: |
|
|
73
|
+
set -euo pipefail
|
|
74
|
+
PKG="${{ steps.meta.outputs.pkg_name }}"
|
|
75
|
+
VER="${{ steps.meta.outputs.pkg_version }}"
|
|
76
|
+
if npm view "${PKG}@${VER}" version >/dev/null 2>&1; then
|
|
77
|
+
echo "exists=true" >> "$GITHUB_OUTPUT"
|
|
78
|
+
echo "npm version already published: ${PKG}@${VER}"
|
|
79
|
+
else
|
|
80
|
+
echo "exists=false" >> "$GITHUB_OUTPUT"
|
|
81
|
+
echo "npm version not published yet: ${PKG}@${VER}"
|
|
82
|
+
fi
|
|
37
83
|
|
|
38
84
|
- name: Install Dependencies
|
|
39
85
|
run: npm install --legacy-peer-deps || npm install
|
|
@@ -43,13 +89,35 @@ jobs:
|
|
|
43
89
|
|
|
44
90
|
# 🚀 自动发布到 npm (使用 OIDC 自动授权,无需 Token)
|
|
45
91
|
- name: Publish to npm
|
|
92
|
+
if: steps.npm_check.outputs.exists != 'true'
|
|
46
93
|
run: npm publish --access public
|
|
47
94
|
|
|
95
|
+
- name: Prepare release notes body
|
|
96
|
+
id: notes
|
|
97
|
+
run: |
|
|
98
|
+
set -euo pipefail
|
|
99
|
+
CHANGELOG_FILE="changelog/v${{ steps.meta.outputs.version }}.md"
|
|
100
|
+
if [ -f "${CHANGELOG_FILE}" ]; then
|
|
101
|
+
echo "Using changelog file: ${CHANGELOG_FILE}"
|
|
102
|
+
cp "${CHANGELOG_FILE}" /tmp/release-body.md
|
|
103
|
+
else
|
|
104
|
+
echo "Changelog file missing: ${CHANGELOG_FILE}; using fallback notes."
|
|
105
|
+
{
|
|
106
|
+
echo "# @yanhaidao/wecom v${{ steps.meta.outputs.version }}"
|
|
107
|
+
echo
|
|
108
|
+
if [ "${{ steps.npm_check.outputs.exists }}" = "true" ]; then
|
|
109
|
+
echo "- npm publish skipped: version already exists."
|
|
110
|
+
else
|
|
111
|
+
echo "- npm publish completed."
|
|
112
|
+
fi
|
|
113
|
+
} > /tmp/release-body.md
|
|
114
|
+
fi
|
|
115
|
+
|
|
48
116
|
# 自动同步发布 GitHub Release
|
|
49
117
|
- name: Create GitHub Release
|
|
50
118
|
uses: softprops/action-gh-release@v2
|
|
51
119
|
with:
|
|
52
|
-
body_path:
|
|
120
|
+
body_path: /tmp/release-body.md
|
|
53
121
|
draft: false
|
|
54
122
|
prerelease: false
|
|
55
123
|
env:
|
package/README.md
CHANGED
|
@@ -502,6 +502,8 @@ Agent 输出 `{"template_card": ...}` 时自动渲染为交互卡片:
|
|
|
502
502
|
|
|
503
503
|
### 2026.3.3(今日更新简报)
|
|
504
504
|
|
|
505
|
+
- 【SDK适配】♻️ **插件 HTTP 注册升级**:入口改为 `registerHttpRoute`(`/plugins/wecom` + `match=prefix` + `auth=plugin`),适配 OpenClaw 新版插件接口。
|
|
506
|
+
- 【兼容修复】🔁 **旧入口保持可达**:同步注册 `/wecom` 前缀路由,保障历史 Bot/Agent 回调地址继续可用。
|
|
505
507
|
- 【兼容性修复】🧩 **OpenClaw 3.1 路由抢占问题修复**:推荐回调地址升级为 `/plugins/wecom/bot/{accountId}`、`/plugins/wecom/agent/{accountId}`,规避根路径 Control UI fallback 抢占 webhook。
|
|
506
508
|
- 【引导收敛】🧭 **Onboarding 仅支持账号化配置**:配置向导统一写入 `channels.wecom.accounts.<accountId>`,不再引导单账号旧结构。
|
|
507
509
|
- 【兼容策略】🔁 **旧路径兼容保留**:`/wecom/*` 历史回调路径保留兼容能力,但不再作为维护主路径。
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# OpenClaw WeCom 插件 v2.3.4 变更简报
|
|
2
|
+
|
|
3
|
+
> [!WARNING]
|
|
4
|
+
> **可用性热修复版本**:`v2.3.4` 重点修复 OpenClaw 3.1+ 下 WeCom webhook 路由兼容与可达性问题,保障历史配置可继续使用。
|
|
5
|
+
|
|
6
|
+
## 2026-03-03(v2.3.4 热修复)
|
|
7
|
+
- 【SDK适配】♻️ 插件入口从 `registerHttpHandler` 迁移为 `registerHttpRoute`(`/plugins/wecom` + `match=prefix` + `auth=plugin`),兼容 OpenClaw 新版插件 HTTP 注册模型。
|
|
8
|
+
- 【兼容修复】🔁 补回旧路径入口注册:新增 `/wecom` 前缀路由注册,确保历史 Bot/Agent webhook 继续可达。
|
|
9
|
+
- 【模式兼容】🧭 保持 legacy 单账号配置可运行,并明确 matrix 模式必须使用带 `accountId` 的回调路径。
|
|
10
|
+
|
|
11
|
+
## 影响说明
|
|
12
|
+
- WeCom Bot/Agent 业务链路保持兼容;核心变化为插件 HTTP 注册 API 的升级适配与旧路径可达性恢复。
|
|
13
|
+
|
|
14
|
+
## 兼容矩阵(单账号/多账号)
|
|
15
|
+
| 场景 | 配置形态 | 回调地址 | 兼容状态 | 说明 |
|
|
16
|
+
|---|---|---|---|---|
|
|
17
|
+
| 历史单账号(legacy) | `channels.wecom.bot/agent` | Bot: `/wecom`(默认)或 `/wecom/bot`;Agent: `/wecom/agent` | ✅ 兼容保留 | 适用于存量部署,不作为新引导方案。 |
|
|
18
|
+
| 多账号(matrix)错误用法 | `channels.wecom.accounts.*` | `/wecom/bot`、`/wecom/agent`(无 accountId) | ❌ 不可用 | 会返回 `wecom_matrix_path_required`。 |
|
|
19
|
+
| 多账号(matrix)兼容路径 | `channels.wecom.accounts.*` | `/wecom/bot/{accountId}`、`/wecom/agent/{accountId}` | ✅ 兼容保留 | 历史路径可用,但不再维护。 |
|
|
20
|
+
| 多账号(matrix)推荐路径 | `channels.wecom.accounts.*` | `/plugins/wecom/bot/{accountId}`、`/plugins/wecom/agent/{accountId}` | ✅ 推荐 | 当前主维护路径。 |
|
package/compat-single-account.md
CHANGED
package/index.test.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
3
|
+
import plugin from "./index.js";
|
|
4
|
+
|
|
5
|
+
describe("wecom plugin register", () => {
|
|
6
|
+
it("registers both recommended and legacy webhook route prefixes", () => {
|
|
7
|
+
const registerChannel = vi.fn();
|
|
8
|
+
const registerHttpRoute = vi.fn();
|
|
9
|
+
const api = {
|
|
10
|
+
runtime: {},
|
|
11
|
+
registerChannel,
|
|
12
|
+
registerHttpRoute,
|
|
13
|
+
} as unknown as OpenClawPluginApi;
|
|
14
|
+
|
|
15
|
+
plugin.register(api);
|
|
16
|
+
|
|
17
|
+
expect(registerChannel).toHaveBeenCalledTimes(1);
|
|
18
|
+
expect(registerHttpRoute).toHaveBeenCalledTimes(2);
|
|
19
|
+
expect(registerHttpRoute).toHaveBeenCalledWith(
|
|
20
|
+
expect.objectContaining({
|
|
21
|
+
path: "/plugins/wecom",
|
|
22
|
+
auth: "plugin",
|
|
23
|
+
match: "prefix",
|
|
24
|
+
}),
|
|
25
|
+
);
|
|
26
|
+
expect(registerHttpRoute).toHaveBeenCalledWith(
|
|
27
|
+
expect.objectContaining({
|
|
28
|
+
path: "/wecom",
|
|
29
|
+
auth: "plugin",
|
|
30
|
+
match: "prefix",
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
});
|
package/index.ts
CHANGED
|
@@ -15,16 +15,24 @@ const plugin = {
|
|
|
15
15
|
configSchema: emptyPluginConfigSchema(),
|
|
16
16
|
/**
|
|
17
17
|
* **register (注册插件)**
|
|
18
|
-
*
|
|
18
|
+
*
|
|
19
19
|
* OpenClaw 插件入口点。
|
|
20
20
|
* 1. 注入 Runtime 环境 (api.runtime)。
|
|
21
21
|
* 2. 注册 WeCom 渠道插件 (ChannelPlugin)。
|
|
22
|
-
* 3. 注册 Webhook HTTP
|
|
22
|
+
* 3. 注册 Webhook HTTP 路由(推荐 /plugins/wecom/*,兼容 /wecom*)。
|
|
23
23
|
*/
|
|
24
24
|
register(api: OpenClawPluginApi) {
|
|
25
25
|
setWecomRuntime(api.runtime);
|
|
26
26
|
api.registerChannel({ plugin: wecomPlugin });
|
|
27
|
-
|
|
27
|
+
const routes = ["/plugins/wecom", "/wecom"];
|
|
28
|
+
for (const path of routes) {
|
|
29
|
+
api.registerHttpRoute({
|
|
30
|
+
path,
|
|
31
|
+
handler: handleWecomWebhookRequest,
|
|
32
|
+
auth: "plugin",
|
|
33
|
+
match: "prefix",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
28
36
|
},
|
|
29
37
|
};
|
|
30
38
|
|
package/package.json
CHANGED
package/src/types/constants.ts
CHANGED
|
@@ -10,9 +10,9 @@ export const WEBHOOK_PATHS = {
|
|
|
10
10
|
BOT_ALT: "/wecom/bot",
|
|
11
11
|
/** Agent 模式历史兼容路径(不再维护) */
|
|
12
12
|
AGENT: "/wecom/agent",
|
|
13
|
-
/** Bot
|
|
13
|
+
/** Bot 模式推荐路径前缀 */
|
|
14
14
|
BOT_PLUGIN: "/plugins/wecom/bot",
|
|
15
|
-
/** Agent
|
|
15
|
+
/** Agent 模式推荐路径前缀 */
|
|
16
16
|
AGENT_PLUGIN: "/plugins/wecom/agent",
|
|
17
17
|
} as const;
|
|
18
18
|
|