Skip to content

qingchencloud/wxchat-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wxchat-sdk

Multi-language SDK for WeChat messaging via the OpenClaw channel protocol

Go · Python · Rust · PHP

License Go Python Rust PHP

Protocol Docs · Disclaimer · 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 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

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

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

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

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:

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

Contributing

Contributions are welcome! Please open an issue or PR.

License

Apache License 2.0


中文说明

这是什么?

一套多语言 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 小时

测试工具

cd examples/testui
pip install httpx
python server.py

浏览器打开 http://localhost:8199 ,扫码绑定后在微信发一条消息建立通道,即可双向聊天。

免责声明

本项目是独立的社区开源项目,与腾讯/微信无任何关联。仅供教育和研究用途。详见 DISCLAIMER.md

Releases

No releases published

Packages

 
 
 

Contributors