Library / SDK
corespeed-io/wechatbot avatar
corespeed-io/wechatbot

WeChatBot: a four-language SDK for wiring AI agents into WeChat iLink

微信 iLink Bot SDK for OpenClaw/AI Agent

649 stars88 forksTypeScriptMIT

At a glance

What is it?
WeChatBot wraps the WeChat iLink Bot protocol in TypeScript, Python, Go and Rust clients so an agent can send and receive messages after a QR scan. The Node.js SDK carries the most surface area, and the multi-tenant story is the part worth reading closely.
Who is it for?
Adopt it if you are building an agent bridge into WeChat and want the iLink protocol handled for you in TypeScript, Python, Go or Rust, and if you can accept that one account must map to exactly one polling instance. Do not adopt it if you need a hosted multi-tenant service or a documented SLA; the README describes the primitives, not an operations product.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 75 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap WeChatBot fills: an agent that can only talk to the terminal

Most agent frameworks assume a chat surface with a clean HTTP API. WeChat does not offer one for this use case. The project positions itself as an iLink Bot SDK, and its stated goal is to let any agent connect to WeChat in about five minutes. The README credits openclaw-weixin as the inspiration, which tells you the protocol layer was reverse-engineered or adapted rather than invented here. The audience is narrow and specific: developers who already have an agent loop, in any language, and need it to receive WeChat messages and reply. The repository ships four client libraries rather than one, which suggests the maintainers expect the agent runtime and the WeChat transport to live in different languages. That is a real constraint in practice. A Python agent can use the Python SDK, a Rust service can use the Rust crate, and neither has to shell out to a Node process.

How the protocol layer is split: poller, sender, typing, media, context store

The architecture diagram in the README shows a Bot Client as the central dispatcher, with four components hanging off it: Poller, Sender, Typing and Media. All four read from and write to a Context Store that caches tokens, and that store sits on top of a Protocol/API layer making HTTP calls, with Storage underneath for credentials and state. The interesting part is the Context Store. The feature table describes context_token as having automatic lifecycle management with persistence across restarts, and the same store is shared by sending, typing indicators and media upload. That means a restart does not force a fresh token exchange, and it also means the store is a synchronization point: if two processes share one store for one account, they will race. Message reception is long polling with automatic cursor management, not a webhook. There is no inbound port to open, which is why the README can claim the SDK occupies no local port. The trade-off is that message latency is bounded by the poll cycle, and the cursor is the only thing preventing duplicate or skipped messages.

Getting a bot running in each of the four SDKs

The README gives a minimal example per language. In TypeScript you import WeChatBot from @wechatbot/wechatbot, construct it, await bot.login() for the QR scan, register bot.onMessage with an async handler that calls bot.reply(msg, text), then await bot.start(). Python uses a decorator instead: @bot.on_message on an async function, then bot.run(), which the comment says performs QR login and starts listening in one call. Go constructs with wechatbot.New(), calls bot.Login(ctx, false), registers bot.OnMessage with a callback, and calls bot.Run(ctx). Rust builds with WeChatBot::new(BotOptions::default()), awaits bot.login(false), registers a boxed closure via bot.on_message, then awaits bot.run(). Credentials persist under ~/.wechatbot/, so a restart should not require a new scan. The Node.js SDK adds a middleware pipeline in the Express or Koa style, a message builder with a chain like .text().image().file().build(), pluggable storage (file, memory, or custom), typed events, and structured logging. Those extras exist only in Node.js, which is the main reason to pick it over the other three if language choice is open.

Multi-tenant deployment and the three rules the README states

Each bot instance is described as fully isolated, with its own HTTP client, events and message poller, no global state and no local port. The intended pattern is one backend process running many WeChat accounts, with the QR URL pushed to a web front end through callbacks so each end user scans on their own page. The login call accepts callbacks for onQrUrl, onScanned and onExpired, and storage can be swapped for something like a PostgresStorage constructed with a pool and a tenantId, or a per-tenant storageDir such as /data/${tenantId}. The README then lists three cautions, and they are the most operationally useful lines in the document. First, every account needs its own storageDir or storage namespace, because sharing one overwrites credentials. Second, one account must have exactly one polling instance across the whole cluster, or cursors overwrite each other; multi-machine deployments need an advisory lock or a lease table to elect a leader. Third, restarts skip the scan because credentials are already persisted. The second rule is the one that will bite teams who scale horizontally without reading it.

Where the SDK is the wrong tool

This is an unofficial client for a protocol the README does not claim is publicly supported. The documentation lives in docs/protocol.md and docs/architecture.md inside the repository, not on a vendor site. Anything built on it inherits that status. The session expiry code -14 and the automatic re-login feature exist precisely because sessions do expire; the SDK handles the recovery, but a re-login means a new QR scan in some flows, and the README does not spell out when a scan is required versus when the persisted credential is enough. Long polling also means you cannot serve a high-frequency, low-latency interface: if you need sub-second delivery, this transport is the wrong shape. And the one-instance-per-account rule makes it a poor fit for a serverless or auto-scaling deployment where you cannot guarantee a single leader without adding a coordination layer yourself. The README points to a lease table or advisory lock but does not ship one. Finally, no releases were retrieved for this repository, so versioning discipline is something to check on npm rather than assume.

How it compares with writing against the iLink API directly

The alternative is not another SDK. It is implementing the iLink Bot API yourself, using docs/protocol.md as the specification and the openclaw-weixin repository as prior art. That path gives you full control over the poll loop, token caching and retry policy, and it removes a dependency that could drift from the upstream protocol. It also means reimplementing AES-128-ECB CDN encryption with dual key format support, the context_token lifecycle, typing indicator tickets with caching, and text splitting on natural boundaries (paragraph, then line, then space). The README lists all of those as shipped features, which is a fair summary of what you would be rebuilding. The honest comparison is maintenance surface versus control: the SDK concentrates protocol churn in one dependency, while a direct implementation concentrates it in your codebase. If your agent already has a mature HTTP layer and you only need send and receive, the direct route is defensible. If you need media upload and download, typing indicators and session recovery, the SDK is doing more work than the README's short feature table suggests.

Licence, upgrade cost and what a fork implies

The repository is MIT licensed, and the npm package is published under the @wechatbot scope. MIT permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive baseline, but it says nothing about the iLink protocol itself or about WeChat's terms of service for automated clients; the licence covers this code, not your right to run a bot against the platform. On upgrade cost, four language SDKs in one repository means protocol changes touch four codebases, and the Node.js SDK carries features the other three do not have, so parity is not guaranteed. There are no retrieved releases, so pinning to a version and reading the diff before bumping is the safer habit. The Pi Agent extension is installed separately with pi install npm:@wechatbot/pi-agent and exposes a /wechat command, which is a different distribution channel from the SDKs and will version independently.

Editorial conclusion

Adopt it if you are building an agent bridge into WeChat and want the iLink protocol handled for you in TypeScript, Python, Go or Rust, and if you can accept that one account must map to exactly one polling instance. Do not adopt it if you need a hosted multi-tenant service or a documented SLA; the README describes the primitives, not an operations product. Before writing code, read docs/protocol.md and docs/architecture.md, then confirm two things yourself: that @wechatbot/wechatbot on npm matches the repository you are reading, and that your storage layer gives each account its own storageDir or namespace.

Official sources

  1. corespeed-io/wechatbot on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Community notes

Community notes