# wxchat-sdk
**Repository Path**: QtCodeCreators/wxchat-sdk
## Basic Information
- **Project Name**: wxchat-sdk
- **Description**: Multi-language SDK for WeChat messaging via OpenClaw channel protocol (Go / Python / Rust / PHP)
- **Primary Language**: Python
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-03-25
- **Last Updated**: 2026-03-25
## Categories & Tags
**Categories**: Uncategorized
**Tags**: openclaw, AI, 人工智能, 微信SDK, 实时聊天
## README
# wxchat-sdk
**Multi-language SDK for WeChat messaging via the OpenClaw channel protocol**
Go · Python · Rust · PHP
[](./LICENSE)
[](#go)
[](#python)
[](#rust)
[](#php)
[Protocol Docs](./docs/PROTOCOL.md) · [Disclaimer](./DISCLAIMER.md) · [Test UI](#test-ui) · [CN / 中文](#中文说明)
---
## What is this?
A set of lightweight, zero-framework SDKs that let you **send and receive WeChat messages programmatically** through the OpenClaw iLink channel protocol.
- Scan a QR code to bind a WeChat account
- Receive messages from WeChat users via long-polling
- Send text, image, video, and file messages back
- All media transferred via CDN with AES-128-ECB encryption
> **Disclaimer**: This is an independent community project. Not affiliated with Tencent or WeChat.
> Intended for educational and research purposes. See [DISCLAIMER.md](./DISCLAIMER.md) for full details.
## Architecture
```
HTTP JSON API
┌──────────┐ ◄─────────────────────► ┌────────────────────────┐
│ Your │ │ ilinkai.weixin.qq.com │
│ App │ │ (iLink Gateway) │
│ + SDK │ CDN Upload / Download ├────────────────────────┤
│ │ ◄─────────────────────► │ novac2c.cdn.weixin.qq │
└──────────┘ AES-128-ECB │ (Media CDN) │
└────────────────────────┘
```
## Critical: Usage Flow
```
Step 1. QR Login → get bot_token + user_id
Step 2. Start long-polling → getUpdates loop
Step 3. User sends a msg → you receive context_token ← REQUIRED
Step 4. Now you can reply → sendMessage with context_token
```
**`context_token` is mandatory for message delivery.** Without it the API accepts your request (HTTP 200) but the message will **never reach** the WeChat client. The token is only available after the user sends their first message from WeChat.
## Quick Start
### Go
```go
import "github.com/qingchencloud/wxchat-sdk/go/wxchatoc"
// 1. QR Login
session, _ := wxchatoc.StartQRLogin(ctx, wxchatoc.DefaultBaseURL)
fmt.Println("Scan:", session.QRCodeURL)
result, _ := session.WaitForLogin(ctx, func(s string) { fmt.Println(s) })
// 2. Create client + start polling
client := wxchatoc.NewClient(result.BotToken)
tokens := wxchatoc.NewContextTokenStore()
poller := wxchatoc.NewPoller(client, func(msg *wxchatoc.WeixinMessage) {
// 3. Save context_token from first message
if msg.ContextToken != "" {
tokens.Set("default", msg.FromUserID, msg.ContextToken)
}
fmt.Printf("From %s: %s\n", msg.FromUserID, msg.ItemList[0].TextItem.Text)
// 4. Reply
ct := tokens.Get("default", msg.FromUserID)
client.SendText(ctx, msg.FromUserID, "Got it!", ct)
})
poller.Run(ctx)
```
**Deps:** Go 1.21+, zero third-party dependencies
### Python
```python
from wxchatoc import WxChatClient, start_qr_login, Poller, ContextTokenStore
# 1. QR Login
session = start_qr_login()
print("Scan:", session.qrcode_url)
result = session.wait_for_login(on_status=print)
# 2. Client + polling
client = WxChatClient(token=result.bot_token)
tokens = ContextTokenStore()
def on_message(msg):
if msg.context_token:
tokens.set("default", msg.from_user_id, msg.context_token)
print(f"From {msg.from_user_id}: {msg.item_list[0].text_item.text}")
ct = tokens.get("default", msg.from_user_id)
client.send_text(msg.from_user_id, "Got it!", ct)
Poller(client, on_message=on_message).run()
```
**Deps:** Python 3.9+, `httpx`, `cryptography`
### Rust
```rust
use wxchatoc::{WxChatClient, auth};
#[tokio::main]
async fn main() {
let mut session = auth::start_qr_login(
"https://ilinkai.weixin.qq.com", None, None
).await.unwrap();
println!("Scan: {}", session.qrcode_url);
let result = session.wait_for_login(
Some(|s: &str| println!("{}", s))
).await.unwrap();
let client = WxChatClient::new(&result.bot_token);
// ... start polling, collect context_token, then send
client.send_text("user@im.wechat", "Hello!", "ctx-token").await.unwrap();
}
```
**Deps:** `reqwest`, `aes`, `serde`, `tokio`
### PHP
```php
use WxChatOC\{Client, Auth, Poller, ContextTokenStore};
$session = Auth::startQRLogin();
echo "Scan: " . $session->qrcodeUrl . "\n";
$result = $session->waitForLogin(fn($s) => print("$s\n"));
$client = new Client($result->botToken);
$tokens = new ContextTokenStore();
$poller = new Poller($client, function($msg) use ($client, $tokens) {
if ($msg->context_token) {
$tokens->set('default', $msg->from_user_id, $msg->context_token);
}
$ct = $tokens->get('default', $msg->from_user_id);
$client->sendText($msg->from_user_id, 'Got it!', $ct);
});
$poller->run();
```
**Deps:** PHP 8.1+, `guzzlehttp/guzzle`, `ext-openssl`
## Test UI
A browser-based chat interface for quick testing:
```bash
cd examples/testui
pip install httpx
python server.py # opens http://localhost:8199
```
Open browser → Scan QR to bind → Send a message from WeChat to establish channel → Chat
## Project Structure
```
wxchat-sdk/
├── go/wxchatoc/ # Go SDK (zero deps)
│ ├── client.go # API client
│ ├── auth.go # QR login
│ ├── cdn.go # CDN upload/download
│ ├── poller.go # Long-poll + token store
│ ├── crypto.go # AES-128-ECB
│ └── types.go # Type definitions
├── python/wxchatoc/ # Python SDK
├── rust/wxchatoc/ # Rust SDK
├── php/wxchatoc/ # PHP SDK
├── examples/testui/ # Browser test UI
└── docs/PROTOCOL.md # Full protocol documentation
```
## API Endpoints
| Endpoint | Method | Description |
|----------|--------|-------------|
| `ilink/bot/get_bot_qrcode` | GET | Fetch QR code for login |
| `ilink/bot/get_qrcode_status` | GET | Poll QR scan status (long-poll) |
| `ilink/bot/getupdates` | POST | Long-poll for new messages |
| `ilink/bot/sendmessage` | POST | Send message (text/image/video/file) |
| `ilink/bot/getuploadurl` | POST | Get CDN upload pre-signed URL |
| `ilink/bot/getconfig` | POST | Get account config (typing ticket) |
| `ilink/bot/sendtyping` | POST | Send typing indicator |
Full protocol documentation: [docs/PROTOCOL.md](./docs/PROTOCOL.md)
## Contributing
Contributions are welcome! Please open an issue or PR.
## License
[Apache License 2.0](./LICENSE)
---
## 中文说明
### 这是什么?
一套多语言 SDK,通过 OpenClaw iLink 通道协议实现与微信的消息收发。
### 核心流程
1. **扫码绑定** -- 获取 bot_token 和用户 ID
2. **启动长轮询** -- getUpdates 循环接收消息
3. **用户从微信发一条消息** -- 获取 context_token(**必需**)
4. **开始双向聊天** -- sendMessage 必须携带 context_token
### 重要提示
- `context_token` 是消息投递的必要条件,没有它消息不会到达微信客户端
- 每次收到新消息都应更新 context_token
- `get_updates_buf` 同步游标需要持久化保存
- errcode=-14 表示会话过期,SDK 会自动暂停 1 小时
### 测试工具
```bash
cd examples/testui
pip install httpx
python server.py
```
浏览器打开 `http://localhost:8199` ,扫码绑定后在微信发一条消息建立通道,即可双向聊天。
### 免责声明
本项目是独立的社区开源项目,与腾讯/微信无任何关联。仅供教育和研究用途。详见 [DISCLAIMER.md](./DISCLAIMER.md)。