@gloablehive/celphone-wechat-plugin 1.0.0

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.
Files changed (45) hide show
  1. package/INSTALL.md +231 -0
  2. package/README.md +259 -0
  3. package/dist/index-simple.js +9 -0
  4. package/dist/index.d.ts +16 -0
  5. package/dist/index.js +77 -0
  6. package/dist/mock-server.d.ts +6 -0
  7. package/dist/mock-server.js +203 -0
  8. package/dist/openclaw.plugin.json +96 -0
  9. package/dist/setup-entry.d.ts +9 -0
  10. package/dist/setup-entry.js +8 -0
  11. package/dist/src/cache/compactor.d.ts +36 -0
  12. package/dist/src/cache/compactor.js +154 -0
  13. package/dist/src/cache/extractor.d.ts +48 -0
  14. package/dist/src/cache/extractor.js +120 -0
  15. package/dist/src/cache/index.d.ts +15 -0
  16. package/dist/src/cache/index.js +16 -0
  17. package/dist/src/cache/indexer.d.ts +41 -0
  18. package/dist/src/cache/indexer.js +262 -0
  19. package/dist/src/cache/manager.d.ts +113 -0
  20. package/dist/src/cache/manager.js +271 -0
  21. package/dist/src/cache/message-queue.d.ts +59 -0
  22. package/dist/src/cache/message-queue.js +147 -0
  23. package/dist/src/cache/saas-connector.d.ts +94 -0
  24. package/dist/src/cache/saas-connector.js +289 -0
  25. package/dist/src/cache/syncer.d.ts +60 -0
  26. package/dist/src/cache/syncer.js +177 -0
  27. package/dist/src/cache/types.d.ts +198 -0
  28. package/dist/src/cache/types.js +43 -0
  29. package/dist/src/cache/writer.d.ts +81 -0
  30. package/dist/src/cache/writer.js +461 -0
  31. package/dist/src/channel.d.ts +65 -0
  32. package/dist/src/channel.js +334 -0
  33. package/dist/src/client.d.ts +280 -0
  34. package/dist/src/client.js +248 -0
  35. package/index-simple.ts +11 -0
  36. package/index.ts +89 -0
  37. package/mock-server.ts +237 -0
  38. package/openclaw.plugin.json +98 -0
  39. package/package.json +37 -0
  40. package/setup-entry.ts +10 -0
  41. package/src/channel.ts +398 -0
  42. package/src/client.ts +412 -0
  43. package/test-cache.ts +260 -0
  44. package/test-integration.ts +319 -0
  45. package/tsconfig.json +22 -0
