← Back to Plugins
Voice

Wecom App Connector

Tern-xt By Tern-xt 👁 52 views ▲ 0 votes

OpenClaw Channel Plugin for WeCom custom applications with encrypted callbacks and text messaging.

GitHub

Configuration Example

channels:
  wecom:
    enabled: true
    corpId: "acme-demo-corp-id"
    agentId: "1000001"
    secret: "replace-with-secret-storage"
    token: "replace-with-callback-token"
    encodingAesKey: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi12345678"
    callbackPath: "/wecom/default/callback"
    replayWindowSeconds: 300
    maxInputLength: 4096
    maxBodyBytes: 1048576
    requestTimeoutMs: 5000
    dmPolicy: "open"
    allowFrom:
      - "demo-user"

README

# openclaw-wecom-app-connector

通过企业微信官方支持的自建应用接口,将企业微信文本私聊接入 OpenClaw Agent。

```text
企业微信自建应用
  → 加密回调
  → OpenClaw Channel Plugin
  → Agent 会话
  → 企业微信应用消息回复
```

项目采用 clean-room 方式独立实现,不依赖任何特定组织的私有代码、账号或基础设施。

> **项目状态:Local MVP / Experimental**
>
> 已完成本地 Mock 自动化测试,但尚未完成真实 OpenClaw Gateway、HTTPS 反向代理和企业微信凭证的端到端验证。当前版本不承诺生产级可靠性,建议先在测试环境中仅向单个测试成员开放。

## 适用场景

适合以下场景:

- 已有企业微信组织,并可创建自建应用。
- 希望通过企业微信私聊使用 OpenClaw Agent。
- 可以提供企业微信公网可访问的 HTTPS 回调地址。
- 接受先在测试环境验证的 Local MVP。

暂不适合以下场景:

- 企业微信群聊机器人。
- 图片、语音、视频或文件消息。
- Markdown、模板卡片、`@all` 或多收件人群发。
- 要求开箱即用、具备持久化投递保证的生产系统。

## 兼容性

- OpenClaw:`>=2026.7.1-2 <2027`
- Node.js:以 [`package.json`](./package.json) 的 `engines.node` 为准
- 企业微信:企业内部自建应用

如果实际 OpenClaw SDK 或 Manifest 契约与本仓库声明的版本不一致,请停止安装并提交 Issue,不要猜测修改宿主配置。

## 已实现能力

- GET 回调 URL 验证
- POST 加密消息回调
- 企业微信 SHA-1 消息签名校验
- AES-256-CBC 与严格 PKCS#7-32 解密
- XML 长度与 ReceiveID / CorpID 校验
- 回调时间窗口与 Body 大小限制
- 外层 XML DTD / ENTITY 防护
- 文本私聊解析与非文本消息忽略
- OpenClaw Core Session 路由
- 基于 `accountId` 的账号隔离
- 消息 ID 内存 TTL 去重与容量上限
- `access_token` 缓存、single-flight 与提前刷新
- Token 错误 `40014` / `42001` 的单次刷新重试
- 企业微信应用文本消息回复
- `@all`、多收件人和控制字符拒绝
- 普通 DM 与 OpenClaw 命令权限分离
- 默认不授权 OpenClaw 控制命令
- 不记录 Token、消息正文或 UserID 的错误日志边界

## 尚未实现

- 群聊
- 图片、语音、视频和文件
- Markdown 和模板卡片
- 通讯录查询
- 主动群发、`@all` 和多收件人
- 持久化消息队列与 durable ingress
- completion tombstone
- 生产部署模板与完整可观测性
- 真实 OpenClaw Gateway、HTTPS 代理和企业微信凭证验证

## 前置条件

开始前需要准备:

1. 兼容版本的 OpenClaw 和 Node.js。
2. 企业微信组织及自建应用管理权限。
3. 公网可访问的 HTTPS 域名或 Gateway。
4. 自己的 `CorpID`、`AgentID`、应用 `Secret`、回调 `Token` 和 `EncodingAESKey`。
5. 一个仅用于首次验证的测试成员账号。

所有凭证都必须由使用者在自己的企业微信后台创建。本仓库不提供、也不依赖任何现成凭证。

## 本地构建与测试

