Architecture
March 23, 2026 Β· View on GitHub
All four SDKs (Node.js, Python, Go, Rust) follow the same layered architecture and expose a consistent API surface.
Layers
graph TD
A["π€ Application β Your Bot Code"] --> B["Middleware (Node.js only)"]
B --> C["Bot Client β Orchestrator: login, run, reply"]
C --> D["Poller"]
C --> E["Sender"]
C --> F["Typing"]
C --> G["Media"]
D --> H["Context Store β context_token lifecycle"]
E --> H
F --> H
G --> H
H --> I["Protocol / API β Raw HTTP calls to iLink"]
I --> J["Transport / HTTP β HTTP client with retry"]
J --> K["Storage β Credentials + state persistence"]
SDK Comparison
| Feature | Node.js | Python | Go | Rust |
|---|---|---|---|---|
| Package | @wechatbot/wechatbot | wechatbot-sdk (PyPI) | github.com/corespeed-io/wechatbot/golang | wechatbot (crates.io) |
| Async model | async/await (Promises) | async/await (asyncio) | goroutines + context.Context | async/await (tokio) |
| Middleware | β Express-style pipeline | β (use decorator composition) | β (use handler composition) | β (use closures) |
| Storage | Pluggable (file/memory/custom) | File-based | File-based | File-based |
| Media crypto | β AES-128-ECB | β AES-128-ECB | β AES-128-ECB | β AES-128-ECB |
| Events | Typed EventEmitter | Callbacks (on_qr_url, on_errorβ¦) | Callbacks (OnError, OnQRURL) | Callbacks |
| Error types | 6 typed error classes | Error hierarchy | APIError with methods | thiserror enum |
| Dependencies | 0 runtime | aiohttp, cryptography | stdlib only | reqwest, serde, aes, tokio |
Shared Concepts
context_token
Every reply must include the context_token from the incoming message. All SDKs:
- Cache tokens in memory per
(userId) - Auto-extract from incoming messages
- Auto-inject into outgoing messages via
reply() - (Node.js) Persist to storage for restart survival
QR Login Flow
All SDKs implement the same flow:
GET /get_bot_qrcodeβ get QR URL- Display QR to user
GET /get_qrcode_statuspoll loop (2s interval)- On
confirmedβ extract credentials, persist to~/.wechatbot/ - On
expiredβ request new QR
Long-Poll Loop
POST /getupdateswith cursor (35s server hold)- Parse messages, cache context_tokens
- Dispatch to handlers
- On
-14error β clear state, re-login - On network error β exponential backoff (1s β 10s max)
Media Pipeline
All SDKs support encrypted media upload and download via the WeChat CDN:
- Upload: generate AES key β encrypt (AES-128-ECB) β getuploadurl β POST to CDN β get download param
- Download: GET from CDN β decrypt (AES-128-ECB) with key from message
The Node.js SDK additionally provides:
- Unified
reply(msg, content)/send(userId, content)β one method handles text, image, video, file, and URL - Auto-routing by MIME β
{ file: data, fileName: 'photo.png' }routes as image;.mp4as video; others as file attachment - Remote URL support β
{ url: 'https://...' }auto-downloads and sends - Voice transcode β SILK β WAV via optional
silk-wasmdependency - Markdown stripping β
stripMarkdown()for cleaning AI model output before sending to WeChat
Text Chunking
All SDKs split text at 2000 characters:
- Priority: paragraph break (
\n\n) β line break (\n) β space β hard cut - Each chunk gets a unique
client_id - All chunks share the same
context_token
File Structure
Node.js
nodejs/
βββ src/
β βββ core/ # Client (unified reply/send/download), events, errors
β βββ transport/ # HTTP with retry
β βββ protocol/ # Wire types + API calls
β βββ auth/ # QR login
β βββ messaging/ # Poller, sender, typing, context
β βββ media/ # AES crypto, CDN up/down, MIME, voice transcode,
β β # remote URL download, markdown stripping
β βββ middleware/ # Engine + 4 builtins
β βββ message/ # Parser, builder, types
β βββ storage/ # File, memory, interface
β βββ logger/ # Structured logging
βββ tests/ # 69 unit tests
βββ examples/ # 3 example bots
Python
python/
βββ wechatbot/
β βββ __init__.py # Public exports
β βββ client.py # WeChatBot (login, start, reply, send)
β βββ protocol.py # Raw iLink API calls
β βββ auth.py # QR login + credential persistence
β βββ types.py # All types (dataclasses)
β βββ errors.py # Error hierarchy
β βββ crypto.py # AES-128-ECB encrypt/decrypt
βββ examples/
β βββ echo_bot.py
βββ tests/
βββ test_crypto.py # 10 tests
βββ test_client.py # 8 tests
Go
golang/
βββ types.go # All public types
βββ bot.go # Bot client
βββ internal/
β βββ protocol/api.go # iLink HTTP calls
β βββ auth/login.go # QR login + credentials
β βββ crypto/aes.go # AES-128-ECB
βββ examples/
βββ echo-bot/main.go
Rust
rust/
βββ src/
β βββ lib.rs # Re-exports
β βββ types.rs # All types (serde)
β βββ error.rs # Error hierarchy
β βββ protocol.rs # iLink API calls
β βββ crypto.rs # AES-128-ECB + tests
β βββ bot.rs # Bot client
βββ examples/
βββ echo_bot.rs