返回 CodeWhale
DEPLOYMENT.md
根目录 / integrations / wecom-bridge / DEPLOYMENT.md
1 # WeCom Bridge — Deployment Guide
2
3 ## Overview
4
5 The WeCom Bridge integrates CodeWhale with WeCom (企业微信) Smart Bot
6 WebSocket long-connection mode, enabling remote terminal agent interaction
7 without a public IP.
8
9 ## Prerequisites
10
11 1. **WeCom admin access** to create a Smart Bot (智能机器人)
12 2. **CodeWhale runtime API** running at `http://127.0.0.1:7878`
13 3. **Node.js 18+** for the bridge runtime
14
15 ### Create a WeCom Smart Bot
16
17 1. Open the [WeCom Admin Console](https://work.weixin.qq.com/wework_admin/frame#apps)
18 2. Navigate: 应用管理 → 智能机器人 → 创建机器人
19 3. Choose **API mode** (not Webhook mode)
20 4. Copy the **BotID** and **Secret** — you will need these
21
22 ## Quick Start
23
24 Use two terminals. In the first terminal, start the local runtime API:
25
26 ```bash
27 export CODEWHALE_RUNTIME_TOKEN="$(openssl rand -hex 32)"
28 codewhale serve --http --host 127.0.0.1 --port 7878 --auth-token "$CODEWHALE_RUNTIME_TOKEN"
29 ```
30
31 In the second terminal, start the bridge:
32
33 ```bash
34 cd integrations/wecom-bridge
35 cp .env.example .env
36 # Edit .env with your WeCom credentials and the same CODEWHALE_RUNTIME_TOKEN.
37 npm install
38 npm run start
39 ```
40
41 ## Configuration
42
43 Copy the environment template and edit:
44
45 ```bash
46 cp .env.example .env
47 # Edit .env with your credentials
48 ```
49
50 ### Required variables
51
52 | Variable | Example | Description |
53 |----------|---------|-------------|
54 | `WECOM_BOT_ID` | `wb-xxxxxxxxxxxxxxxx` | Smart Bot BotID from WeCom Admin |
55 | `WECOM_BOT_SECRET` | `your-secret` | Smart Bot Secret from WeCom Admin |
56 | `CODEWHALE_RUNTIME_TOKEN` | `rand-xxxxxxxx` | Bearer token for Runtime API (generate a random string) |
57
58 ### Optional variables
59
60 | Variable | Default | Description |
61 |----------|---------|-------------|
62 | `CODEWHALE_RUNTIME_URL` | `http://127.0.0.1:7878` | Runtime API address |
63 | `CODEWHALE_WORKSPACE` | `(cwd)` | Workspace directory |
64 | `CODEWHALE_MODEL` | `auto` | Default model name |
65 | `WECOM_CHAT_ALLOWLIST` | `""` | Comma-separated allowed UserIDs |
66 | `WECOM_ALLOW_UNLISTED` | `false` | Enable first-pairing mode |
67 | `WECOM_MAX_REPLY_CHARS` | `3500` | Max characters per reply message |
68 | `CODEWHALE_TURN_TIMEOUT_MS` | `900000` | Turn timeout in ms (15 min) |
69 | `CODEWHALE_APPROVAL_TIMEOUT_MS` | `300000` | Approval timeout in ms (5 min) |
70
71 ## First Pairing
72
73 1. Leave `WECOM_ALLOW_UNLISTED=false` and start the bridge.
74 2. Send any message to the bot in WeCom.
75 3. The bot will refuse the unlisted chat and reply with `chat_id=...` and,
76 when available, `user_id=...`.
77 4. Add one of those values to `WECOM_CHAT_ALLOWLIST`.
78 5. Restart the bridge.
79
80 ## Verify Installation
81
82 ```bash
83 # Check syntax
84 npm run check
85
86 # Run bridge tests
87 npm test
88 ```
89
90 Expected output: `ℹ tests 16 ℹ pass 16 ℹ fail 0`
91
92 ## Architecture
93
94 ```
95 WeCom Client → Smart Bot WebSocket → WeCom Bridge ──HTTP──→ codewhale serve --http
96 ◀── aibot_respond_msg ◀── (127.0.0.1:7878)
97 ```
98
99 The bridge:
100 1. Authenticates via BotID + Secret to obtain an `access_token`
101 2. Establishes a WebSocket long connection to the WeCom Smart Bot API
102 3. Receives `aibot_msg_callback` events, processes them through the Runtime API
103 4. Replies via `aibot_respond_msg` commands
104
105 ## Security Boundaries
106
107 - **No public port exposure**: `codewhale serve --http` binds to `127.0.0.1` only
108 - **Token authentication**: all `/v1/*` runtime calls require `CODEWHALE_RUNTIME_TOKEN`
109 - **Chat allowlist**: only chats/users in `WECOM_CHAT_ALLOWLIST` are served
110 - **Approval gate**: tool calls from WeCom require explicit approval (`/allow` or natural-language keywords)
111 - **WeCom only sees**: prompts, status summaries, thread listings, and approval requests — workspace contents, shell output, and runtime internals stay on your local machine
112
113 ## Troubleshooting
114
115 | Symptom | Likely cause | Fix |
116 |---------|-------------|-----|
117 | "not paired" warning | `WECOM_CHAT_ALLOWLIST` is empty | Add your user_id or enable `WECOM_ALLOW_UNLISTED=true` |
118 | 404 on `/allow` | Approval ID expired (5 min) | Respond faster, or increase `CODEWHALE_APPROVAL_TIMEOUT_MS` |
119 | Bridge exits immediately | Missing env vars | Run `node src/index.mjs` directly to see validation errors |
120 | Messages not received | Secret or BotID wrong | Verify credentials in WeCom Admin Console |
121 | WebSocket disconnect | Network flakiness | Bridge auto-reconnects; check the bridge stdout/stderr logs for details |
122
123 ## Production Deployment
124
125 ### Long-running service
126
127 Run the runtime API and bridge under the process manager you already use
128 (systemd, launchd, Task Scheduler, pm2, or a terminal multiplexer). The two
129 commands to supervise are:
130
131 ```bash
132 codewhale serve --http --host 127.0.0.1 --port 7878 --auth-token "$CODEWHALE_RUNTIME_TOKEN"
133 npm run start --prefix integrations/wecom-bridge
134 ```
135
136 ### Logging
137
138 The bridge logs to stdout/stderr. Configure your service manager to capture
139 those streams; for example, systemd captures them in `journalctl`, and launchd
140 can redirect them with `StandardOutPath` / `StandardErrorPath`.
141
142 ### Auto-restart
143
144 Enable restart/recovery in the same process manager. The bridge reconnects to
145 WeCom after transient WebSocket disconnects, but the supervisor should restart
146 the process after crashes or host reboots.
147
148 ## Related Documentation
149
150 - [WeCom Bridge README](README.md)
151 - [CodeWhale Security Policy](../../SECURITY.md)
152 - [CodeWhale Contributing Guide](../../CONTRIBUTING.md)
153
153 lines MARKDOWN