package/INSTALL.md ADDED
@@ -0,0 +1,231 @@
1
+ # WorkPhone WeChat 插件安装指南
2
+
3
+ > 本指南详细介绍如何将 WorkPhone WeChat 通道插件安装到 OpenClaw 系统。
4
+
5
+ ## 前置要求
6
+
7
+ ### 系统要求
8
+
9
+ | 组件 | 要求 |
10
+ |------|------|
11
+ | Node.js | ≥ 18.0.0 |
12
+ | pnpm | ≥ 8.0.0 |
13
+ | OpenClaw | ≥ 1.0.0 |
14
+
15
+ ### 账号要求
16
+
17
+ - ✅ WorkPhone 商业账号(需开通 WeChat API 权限)
18
+ - ✅ WorkPhone API Key
19
+ - ✅ 微信号已绑定到 WorkPhone
20
+
21
+ ## 安装步骤
22
+
23
+ ### 步骤 1:获取插件
24
+
25
+ ```bash
26
+ # 方式 A:从本地目录安装(开发时)
27
+ cd /path/to/openclaw
28
+ pnpm add ./channels/celphone-wechat-plugin
29
+
30
+ # 方式 B:从 npm 安装(生产环境)
31
+ pnpm add @gloablehive/celphone-wechat-plugin
32
+ ```
33
+
34
+ ### 步骤 2:配置 OpenClaw
35
+
36
+ 编辑 OpenClaw 配置文件(通常是 `openclaw.json` 或 `.env`):
37
+
38
+ ```json
39
+ {
40
+ "channels": {
41
+ "celphone-wechat": {
42
+ "apiKey": "your-workphone-api-key",
43
+ "baseUrl": "https://api.workphone.example.com",
44
+ "wechatAccountId": "wp-wechat-001",
45
+ "wechatId": "wxid_xxxxx",
46
+ "nickName": "客服小微",
47
+ "accountId": "wechat-service-001",
48
+ "allowFrom": [],
49
+ "dmSecurity": "allowlist"
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ #### 配置参数说明
56
+
57
+ | 参数 | 必填 | 说明 |
58
+ |------|------|------|
59
+ | `apiKey` | ✅ | WorkPhone API 密钥 |
60
+ | `wechatAccountId` | ✅ | WorkPhone 中的 WeChat 账号 ID |
61
+ | `baseUrl` | - | WorkPhone API 地址(默认提供) |
62
+ | `wechatId` | - | 微信实际 ID(wxid_xxx) |
63
+ | `nickName` | - | 显示名称 |
64
+ | `accountId` | - | 内部账号标识(用于 bindings 路由) |
65
+ | `allowFrom` | - | 白名单:允许接收消息的微信 ID |
66
+ | `dmSecurity` | - | 安全策略:`allowlist`/`blocklist`/`allowall` |
67
+
68
+ ### 步骤 3:配置消息路由(bindings)
69
+
70
+ 在 `openclaw.json` 中添加 bindings 配置,将消息路由到对应的 Agent:
71
+
72
+ ```json5
73
+ {
74
+ "bindings": [
75
+ {
76
+ "agentId": "service-frontdesk",
77
+ "match": {
78
+ "channel": "celphone-wechat",
79
+ "accountId": "wechat-service-001"
80
+ }
81
+ }
82
+ ]
83
+ }
84
+ ```
85
+
86
+ ### 步骤 4:配置 Webhook
87
+
88
+ 你需要配置 WorkPhone 将消息推送到你的 OpenClaw 实例:
89
+
90
+ ```
91
+ Webhook URL: https://your-openclaw-instance.com/celphone-wechat/webhook
92
+ ```
93
+
94
+ **如果使用 ngrok 本地开发:**
95
+
96
+ ```bash
97
+ # 启动 ngrok 隧道
98
+ ngrok http 3000
99
+
100
+ # 将得到的 URL 配置到 WorkPhone 后台
101
+ # 例如:https://abc123.ngrok.io/celphone-wechat/webhook
102
+ ```
103
+
104
+ ### 步骤 5:验证安装
105
+
106
+ ```bash
107
+ # 启动 OpenClaw
108
+ pnpm run dev
109
+
110
+ # 检查日志中是否有以下输出:
111
+ # [Channel] celphone-wechat initialized
112
+ # [Webhook] Listening on /celphone-wechat/webhook
113
+ ```
114
+
115
+ 发送测试消息到微信号,确认消息能到达 OpenClaw。
116
+
117
+ ## 多微信号配置
118
+
119
+ 如果你需要管理多个微信号:
120
+
121
+ ```json
122
+ {
123
+ "channels": {
124
+ "celphone-wechat": {
125
+ "accounts": [
126
+ {
127
+ "accountId": "wechat-service-001",
128
+ "wechatAccountId": "wp-wechat-001",
129
+ "wechatId": "wxid_cs001",
130
+ "nickName": "客服小微"
131
+ },
132
+ {
133
+ "accountId": "wechat-service-002",
134
+ "wechatAccountId": "wp-wechat-002",
135
+ "wechatId": "wxid_sales01",
136
+ "nickName": "销售小王"
137
+ }
138
+ ]
139
+ }
140
+ },
141
+ "bindings": [
142
+ {
143
+ "agentId": "service-frontdesk",
144
+ "match": {
145
+ "channel": "celphone-wechat",
146
+ "accountId": "wechat-service-001"
147
+ }
148
+ },
149
+ {
150
+ "agentId": "service-sales",
151
+ "match": {
152
+ "channel": "celphone-wechat",
153
+ "accountId": "wechat-service-002"
154
+ }
155
+ }
156
+ ]
157
+ }
158
+ ```
159
+
160
+ ## 本地开发
161
+
162
+ ```bash
163
+ # 进入插件目录
164
+ cd channels/celphone-wechat-plugin
165
+
166
+ # 安装依赖
167
+ pnpm install
168
+
169
+ # 运行测试
170
+ pnpm test
171
+
172
+ # 构建
173
+ pnpm build
174
+ ```
175
+
176
+ ## 常见问题
177
+
178
+ ### Q: 消息收不到?
179
+
180
+ 1. 检查 Webhook URL 是否正确配置
181
+ 2. 检查 `dmSecurity` 设置是否正确
182
+ 3. 检查日志输出 `allowFrom` 列表
183
+
184
+ ### Q: 发送消息失败?
185
+
186
+ 1. 确认 API Key 权限
187
+ 2. 检查 wechatAccountId 是否正确
188
+ 3. 查看错误日志
189
+
190
+ ### Q: 如何开启安全模式?
191
+
192
+ ```json
193
+ {
194
+ "dmSecurity": "allowlist",
195
+ "allowFrom": [
196
+ "wxid_customer001",
197
+ "wxid_customer002"
198
+ ]
199
+ }
200
+ ```
201
+
202
+ ## 目录结构
203
+
204
+ ```
205
+ celphone-wechat-plugin/
206
+ ├── package.json # 插件清单
207
+ ├── openclaw.plugin.json # 插件配置
208
+ ├── index.ts # 入口
209
+ ├── setup-entry.ts # 轻量入口
210
+ ├── src/
211
+ │ ├── channel.ts # 通道实现
212
+ │ ├── client.ts # API 客户端
213
+ │ └── cache/ # 本地缓存
214
+ │ ├── manager.ts
215
+ │ ├── writer.ts
216
+ │ ├── indexer.ts
217
+ │ ├── extractor.ts
218
+ │ ├── compactor.ts
219
+ │ ├── syncer.ts
220
+ │ ├── saas-connector.ts
221
+ │ └── message-queue.ts
222
+ ├── test-cache.ts # 单元测试
223
+ └── test-integration.ts # 集成测试
224
+ ```
225
+
226
+ ## 相关文档
227
+
228
+ - [README](./README.md) - 完整功能说明
229
+ - [API 手册](../../data/apifox-workphone-3/handbooks/apifox-workphone-api-manual.md)
230
+ - [缓存设计](./doc/spec/celphone-wechat-cache.md)
231
+ - [Harness 工程规范](../../harness/AGENTS.md)
package/README.md ADDED
@@ -0,0 +1,259 @@
1
+ # WorkPhone WeChat Channel Plugin
2
+
3
+ OpenClaw channel plugin for connecting to WorkPhone's WeChat API. Enables sending and receiving WeChat messages through the WorkPhone platform.
4
+
5
+ ## ⚠️ Important: Human Account Model
6
+
7
+ Unlike Telegram/WhatsApp bots, this channel connects to a **real human WeChat account**:
8
+
9
+ - **Bot Mode** (Telegram/WhatsApp): One bot account → communicates with many users
10
+ - **Human Mode** (This plugin): One real WeChat account → Agent manages ALL their friends and groups
11
+
12
+ The agent needs to handle conversations with:
13
+ - All friends (1-on-1 DM)
14
+ - All group chats (chatrooms)
15
+ - Friend requests
16
+ - Moments interactions
17
+
18
+ ## Features
19
+
20
+ - **Send/Receive Messages**: Send text, media, links, and more to WeChat friends and groups
21
+ - **Friend Management**: Get friend list, update remarks, manage labels
22
+ - **Group Chat**: Send messages to WeChat chatrooms (groups)
23
+ - **Moments (朋友圈)**: Read and post to WeChat Moments
24
+ - **Webhook Integration**: Receive real-time message callbacks from WorkPhone
25
+
26
+ ## Requirements
27
+
28
+ - OpenClaw instance
29
+ - WorkPhone account with WeChat API access
30
+ - WorkPhone API key
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ # If using as a local plugin
36
+ pnpm add ./channels/celphone-wechat-plugin
37
+
38
+ # Or link from your plugin registry
39
+ pnpm add @gloablehive/celphone-wechat-plugin
40
+ ```
41
+
42
+ ## Configuration
43
+
44
+ Add to your OpenClaw config:
45
+
46
+ ```json
47
+ {
48
+ "channels": {
49
+ "celphone-wechat": {
50
+ "apiKey": "your-workphone-api-key",
51
+ "baseUrl": "https://api.workphone.example.com",
52
+ "accountId": "your-workphone-account-id",
53
+ "wechatAccountId": "workphone-wechat-account-id", // REQUIRED
54
+ "wechatId": "wxid_xxxxx", // Actual WeChat ID
55
+ "nickName": "My WeChat",
56
+ "allowFrom": ["friend-wxid-1", "friend-wxid-2"],
57
+ "dmSecurity": "allowlist"
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### Configuration Options
64
+
65
+ | Option | Type | Required | Description |
66
+ |--------|------|----------|-------------|
67
+ | `apiKey` | string | Yes | WorkPhone API key for authentication |
68
+ | `wechatAccountId` | string | Yes | WeChat account ID from WorkPhone |
69
+ | `baseUrl` | string | No | WorkPhone API base URL (default: provided by WorkPhone) |
70
+ | `accountId` | string | No | WorkPhone account ID |
71
+ | `wechatId` | string | No | Actual WeChat ID (wxid_xxx) |
72
+ | `nickName` | string | No | Display name for this account |
73
+ | `allowFrom` | string[] | No | WeChat IDs that can DM the agent |
74
+ | `dmSecurity` | string | No | Policy: `allowlist`, `blocklist`, or `allowall` |
75
+ | `webhookSecret` | string | No | Secret for webhook signature verification |
76
+
77
+ ## OpenClaw Configuration (bindings)
78
+
79
+ To route WeChat messages to the correct agent, configure in `openclaw.json`:
80
+
81
+ ```json5
82
+ {
83
+ // ... other config ...
84
+
85
+ bindings: [
86
+ // Internal management agents
87
+ {
88
+ agentId: "merchant-setup",
89
+ match: {
90
+ channel: "celphone-wechat",
91
+ accountId: "wechat-admin-001",
92
+ },
93
+ },
94
+ {
95
+ agentId: "merchant-ops",
96
+ match: {
97
+ channel: "celphone-wechat",
98
+ accountId: "wechat-ops-001",
99
+ },
100
+ },
101
+
102
+ // Service agents (customer-facing)
103
+ {
104
+ agentId: "service-frontdesk",
105
+ match: {
106
+ channel: "celphone-wechat",
107
+ accountId: "wechat-service-001",
108
+ },
109
+ },
110
+ {
111
+ agentId: "service-orders",
112
+ match: {
113
+ channel: "celphone-wechat",
114
+ accountId: "wechat-service-002",
115
+ },
116
+ }
117
+ ]
118
+ }
119
+ ```
120
+
121
+ ### Multi-WeChat Account Support
122
+
123
+ For enterprises managing multiple WeChat accounts:
124
+
125
+ ```json
126
+ {
127
+ "channels": {
128
+ "celphone-wechat": {
129
+ // Account 1: Customer service
130
+ "apiKey": "xxx",
131
+ "wechatAccountId": "wp-wechat-001",
132
+ "wechatId": "wxid_customer_service",
133
+ "nickName": "客服小微",
134
+ "accountId": "wechat-service-001"
135
+ }
136
+ }
137
+ }
138
+ ```
139
+
140
+ Each WeChat account maps to a different `accountId` in bindings for routing.
141
+
142
+ ## Webhook Setup
143
+
144
+ To receive messages, configure WorkPhone to send webhooks to your OpenClaw instance:
145
+
146
+ ```
147
+ Your OpenClaw URL: https://your-instance.com/celphone-wechat/webhook
148
+ ```
149
+
150
+ The webhook will POST message events to OpenClaw in real-time.
151
+
152
+ ## Supported Message Types
153
+
154
+ ### Outbound (Sending) - Both DM and Group
155
+
156
+ - **Direct Messages (DM)**: Text, images, videos, files, links to friends
157
+ - **Group Messages**: Text, images, videos, files to chatrooms (supports @mention)
158
+
159
+ ### Inbound (Receiving)
160
+
161
+ - Text messages from friends
162
+ - Text messages from group chats
163
+ - Media messages (images, videos, files)
164
+ - Friend requests
165
+ - Group invitations (if enabled)
166
+
167
+ ## API Coverage
168
+
169
+ This plugin integrates with the WorkPhone WeChat API (131 APIs). Key covered areas:
170
+
171
+ - **WeChat Accounts**: List accounts, get account info
172
+ - **Friends**: Get friends, add friends, accept requests, update remarks/labels
173
+ - **Chatrooms**: Get group list, send to groups, update group name/announcement
174
+ - **Messages**: Send/receive friend messages and chatroom messages
175
+ - **Moments**: Read posts, publish moments, comment, like
176
+
177
+ See [API Manual](./docs/apifox-workphone-api-manual.md) for full API documentation.
178
+
179
+ ## Development
180
+
181
+ ```bash
182
+ # Install dependencies
183
+ pnpm install
184
+
185
+ # Build
186
+ pnpm build
187
+
188
+ # Test
189
+ pnpm test
190
+ ```
191
+
192
+ ## File Structure
193
+
194
+ ```
195
+ celphone-wechat-plugin/
196
+ ├── package.json # Plugin manifest
197
+ ├── openclaw.plugin.json # Plugin config schema
198
+ ├── index.ts # Entry point
199
+ ├── setup-entry.ts # Lightweight setup entry
200
+ ├── src/
201
+ │ ├── channel.ts # Channel plugin implementation
202
+ │ └── client.ts # WorkPhone API client
203
+ └── README.md
204
+ ```
205
+
206
+ ## License
207
+
208
+ ---
209
+
210
+ ## 附录:与企业平台集成要点
211
+
212
+ 根据企业场景总方案,这个 channel 需要与外部平台集成:
213
+
214
+ ### 1. 用户画像查询(外部平台提供)
215
+
216
+ Service agent 应通过外部平台 API 查询用户画像:
217
+
218
+ ```
219
+ Service Agent -> 外部平台 API -> 返回: displayTier, serviceState, riskFlags, preferenceHints
220
+ ```
221
+
222
+ ### 2. 沟通记录归档
223
+
224
+ 消息需要回写到外部平台:
225
+
226
+ ```
227
+ WorkPhone Webhook -> OpenClaw -> 外部平台 ConversationLog
228
+ ```
229
+
230
+ 具体实现:在 `handleInboundMessage` 中添加归档逻辑。
231
+
232
+ ### 3. 外部平台作为 Source of Truth
233
+
234
+ 按照总方案:
235
+ - **用户主数据外置** - 不存 OpenClaw
236
+ - **沟通记录归档** - 写到外部平台
237
+ - **OpenClaw 只保留运行时缓存**
238
+
239
+ ### 4. Security 注意事项
240
+
241
+ - `dmSecurity: "allowlist"` - 只接受白名单用户消息
242
+ - Service agent 权限最小化(workspace 只读)
243
+ - 敏感操作需要审批
244
+
245
+ ---
246
+
247
+ ## 附录:API 文档关联
248
+
249
+ 配套的 WorkPhone WeChat API 手册位置:
250
+
251
+ - 完整手册:`../../data/apifox-workphone-3/handbooks/apifox-workphone-api-manual.md`
252
+ - JSON 索引:`../../data/apifox-workphone-3/handbooks/apifox-workphone-api-manual.json`
253
+ - 原始 API:`../../data/apifox-workphone-3/raw/*.json`
254
+
255
+ 如有 OpenClaw skill 需要基于这些文档回答问题,可参考 `../../skills/workphone-apifox-api/`
256
+
257
+ ## License
258
+
259
+ MIT
@@ -0,0 +1,9 @@
1
+ /**
2
+ * OpenClaw Channel Plugin Entry Point - Simplified Version
3
+ *
4
+ * WorkPhone WeChat Plugin - 最小可运行版本
5
+ */
6
+ import { celPhoneWeChatPlugin } from "./src/channel.js";
7
+ // 直接导出插件,不使用复杂包装
8
+ export default celPhoneWeChatPlugin;
9
+ export { celPhoneWeChatPlugin };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * OpenClaw Channel Plugin Entry Point
3
+ *
4
+ * WorkPhone WeChat Plugin - enables OpenClaw to send/receive WeChat messages
5
+ * through the WorkPhone API platform.
6
+ */
7
+ declare const _default: {
8
+ id: string;
9
+ name: string;
10
+ description: string;
11
+ configSchema: import("openclaw/plugin-sdk/core").OpenClawPluginConfigSchema;
12
+ register: (api: import("openclaw/plugin-sdk/core").OpenClawPluginApi) => void;
13
+ channelPlugin: import("openclaw/plugin-sdk/core").ChannelPlugin<import("./src/channel.js").CelPhoneWeChatResolvedAccount, unknown, unknown>;
14
+ setChannelRuntime?: (runtime: import("openclaw/plugin-sdk/core").PluginRuntime) => void;
15
+ };
16
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,77 @@
1
+ /**
2
+ * OpenClaw Channel Plugin Entry Point
3
+ *
4
+ * WorkPhone WeChat Plugin - enables OpenClaw to send/receive WeChat messages
5
+ * through the WorkPhone API platform.
6
+ */
7
+ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
8
+ import { celPhoneWeChatPlugin, handleInboundMessage } from "./src/channel.js";
9
+ export default defineChannelPluginEntry({
10
+ id: "celphone-wechat",
11
+ name: "WorkPhone WeChat",
12
+ description: "Connect OpenClaw to WorkPhone WeChat API for sending and receiving WeChat messages",
13
+ plugin: celPhoneWeChatPlugin,
14
+ registerCliMetadata(api) {
15
+ api.registerCli(({ program }) => {
16
+ program
17
+ .command("celphone-wechat")
18
+ .description("WorkPhone WeChat channel management")
19
+ .option("-a, --account <id>", "WeChat account ID")
20
+ .option("-l, --list", "List configured WeChat accounts");
21
+ }, {
22
+ descriptors: [
23
+ {
24
+ name: "celphone-wechat",
25
+ description: "WorkPhone WeChat channel",
26
+ hasSubcommands: true,
27
+ },
28
+ ],
29
+ });
30
+ },
31
+ registerFull(api) {
32
+ // Register webhook endpoint for receiving messages from WorkPhone
33
+ api.registerHttpRoute({
34
+ path: "/celphone-wechat/webhook",
35
+ auth: "plugin", // Plugin-managed auth - verify signatures yourself
36
+ handler: async (req, res) => {
37
+ try {
38
+ // Parse the webhook payload
39
+ // The exact format depends on WorkPhone's webhook configuration
40
+ const payload = req.body;
41
+ // Verify the request is from WorkPhone
42
+ // Add signature verification here if needed
43
+ const signature = req.headers["x-workphone-signature"];
44
+ if (!signature) {
45
+ res.statusCode = 401;
46
+ res.end("Missing signature");
47
+ return true;
48
+ }
49
+ // Handle the inbound message
50
+ await handleInboundMessage(api, payload);
51
+ res.statusCode = 200;
52
+ res.end("ok");
53
+ return true;
54
+ }
55
+ catch (error) {
56
+ console.error("Webhook error:", error);
57
+ res.statusCode = 500;
58
+ res.end("Internal error");
59
+ return true;
60
+ }
61
+ },
62
+ });
63
+ // Register gateway method for outbound media handling
64
+ api.registerGatewayMethod({
65
+ method: "POST",
66
+ path: "/celphone-wechat/media",
67
+ handler: async (req, res) => {
68
+ const { messageId, mediaUrl, mediaType } = req.body;
69
+ // Handle media upload/send through WorkPhone
70
+ // This is called when the bot needs to send media files
71
+ res.statusCode = 200;
72
+ res.json({ success: true, messageId });
73
+ return true;
74
+ },
75
+ });
76
+ },
77
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Mock WorkPhone API Server for Testing
3
+ *
4
+ * 模拟 WorkPhone 的 API 端点,用于本地测试
5
+ */
6
+ export {};