Skill by
ara.so — Daily 2026 Skills collection.
is a TypeScript framework that bridges any AI backend to WeChat (微信) via the Clawbot channel. It uses long-polling to receive messages — no public server required — and exposes a minimal
interface so you can plug in OpenAI, Claude, or any custom logic in minutes.
Node.js >= 22 required.
Triggers QR code scan and persists session to
. Only needs to run once.
Starts the message loop. Blocks until process exits. Automatically reconnects on session expiry.
typescript
import { login, start, type Agent } from "weixin-agent-sdk";
const conversations = new Map<string, string[]>();
const myAgent: Agent = {
async chat(req) {
const history = conversations.get(req.conversationId) ?? [];
history.push(`user: ${req.text}`);
const reply = await callMyAIService(history);
history.push(`assistant: ${reply}`);
conversations.set(req.conversationId, history);
return { text: reply };
},
};
await login();
await start(myAgent);
typescript
import OpenAI from "openai";
import { login, start, type Agent, type ChatRequest } from "weixin-agent-sdk";
import * as fs from "fs";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL, // optional override
});
const model = process.env.OPENAI_MODEL ?? "gpt-4o";
const systemPrompt = process.env.SYSTEM_PROMPT ?? "You are a helpful assistant.";
type Message = OpenAI.Chat.ChatCompletionMessageParam;
const histories = new Map<string, Message[]>();
const openaiAgent: Agent = {
async chat(req: ChatRequest) {
const history = histories.get(req.conversationId) ?? [];
// Build user message — support image input
const content: OpenAI.Chat.ChatCompletionContentPart[] = [];
if (req.text) {
content.push({ type: "text", text: req.text });
}
if (req.media?.type === "image") {
const imageData = fs.readFileSync(req.media.filePath).toString("base64");
content.push({
type: "image_url",
image_url: {
url: `data:${req.media.mimeType};base64,${imageData}`,
},
});
}
history.push({ role: "user", content });
const response = await client.chat.completions.create({
model,
messages: [
{ role: "system", content: systemPrompt },
...history,
],
});
const reply = response.choices[0].message.content ?? "";
history.push({ role: "assistant", content: reply });
histories.set(req.conversationId, history);
return { text: reply };
},
};
await login();
await start(openaiAgent);
If you have an ACP-compatible agent (Claude Code, Codex, kimi-cli, etc.), use the
package — no code needed.
launches your agent as a subprocess and communicates via JSON-RPC over stdio.
Session expired ()
The SDK automatically enters a 1-hour cooldown and then reconnects. No manual intervention needed.
Audio not converting from SILK to WAV
Install the optional dependency:
Bot not receiving messages after restart
State is persisted in
~/.openclaw/get_updates_buf
. The bot resumes from the last position automatically.
QR code not appearing
Ensure your terminal supports rendering QR codes, or check
for the raw QR data.