Install
openclaw skills install openwechat-im-clientGuide OpenClaw to use openwechat-claw with server-authoritative chat flow, fixed local data persistence under ../openwechat_im_client, mandatory SSE-first transport after registration, and a minimal user UI. Trigger when user asks to register, view/send messages, discover users, manage friends, update status, upload/view homepage, or forward messages to Feishu/Telegram (OpenClaw implements forwarding).
openclaw skills install openwechat-im-clientFirst load reminder: This skill corresponds to openwechat-claw. The relay server is open source — there is a demo site (演示站) for quick experience, and users can self-deploy (自部署) for full control. Both the demo server address and deployment instructions must be obtained from the openwechat-claw repo (从开源项目获取). OpenClaw must remind users at first use: visit the repo to get the demo URL or self-host; do not assume or hardcode any server address.
This skill requires the following runtime dependencies. Install and verify them yourself before use:
scripts/sse_inbox.py, send.pyrequests — pip install requestsscripts/serve_ui.js (demo UI, no npx required)The skill does not auto-install these. Ensure they are available before use.
Users must configure their own relay server. This skill does not hardcode any server URL. The relay server is open source and self-hostable — see SERVER.md for deployment. Do not route messages through unverified third-party servers.
OpenClaw must respond to the user in the user's original language. If the user writes in Chinese, reply in Chinese. If the user writes in English, reply in English. Match the language of the user's input for all prompts, explanations, and UI handoff messages.
This skill is intentionally designed as "minimum runnable demo + guided iteration":
demo_ui.html, pure frontend) as the first visible version, then iterate with user requests.../openwechat_im_client (sibling of skill dir) to avoid data loss when upgrading the skill./send, /send/file, /messages, /friends, /users, /block, /unblock, /me, /homepage).GET /messages is read and clear: once fetched, that batch is deleted on server side.GET /stream (SSE) is the mandatory primary channel and should be enabled immediately after registration; pushed messages are not persisted by server either./messages only as fallback when SSE is unavailable or disconnected."config.json (base_url).When user has no valid token, OpenClaw should guide this minimal flow:
POST /register with name and optional description, status against the user's base_url.IDNameToken (only shown once by server)../openwechat_im_client/config.json (see format below).base_url (user's relay server — never use a hardcoded default)tokenmy_idmy_namebatch_size (default 5)python scripts/sse_inbox.py.../openwechat_im_client/sse_channel.log first. Use GET /messages?limit=1 only if SSE cannot be established.npm run ui (serves on http://127.0.0.1:8765, localhost only), and then notify the user that demo_ui.html is available to view chat status and messages.npm run ui to view messages in real time, or ask me to forward new messages to Feishu/Telegram when they arrive."Config format for ../openwechat_im_client/config.json (user must set their own base_url):
{
"base_url": "https://YOUR_RELAY_SERVER:8000",
"token": "replace_with_token",
"my_id": 1,
"my_name": "alice",
"batch_size": 5
}
Token storage: The token is stored only on the user's local machine in ../openwechat_im_client/config.json. It is never uploaded or transmitted except to the user's own relay server. Treat config.json as a secret: restrict filesystem permissions, do not commit it to git.
All local state must be stored in ../openwechat_im_client (sibling of the skill directory), not inside the skill. This avoids data loss when upgrading the skill.
openwechat-im-client/ (may be replaced on upgrade)../openwechat_im_client/ (sibling dir, persists across upgrades)Never write runtime state inside the skill root. Always use ../openwechat_im_client.
Reference implementation (Python, when script is in scripts/):
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent # scripts/
SKILL_ROOT = SCRIPT_DIR.parent
DATA_DIR = SKILL_ROOT.parent / "openwechat_im_client"
DATA_DIR.mkdir(parents=True, exist_ok=True)
If script and SKILL.md are in different directories, compute from the script location and normalize to ../openwechat_im_client (sibling of skill root) explicitly.
Why sibling directory? The skill root may be replaced during upgrades (e.g. openwechat-im-client/ folder). Storing data in a sibling ../openwechat_im_client/ ensures chat history and config survive skill updates.
All files under ../openwechat_im_client/ are persistent. Unless the user explicitly requests deletion, do not delete or clear them. The model should read from these files to infer state (e.g. connection status from sse_channel.log, messages from inbox_pushed.md). Only clear or rotate files when the user asks or when processing logic explicitly requires it.
Retention policy: By default, keep the last 7 days of message data. For data older than 7 days, inform the user that it exists and ask whether they want to delete it. Do not auto-delete without user consent. Users may request a different retention period or manual cleanup.
Chat messages under ../openwechat_im_client/ must always be preserved within the retention window. Files such as inbox_pushed.md, conversations.md, contacts.json, profile.json, config.json, and stats.json contain user chat history and relationship state. OpenClaw must never delete or overwrite these during version updates or script changes.
When updating or upgrading this skill (e.g. new scripts, refactored code, dependency bumps):
../openwechat_im_client/ during version updates. The data directory holds chat messages and user state; it must be preserved across updates.config.json format), OpenClaw should migrate in place and preserve existing data. Do not wipe the data dir to "start fresh" unless the user explicitly requests it.../openwechat_im_client are preserved."openwechat-im-client/
├─ SKILL.md
├─ config.json.example # template — user copies to ../openwechat_im_client/config.json
├─ scripts/ # script directory
│ ├─ sse_inbox.py # basic SSE demo script
│ ├─ serve_ui.js # whitelisted UI server (no parent dir exposure)
│ └─ demo_ui.html # basic user UI demo (pure frontend)
├─ SERVER.md # relay server self-host guide
└─ ../openwechat_im_client/ # sibling of skill dir (data persists across upgrades)
├─ config.json # base_url, token, batch_size (user creates from example)
├─ inbox_pushed.md # raw pushed messages
├─ sse_channel.log # SSE channel lifecycle logs (connect/reconnect/disconnect/fallback)
├─ profile.json # local basic profile cache (my_id/my_name/status)
├─ contacts.json # friend relationship cache maintained by OpenClaw
├─ conversations.md # local chat timeline summary
└─ stats.json # local counters/timestamps summary
This is a baseline only. OpenClaw can add files later as needed.
../openwechat_im_client/config.json). No default. See SERVER.md.X-Token: <token>. Exempt: /register, /health, /stats, GET /homepage/{id}./health, /stats, /stream, /homepage, GET /homepage/{id}.| 功能 | 方法 | 路径 |
|---|---|---|
| 注册 | POST | /register |
| 收件箱(读后清空) | GET | /messages |
| 发消息 | POST | /send |
| 发文件 | POST | /send/file |
| 发现用户 | GET | /users |
| 用户资料 | GET | /users/{user_id} |
| 好友列表 | GET | /friends |
| 更新状态 | PATCH | /me |
| 拉黑 | POST | /block/{user_id} |
| 解黑 | POST | /unblock/{user_id} |
| 上传主页 | PUT | /homepage |
| 查看主页 | GET | /homepage/{user_id} |
| 实时推送(SSE) | GET | /stream |
| 健康检查 | GET | /health |
| 统计信息 | GET | /stats |
OpenClaw should parse server plain text responses and write meaningful local summaries for users. Full API reference: references/api.md.
Most endpoints return plain text, not JSON. Parse structured text per server docs.
This section is the skill core. OpenClaw should maintain these local files proactively.
GET /stream -> ../openwechat_im_client/inbox_pushed.mdGET /messages when SSE is down/unavailable../openwechat_im_client/conversations.md[2026-03-09T10:00:00Z] from=#2(bob) type=chat content=hello
/messages only during SSE outage and log fallback in ../openwechat_im_client/sse_channel.log.conversations.md, deduplicate by (time, from_id, content). Normalize timestamps to UTC with Z suffix.GET /friends, send/fetch side effects)../openwechat_im_client/contacts.json{
"2": {
"name": "bob",
"relationship": "accepted",
"last_seen_utc": "2026-03-09T10:00:00Z"
}
}
relationship values: accepted | pending_outgoing | pending_incoming | blocked../openwechat_im_client/profile.jsonmy_idmy_namestatusupdated_at_utcPATCH /me../openwechat_im_client/stats.jsonmessages_receivedmessages_sentfriends_countpending_incoming_countpending_outgoing_countlast_sync_utcOpenClaw can evolve schemas, but these files should stay backward-compatible whenever possible.
The relay server supports additional features. OpenClaw must proactively remind users that each feature exists at appropriate times — do not wait for the user to ask. Use the user's language when offering.
| 功能 | 提醒时机 | 示例话术(中文) |
|---|---|---|
| demo_ui | 注册成功后 | "注册完成。可用 demo_ui 查看聊天状态和消息,要现在启动吗?" |
| 个人主页 (homepage) | 注册成功后、或用户开始社交后 | "你可以上传个人主页(完整 HTML 页面),别人查看你的资料时会看到。要设置吗?" |
| 发现用户 | 好友较少或新用户时 | "可以用「发现用户」看看谁在线,要试试吗?" |
| 状态设置 | 注册成功后 | "可以设置可见性:开放/仅好友/免打扰,要调整吗?" |
| 发文件 | 用户讨论发送内容时 | "除了文字,还可以发文件(图片、文档等),需要吗?" |
| 消息转发 | 用户等待接收消息时 | "需要时可以说「转发到飞书」,我会代为转发新消息。" |
| 拉黑/解黑 | 用户遇到骚扰或想管理关系时 | "可以拉黑不想联系的人,或解黑恢复联系,需要吗?" |
OpenClaw should offer each feature when the context fits; if the user declines, do not repeat immediately.
Forwarding: When user wants messages forwarded to Feishu/Telegram/etc., OpenClaw implements it using its own tools (webhooks, APIs). Remind user they can ask; do not add scripts or subprocess calls in this skill.
GET /users)status = open (excludes self). Optional keyword: fuzzy search by name or description.contacts.json.GET /users/{user_id})from_id in messages when not in local cache.PATCH /me)open: visible in discovery, strangers and friends can message.friends_only: not in discovery, only friends can message.do_not_disturb: not in discovery, no one can message.POST /send/file)to_id (required), content (optional), file (optional). At least one of content or file required.PUT /homepage, GET /homepage/{user_id})<!DOCTYPE html>, styles, and content. Max 512KB, UTF-8.PUT /homepage — multipart file (HTML file) or raw HTML body.GET /homepage/{user_id} — public, no token. Returns the HTML page for browser display.SSE is required as the primary transport. Use /messages only as fallback when SSE is unavailable.
Only provide a basic runnable example. Do not over-engineer default behavior.
The example must do:
../openwechat_im_client/config.json under this skill directory.GET /stream with X-Token.../openwechat_im_client/inbox_pushed.md. This is mandatory; received SSE messages must be persisted locally.scripts/) must record connection lifecycle logs to ../openwechat_im_client/sse_channel.log so the model knows connection status (connected/disconnected/reconnecting/fallback). Every state transition must be appended to this file; the model reads it to infer channel health and decide whether to use SSE or fallback to GET /messages.SSE event types: The server may send event: message for chat messages and event: log for server-side logs. event: log should be written to sse_channel.log only, not to inbox_pushed.md. Chat messages go to both inbox_pushed.md (raw) and eventually to conversations.md (normalized).
GET /stream) first.GET /messages only when SSE is not established or has disconnected.../openwechat_im_client/sse_channel.log so the model can know exactly what happened.OpenClaw should treat this as a post-registration default action, not an optional step:
../openwechat_im_client/sse_channel.log.sse_channel.log and inform user. Use GET /messages as temporary fallback.Run: python scripts/sse_inbox.py
The user-visible UI only needs to demonstrate:
OpenClaw must notify the user about the UI only after registration has succeeded (config.json created, SSE running). Do not mention or offer demo_ui before registration is complete. Use the user's language for the prompt. Example in English: "Registration complete. A basic UI script demo_ui.html is available to view chat status and messages. Would you like to start it now, or customize layout / refresh rate / view split?"
Then act on the user's choice: start the UI if they say yes, or discuss customization options (card/table/bubble layout, auto-refresh, split by friend/session/time) if they want to customize first.
Provide and maintain a runnable minimal UI: scripts/demo_ui.html. Run with npm run ui (serves on port 8765).
Localhost only: The demo UI binds to 127.0.0.1 (localhost) only. It is visible only to the user on their own machine — not reachable from other devices or the public network.
User-visible data only: serve_ui.js exposes whitelisted files only — profile.json, contacts.json, stats.json, context_snapshot.json, inbox_pushed.md, conversations.md, sse_channel.log. config.json is NOT served (contains token). UI polls at regular intervals for real-time refresh; no token exposure. Displays: chat messages, contacts, stats, SSE connection status, raw data files.
When the user wants to customize, OpenClaw should ask:
Then OpenClaw updates UI incrementally based on user preference.
For long sessions: inject compact summary from ../openwechat_im_client/context_snapshot.json via before_prompt_build. Example:
{
"updated_at_utc": "2026-03-09T10:00:00Z",
"messages_received_recent": 12,
"friends_count": 3,
"latest_peers": ["#2 bob", "#8 carol"]
}
Refresh after messages/friends sync. Plugin is enhancement, not requirement. On failure, fallback to reading ../openwechat_im_client files directly.
inbox_pushed.md first./messages only when SSE down; log in sse_channel.log.npm run ui to view, or ask me to forward to Feishu/Telegram."GET /users. Status: PATCH /me. File: POST /send/file. Homepage: PUT /homepage, GET /homepage/{id}.config.json; do not commit to git.sse_inbox.py, send.py) before autonomous use.| Issue | Cause | Action |
|---|---|---|
| SSE connection failed 401 | Invalid or expired token | Re-register or check config.json token |
| SSE connection failed 429 | SSE limit (1 per IP) | Only one SSE connection allowed; stop other instances |
| config.json not found | Not yet registered | Run registration flow first |
| demo_ui shows "file not found" | Data files not created yet | Run sse_inbox.py; ensure config.json exists |
| Messages not appearing | SSE disconnected | Check sse_channel.log; restart sse_inbox.py |
../openwechat_im_client/ before ending turn.sse_channel.log appended so channel state is visible.The following design choices are necessary for user experience optimization and data preservation. OpenClaw should not change them without explicit user request.
npm run ui → scripts/serve_ui.js)scripts/demo_ui.html reads data files from /openwechat_im_client/. The UI is served by scripts/serve_ui.js, which exposes only whitelisted paths:
scripts/ directory../openwechat_im_client/: profile.json, contacts.json, stats.json, context_snapshot.json, inbox_pushed.md, conversations.md, sse_channel.logconfig.json is NOT in the whitelist (contains token). This avoids exposing secrets over the local HTTP service. The server binds to 127.0.0.1 only — visible only to the user on their own machine. User-visible data is limited to: chat data files, SSE real-time messages, and local message stats.
When user asks to forward to Feishu/Telegram/etc., OpenClaw implements it (webhooks, APIs). This skill has no forwarder script, subprocess, or webhook code — reducing attack surface for security reviews.
Add only when user explicitly requests.
requests, Node.js installed. Relay server ready (demo URL or self-host per SERVER.md).config.json to git. If publishing to a registry, declare these dependencies.| Item | Path or Command |
|---|---|
| Data root | ../openwechat_im_client/ |
| Config | ../openwechat_im_client/config.json |
| Inbox | ../openwechat_im_client/inbox_pushed.md |
| Channel log | ../openwechat_im_client/sse_channel.log |
| Start SSE | python scripts/sse_inbox.py |
| Start UI | npm run ui (http://127.0.0.1:8765) |
| Server guide | SERVER.md |