```sh
git clone https://github.com/Tern-xt/openclaw-wecom-app-connector.git
cd openclaw-wecom-app-connector

npm ci
npm run build
npm run check
npm test
npm run lint
npm run markdownlint
npm pack --dry-run
```

构建成功后应存在:

```text
dist/index.js
```

`npm pack --dry-run` 的结果也应包含 `dist/index.js`。

## OpenClaw 安装状态

源码和包入口已经按照 `[email protected]` SDK 实现,但真实 Gateway 的安装、启用和重启流程尚未完成端到端验证。

请先根据自己安装的 OpenClaw 版本核对插件安装方式。不要把未经验证的命令直接用于生产 Gateway,也不要覆盖已有 Channel 配置。

完成第一次真实 Gateway 验证后,本节会补充经过验证的安装和回滚步骤。

## 配置字段

实际字段以 [`openclaw.plugin.json`](./openclaw.plugin.json) 和 [`src/config.ts`](./src/config.ts) 为准。

```yaml
channels:
  wecom:
    enabled: true
    corpId: "acme-demo-corp-id"
    agentId: "1000001"
    secret: "replace-with-secret-storage"
    token: "replace-with-callback-token"
    encodingAesKey: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi12345678"
    callbackPath: "/wecom/default/callback"
    replayWindowSeconds: 300
    maxInputLength: 4096
    maxBodyBytes: 1048576
    requestTimeoutMs: 5000
    dmPolicy: "open"
    allowFrom:
      - "demo-user"
```

以上仅为结构示例,不是可直接使用的真实配置。配置真实存放位置和 Secret 引用语法应以当前 OpenClaw Gateway 文档为准。

### 关键字段

| 字段 | 说明 |
|---|---|
| `corpId` | 企业 ID |
| `agentId` | 自建应用 AgentID |
| `secret` | 自建应用 Secret |
| `token` | 接收消息回调 Token |
| `encodingAesKey` | 43 字符回调 EncodingAESKey |
| `callbackPath` | 插件注册的 HTTP 回调路径 |
| `replayWindowSeconds` | 回调时间窗口 |
| `maxInputLength` | 文本输入长度上限 |
| `maxBodyBytes` | HTTP Body 字节上限 |
| `requestTimeoutMs` | 企业微信 API 请求超时 |
| `allowFrom` | 允许执行命令的企业微信 UserID 列表 |
| `dmPolicy` | OpenClaw DM 访问策略 |

`.env.example` 只用于展示需要准备的字段,插件不会自动读取 `.env`。

### 凭证安全

- 不要把真实凭证提交到 Git。
- 不要在 GitHub Issue 中粘贴凭证、完整日志或真实消息。
- 不要把 Secret、Token 或 EncodingAESKey 发进普通 AI 对话。
- 优先使用 OpenClaw 支持的 Secret 配置机制。
- 修改 Gateway 配置前先创建备份。

## 企业微信后台配置

完整步骤见 [`docs/WECOM_SETUP.md`](./docs/WECOM_SETUP.md)。流程概览:

1. 创建企业微信自建应用。
2. 获取 CorpID、AgentID 和应用 Secret。
3. 将应用可见范围限制为测试成员。
4. 配置“接收消息”所需的 Token 和 EncodingAESKey。
5. 配置企业微信可公网访问的 HTTPS 回调 URL。
6. 先完成 GET URL 验证。
7. 再由单个测试成员发送文本消息。
8. 检查 Gateway、插件和反向代理日志是否已脱敏。

示例回调地址:

```text
https://example.com/wecom/default/callback
```

回调必须使用 HTTPS,`callbackPath` 必须与插件配置一致。反向代理不得修改 Query 参数或原始 POST Body。

## 权限与安全建议

- 首次验证只开放一个测试成员。
- 使用 `allowFrom` 限制可以执行命令的成员。
- 未配置 `allowFrom` 时,OpenClaw 控制命令默认未授权。
- 普通 DM 是否允许与命令权限是两个不同问题。
- 默认拒绝 `@all`、逗号或竖线分隔的多收件人。
- 定期轮换 Secret、Token 和 EncodingAESKey。
- 日志中不得记录 Token、UserID 或消息正文。

更多说明见 [`docs/SECURITY.md`](./docs/SECURITY.md)。

## 验证清单

### 仓库内已验证

