How tencent/openclaw-weixin works
1. What this repository is
This is an OpenClaw channel plugin for WeChat. It is not a standalone app; it runs inside the OpenClaw plugin runtime and bridges OpenClaw’s channel abstraction to a WeChat backend API over HTTP JSON.
2. Top-level plugin boundary
The plugin entrypoint is index.ts, with metadata in openclaw.plugin.json. At startup it checks host compatibility and refuses to load if the running OpenClaw version is outside the supported range. That version gate is part of the plugin’s outer boundary.
3. Main runtime orchestration
src/runtime.ts is the likely composition root: it ties together config loading, session/account state, the API client, inbound polling, outbound send paths, and monitoring. This is where the plugin’s long-lived loops and channel lifecycle are probably assembled.
4. Backend API integration layer
src/api/ is the primary network boundary to the WeChat backend. api.ts and types.ts define the HTTP contract described in the README: getupdates, sendmessage, getuploadurl, getconfig, and sendtyping. Supporting modules like config-cache.ts and session-guard.ts indicate response caching and session validity checks around that API.
5. Authentication and account management
src/auth/ handles QR-code login and account persistence. Files like login-qr.ts, pairing.ts, accounts.ts, and the account-related tests suggest a flow where scanning a QR code creates or refreshes a saved account entry, likely with multiple WeChat accounts supported concurrently.
6. Inbound message pipeline
src/messaging/inbound.ts and src/messaging/process-message.ts are the message ingestion path. The backend is polled via long-polling getupdates; raw WeChat messages are then normalized, filtered, and turned into OpenClaw channel events. context-token-store.ts, debug-mode.ts, error-notice.ts, and slash-commands.ts indicate extra handling for conversation context, diagnostics, user-facing errors, and command-like messages.
7. Outbound message pipeline
src/messaging/send.ts and src/messaging/send-media.ts implement the reverse path from OpenClaw to WeChat. Text messages go directly through the API, while media messages are routed through the CDN/upload flow first and then sent as message items referencing the uploaded media.
8. Media and CDN subsystem
src/cdn/ and src/media/ are a distinct subsystem for file handling. The README shows media is uploaded and downloaded via AES-128-ECB encrypted CDN payloads. aes-ecb.ts, cdn-upload.ts, cdn-url.ts, pic-decrypt.ts, and upload.ts together suggest URL construction, encryption/decryption, and upload orchestration. media-download.ts, mime.ts, and silk-transcode.ts indicate download handling, MIME detection, and voice/voice-note transcoding for WeChat’s SILK format.
9. Session, DM scope, and context isolation
src/channel.ts, src/compat.ts, and src/messaging/context-token-store.ts shape how the plugin maps WeChat identities into OpenClaw channel/session semantics. The README’s session.dmScope setting and the presence of session-related guards imply the plugin isolates direct-message conversations by account/channel/peer when multiple accounts are online.
10. State and local persistence
src/storage/ contains the local persistence layer used by the plugin: state-dir.ts defines where plugin state lives, and sync-buf.ts stores polling cursors/sync buffers. This is the local boundary between ephemeral runtime and durable account/session state.
11. Configuration and host compatibility
src/config/config-schema.ts validates plugin config, while src/api/config-cache.ts appears to cache backend-provided configuration such as typing tickets. src/api/session-guard.ts enforces that requests are only made when the session is valid. Together these modules keep host config, backend config, and login/session state consistent.
12. Operational/diagnostic support
src/monitor/monitor.ts suggests a runtime watchdog or health/telemetry hook. src/util/logger.ts and src/util/redact.ts support structured logging with sensitive-data masking, which matters because this plugin handles auth tokens, account IDs, and message payloads.
13. Data flow summary
The main flow is: OpenClaw loads the plugin → plugin validates compatibility and loads local state → user scans QR code to pair/login → backend session/account info is stored locally → getupdates long-polling feeds inbound messages into OpenClaw → outbound replies, typing indicators, and media uploads go back through the backend API/CDN paths → session and sync cursors are persisted for the next restart.
14. Testing and confidence boundary
The many *.test.ts files indicate the repository emphasizes unit-level validation for each subsystem: API behavior, auth/account lifecycle, CDN/media handling, message filtering, compatibility, and storage. That suggests a modular architecture with relatively clear seams between protocol, storage, and message transformation layers.
Main entry points: runtime.ts Runtime · api.ts API client · process-message.ts Process msg · send.ts Send
Components 25
Plugin boundary
Host entrypoint and compatibility gate.
- Entry · OpenClaw plugin entrypoint and startup gate.
index.ts - Plugin meta · Plugin metadata and declared compatibility constraints.
openclaw.plugin.json
Core runtime
Composition root and channel/session wiring.
Backend API
HTTP contract and request/session safeguards.
- API client · Primary backend request boundary for WeChat operations.
src/api/api.ts - API types · Typed request/response shapes for backend endpoints.
src/api/types.ts - Config cache · Caches backend-provided configuration and tickets.
src/api/config-cache.ts - Session guard · Blocks API calls when the session is invalid or stale.
src/api/session-guard.ts
Auth & accounts
QR login and persisted account state.
Messaging
Inbound normalization and outbound send paths.
- Inbound · Long-polling ingestion of raw backend updates.
src/messaging/inbound.ts - Process msg · Converts raw updates into channel events and filters them.
src/messaging/process-message.ts - Send · Routes text and control messages back to WeChat.
src/messaging/send.ts - Send media · Uploads media first, then sends references through the API.
src/messaging/send-media.ts - Context store · Tracks conversation context tokens for isolation.
Media & CDN
Upload, download, and transcoding for media payloads.
- CDN upload · Builds and executes encrypted CDN upload requests.
src/cdn/cdn-upload.ts - Media download · Fetches and decodes media payloads from backend/CDN.
src/media/media-download.ts - SILK transcode · Transcodes voice media for WeChat-compatible delivery.
src/media/silk-transcode.ts
State & ops
Local persistence, monitoring, and diagnostics.
- State dir · Defines the plugin's local state directory.
src/storage/state-dir.ts - Sync buffer · Persists polling cursors and sync state across restarts.
src/storage/sync-buf.ts - Monitor · Runtime health and operational monitoring hook.
src/monitor/monitor.ts - Logger · Structured logging support for runtime operations.
src/util/logger.ts - Redact · Masks secrets and sensitive payloads in logs.
src/util/redact.ts
Connections 29
- Entry → Compat: gates · Refuses startup when the host is incompatible.
- Entry → Runtime: loads · Hands control to the long-lived plugin runtime.
- Plugin meta → Entry: declares · Provides plugin metadata and supported host range.
- Runtime → Accounts: uses · Loads and updates persisted account state.
- Runtime → API client: orchestrates · Coordinates backend calls through the API boundary.
- Runtime → Inbound: starts · Begins inbound polling and event processing.
- Runtime → Send: routes · Dispatches outbound channel messages.
- Runtime → Monitor: reports · Feeds runtime health and diagnostics.
- Runtime → State dir: persists · Reads and writes local plugin state.
- Runtime → Channel: binds · Connects WeChat identities to OpenClaw channel semantics.
- Channel → Context store: isolates · Uses context tokens to separate conversations.
- API client → API types: speaks · Implements the backend request/response contract.
- API client → Session guard: checks · Avoids requests when the session is invalid.
- API client → Config cache: reads · Uses cached backend config when available.
- QR login → Pairing: creates · QR login flows into account pairing.
- Pairing → Accounts: stores · Persists paired account records.
- Inbound → Process msg: normalizes · Transforms raw backend updates into channel events.
- Process msg → Context store: consults · Uses context state during message handling.
- Process msg → Redact: sanitizes · Redacts sensitive data in diagnostics and errors.
- Send → Send media: delegates · Routes media messages through the media path.
- Send → API client: posts · Sends outbound text and control messages.
- Send media → CDN upload: uploads · Uploads media before sending message references.
- Send media → API client: posts · Completes media send through backend API calls.
- CDN upload → SILK transcode: encodes · Prepares voice media for compatible delivery when needed.
- CDN upload → Media download: pairs · Shares the media boundary for fetch/upload workflows.
- Media download → Redact: sanitizes · Keeps media diagnostics free of sensitive payloads.
- Monitor → Logger: logs · Emits operational events through structured logging.
- Logger → Redact: masks · Removes secrets before log emission.
- State dir → Sync buffer: contains · Provides the durable home for sync state.