Channels
Wechat Kf
OpenClaw channel plugin for WeChat Customer Service (企业微信客服)
Install
npm install
#
Configuration Example
channels:
wechat-kf:
enabled: true
corpId: "wwXXXXXXXXXXXXXXXX" # Your Corp ID
appSecret: "your-app-secret-here" # App Secret (self-built app or WeChat KF secret)
token: "your-callback-token" # Callback Token
encodingAESKey: "your-43-char-key" # Callback EncodingAESKey (43 characters)
webhookPort: 9999 # Local port for webhook server (default: 9999)
webhookPath: "/wechat-kf" # URL path for webhook (default: /wechat-kf)
dmPolicy: "open" # Access control: open | pairing | allowlist
# allowFrom: # Only used with dmPolicy: allowlist
# - "external_userid_1"
# - "external_userid_2"
README
**English** | [中文](./README.zh-CN.md)
# wechat-kf
[](https://www.npmjs.com/package/wechat-kf)
[](LICENSE)
[](https://openclaw.dev)
**WeChat Customer Service channel plugin for OpenClaw** — let WeChat users chat with your AI agent via the WeCom KF API. Zero runtime dependencies — uses only Node.js built-ins.
---
## Features
- **Inbound message handling** — receive text, image, voice, video, file, location, link, mini-program, channels, business card, and forwarded chat history from WeChat users (11+ message types)
- **Event handling** — processes enter_session, msg_send_fail, and servicer_status_change events
- **Rich outbound messaging** — send text, image, voice, video, file, and link messages back to users
- **Media upload & download** — automatically downloads inbound media and uploads outbound media via the WeCom temporary media API; supports HTTP URL download for outbound media
- **Markdown to Unicode formatting** — converts markdown bold/italic/headings/lists to Unicode Mathematical Alphanumeric symbols for styled plain-text display in WeChat
- **AES-256-CBC encryption** — full WeChat callback encryption/decryption with SHA-1 signature verification and PKCS#7 padding validation
- **Webhook + polling fallback** — HTTP webhook server for real-time callbacks, with automatic 30-second polling fallback for reliability; hardened with body size limits, method validation, and error responses
- **Dynamic KF account discovery** — KF account IDs (open_kfid) are automatically discovered from webhook callbacks with enable/disable/delete lifecycle management
- **Cursor-based incremental sync** — persists sync cursors per KF account with atomic file writes for crash safety
- **Access token auto-caching** — tokens cached in memory with hashed keys, automatic refresh 5 minutes before expiry, and auto-retry on token expiry
- **Multi-KF-account isolation** — each KF account gets its own session, cursor, and routing context with per-kfId processing mutex
- **DM policy control** — configurable access control: `open`, `pairing`, or `allowlist` with security adapter (resolveDmPolicy, collectWarnings)
- **Text chunking** — automatically splits long replies to respect WeChat's 2000-character message size limit, with chunker declaration for framework integration
- **Session limit awareness** — detects and gracefully handles WeChat's 48-hour reply window and 5-message-per-window limits
- **Race condition safety** — per-kfId mutex and msgid deduplication prevent duplicate message processing
- **Human-like reply delays** — configurable typing delay simulation for natural conversation pacing
- **Graceful shutdown** — responds to abort signals with pre-check guards, cleanly stopping the webhook server and polling
## Prerequisites
1. A **WeCom account** (企业微信) with admin privileges — [Register here](https://work.weixin.qq.com/)
2. At least one **Customer Service account** (客服账号) created in WeCom's WeChat Customer Service module
3. A **publicly accessible URL** for receiving callbacks — you can use [ngrok](https://ngrok.com/), [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/), or a server with a public IP
4. **OpenClaw Gateway** installed and running (`openclaw gateway start`)
## Installation
```bash
openclaw plugins install @pawaca/wechat-kf
```
## WeCom Setup Guide
The WeChat KF API supports **two integration methods**. Both share the same underlying API (`sync_msg`, `send_msg`, etc.) and this plugin is fully compatible with either.
### Method comparison
| | Method 1: WeCom Admin Self-built App | Method 2: WeChat KF Admin API Hosting |
| ---------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------- |
| **Admin console** | [WeCom Admin](https://work.weixin.qq.com/wework_admin/frame) | [WeChat KF Admin](https://work.weixin.qq.com/kf/) |
| **Secret source** | Self-built app secret | WeChat KF dedicated secret |
| **Callback config location** | WeCom Admin > WeChat KF > API > Callback settings | WeChat KF Admin > Dev Config > Callback settings |
| **Callback URL requirement** | Must use a verified corporate domain (trusted domain configured in WeCom Admin) | No restriction — any publicly accessible URL works |
| **Requires self-built app** | Yes — create an app and grant KF API permissions | No — configure directly in the KF admin console |
| **IP whitelist** | Required (self-built app security requirement) | Not required |
| **API scope** | Full — can call other WeCom APIs alongside KF | Limited to WeChat KF APIs only |
| **Best for** | Teams with existing WeCom integrations | Developers who only need AI customer service |
| **Complexity** | Higher — create app, grant permissions, configure IP whitelist | Lower — enable API and go |
> **Important:** The two methods are **mutually exclusive** — a KF account can only be managed through one method at a time. To switch, you must first unbind the current API integration.
### Required credentials
Regardless of which method you choose, you need these four values for the plugin configuration:
| Credential | Where to find it |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **Corp ID** (`corpId`) | WeCom Admin > My Enterprise > Enterprise ID (format: `wwXXXXXXXXXXXXXXXX`) |
| **App Secret** (`appSecret`) | Method 1: WeCom Admin > App Management > App Details > Secret; Method 2: WeChat KF Admin > Dev Config > Secret |
| **Token** (`token`) | Generated when configuring callback URL (any random string, up to 32 chars) |
| **EncodingAESKey** (`encodingAESKey`) | Generated when configuring callback URL (43-char string) |
### Detailed setup instructions
Since the WeCom and WeChat KF admin consoles are entirely in Chinese, detailed step-by-step setup instructions are provided in the [Chinese guide](./README.zh-CN.md#企业微信客服接入指南). The guide covers:
- **Method 1** (企业微信后台自建应用): Creating a self-built app, granting KF permissions, configuring callback URL and IP whitelist (6 steps)
- **Method 2** (微信客服后台 API 托管): Enabling the API directly from the KF admin console (5 steps)
- A detailed comparison table of both methods
## Configuration
Add the following to your OpenClaw config (`~/.openclaw/openclaw.yaml` or via `openclaw config`):
```yaml
channels:
wechat-kf:
enabled: true
corpId: "wwXXXXXXXXXXXXXXXX" # Your Corp ID
appSecret: "your-app-secret-here" # App Secret (self-built app or WeChat KF secret)
token: "your-callback-token" # Callback Token
encodingAESKey: "your-43-char-key" # Callback EncodingAESKey (43 characters)
webhookPort: 9999 # Local port for webhook server (default: 9999)
webhookPath: "/wechat-kf" # URL path for webhook (default: /wechat-kf)
dmPolicy: "open" # Access control: open | pairing | allowlist
# allowFrom: # Only used with dmPolicy: allowlist
# - "external_userid_1"
# - "external_userid_2"
```
### Configuration reference
| Field | Type | Required | Default | Description |
| ---------------- | -------- | -------- | ------------ | ------------------------------------------------------- |
| `enabled` | boolean | No | `false` | Enable the channel |
| `corpId` | string | **Yes** | — | WeCom Corp ID |
| `appSecret` | string | **Yes** | — | Self-built app secret or WeChat KF secret |
| `token` | string | **Yes** | — | Webhook callback token |
| `encodingAESKey` | string | **Yes** | — | 43-char AES key for message encryption |
| `webhookPort` | integer | No | `9999` | Port for the HTTP webhook server |
| `webhookPath` | string | No | `/wechat-kf` | URL path for webhook callbacks |
| `dmPolicy` | string | No | `"open"` | `open` / `pairing` / `allowlist` |
| `allowFrom` | string[] | No | `[]` | Allowed external_userids (when dmPolicy is `allowlist`) |
## Verification
1. Start the gateway:
```bash
openclaw gateway start
```
2. Expose the webhook port (if not on a public server):
```bash
ngrok http 9999
```
3. Copy the HTTPS URL (e.g. `https://xxxx.ngrok-free.app`) and set the callback URL in WeCom:
```
https://xxxx.ngrok-free.app/wechat-kf
```
4. WeCom sends a GET verification request — the plugin decrypts the `echostr` and responds automatically
5. Send a test message from WeChat (via the KF link) and confirm the agent responds
## Usage
Once configured and runni
... (truncated)
channels
Comments
Sign in to leave a comment