- [x] `npm test` 全部通过
- [x] `dist/index.js` 可生成
- [x] `npm pack` 包含 `dist/index.js`
- [x] PKCS#7-32 边界测试通过
- [x] 多收件人和 `@all` 拒绝测试通过
- [x] 默认命令未授权测试通过
- [x] Mock 测试不调用真实企业微信 API

### 使用者环境待验证

- [ ] OpenClaw 版本兼容
- [ ] OpenClaw Gateway 成功加载插件
- [ ] HTTPS 反向代理工作正常
- [ ] 企业微信 GET 回调验证成功
- [ ] POST 回调返回 `success`
- [ ] OpenClaw 收到文本消息
- [ ] 回复只发送给原始 UserID
- [ ] 未授权命令被拒绝
- [ ] 日志没有凭证和消息正文

## Troubleshooting

| 现象 | 建议检查 |
|---|---|
| 回调 URL 验证失败 | Token、EncodingAESKey、CorpID、时间戳和 URL 编码 |
| 返回 `invalid callback` | 签名、时间窗口、外层 XML、Body 大小和 CorpID |
| `corpId mismatch` | 解密尾部 ReceiveID 是否与当前账号 CorpID 一致 |
| `invalid ciphertext padding` | EncodingAESKey、密文完整性和 PKCS#7-32 |
| 能接收但不能回复 | Secret、AgentID、应用可见范围和 access_token |
| 企业微信返回 `40014` / `42001` | Token 失效、系统时间和凭证配置 |
| OpenClaw 无法加载插件 | OpenClaw 版本、构建结果和 `dist/index.js` |
| 消息重复 | 企业微信重试或当前进程内存去重状态已丢失 |
| 重启后重复处理 | 当前去重仅保存在进程内存中 |
| 命令被拒绝 | `allowFrom`、`dmPolicy` 和发送者 UserID |
| 多账号路由注册失败 | 检查 `accountId` 和 `callbackPath` 是否冲突 |

排查时请先脱敏。Issue 中不要提交真实凭证、UserID、域名、IP 或完整日志。

## 可靠性边界

消息去重状态仅保存在当前进程内存中。进程重启会丢失去重记录。

回调在协议校验和去重后先返回 ACK,再异步执行 Agent turn。如果进程在 ACK 后、回复完成前崩溃,该消息可能丢失。当前没有持久化队列、durable ingress 或 completion tombstone,因此不是 Production Ready。

详见 [`docs/LIMITATIONS.md`](./docs/LIMITATIONS.md)。

## 让 OpenClaw Agent 协助安装

可以将下面的提示词和仓库地址交给具备本机文件、Shell 和配置权限的 OpenClaw Agent:

```text
请协助我评估并安装这个企业微信 Channel Plugin:
https://github.com/Tern-xt/openclaw-wecom-app-connector

先阅读 README、package.json、openclaw.plugin.json 和 docs。
检查当前 OpenClaw、Node.js、Gateway、HTTPS 和反向代理条件。
先输出安装计划、配置位置、备份和回滚方法,不要立即修改配置或重启 Gateway。
不要要求我把 Secret、Token 或 EncodingAESKey 粘贴到普通聊天中;使用 OpenClaw 支持的 Secret 配置机制。
不要覆盖其他 Channel。先验证 GET 回调,再使用单个测试成员验证 POST 文本消息。
如果实际 SDK 与仓库声明的兼容范围不一致,立即停止并说明差异,不要猜测适配。
当前项目是 Local MVP,不要将其描述为已完成生产验证。
```

Agent 必须具备相应权限才能执行安装;仅发送仓库地址不会自动获得企业微信后台、HTTPS 域名或 Gateway 管理权限。

## 架构与开发文档

- [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md)
- [`docs/WECOM_SETUP.md`](./docs/WECOM_SETUP.md)
- [`docs/SECURITY.md`](./docs/SECURITY.md)
- [`docs/LIMITATIONS.md`](./docs/LIMITATIONS.md)

## 贡献与 Issue

欢迎提交 Issue、兼容性反馈和改进建议。

提交 Issue 前请删除:

- Secret、Token 和 EncodingAESKey
- 真实消息正文和 UserID
- 内部域名、IP 和服务器路径
- 未脱敏的完整日志

## License

[MIT](./LICENSE) · Copyright (c) 2026 Tern
voice

Comments

Sign in to leave a comment

Loading comments...