# tencent/openclaw-weixin architecture

> Architecture diagram of the GitHub repository tencent/openclaw-weixin, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-05-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/tencent/openclaw-weixin
- Repository: https://github.com/tencent/openclaw-weixin

## Overview

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: [`src/runtime.ts`](https://github.com/tencent/openclaw-weixin/blob/main/src/runtime.ts) (Runtime), [`src/api/api.ts`](https://github.com/tencent/openclaw-weixin/blob/main/src/api/api.ts) (API client), [`src/messaging/process-message.ts`](https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/process-message.ts) (Process msg), [`src/messaging/send.ts`](https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/send.ts) (Send)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_boundary["Plugin boundary"]
  node_index["Entry<br/>[index.ts]"]
  node_plugin_meta["Plugin meta<br/>plugin manifest"]
end

subgraph group_core["Core runtime"]
  node_runtime["Runtime<br/>composition root<br/>[runtime.ts]"]
  node_channel["Channel<br/>adapter<br/>[channel.ts]"]
  node_compat["Compat<br/>host gate<br/>[compat.ts]"]
end

subgraph group_api["Backend API"]
  node_api_client["API client<br/>HTTP client<br/>[api.ts]"]
  node_api_types["API types<br/>contract types<br/>[types.ts]"]
  node_config_cache["Config cache<br/>cached config<br/>[config-cache.ts]"]
  node_session_guard["Session guard<br/>request guard<br/>[session-guard.ts]"]
end

subgraph group_auth["Auth & accounts"]
  node_accounts[("Accounts<br/>account store<br/>[accounts.ts]")]
  node_login_qr["QR login<br/>login flow<br/>[login-qr.ts]"]
  node_pairing["Pairing<br/>[pairing.ts]"]
end

subgraph group_messaging["Messaging"]
  node_inbound["Inbound<br/>polling pipeline<br/>[inbound.ts]"]
  node_process_message["Process msg<br/>normalizer<br/>[process-message.ts]"]
  node_send["Send<br/>outbound pipeline<br/>[send.ts]"]
  node_send_media["Send media<br/>media outbound<br/>[send-media.ts]"]
  node_context_store[("Context store<br/>session state")]
end

subgraph group_media["Media & CDN"]
  node_cdn_upload["CDN upload<br/>upload flow<br/>[cdn-upload.ts]"]
  node_media_dl["Media download<br/>download flow<br/>[media-download.ts]"]
  node_silk["SILK transcode<br/>codec<br/>[silk-transcode.ts]"]
end

subgraph group_state["State & ops"]
  node_storage_dir[("State dir<br/>persistence root<br/>[state-dir.ts]")]
  node_sync_buf[("Sync buffer<br/>cursor store<br/>[sync-buf.ts]")]
  node_monitor["Monitor<br/>watchdog<br/>[monitor.ts]"]
  node_logger["Logger<br/>logging<br/>[logger.ts]"]
  node_redact["Redact<br/>sanitizer<br/>[redact.ts]"]
end

node_index -->|"gates"| node_compat
node_index -->|"loads"| node_runtime
node_plugin_meta -->|"declares"| node_index
node_runtime -->|"uses"| node_accounts
node_runtime -->|"orchestrates"| node_api_client
node_runtime -->|"starts"| node_inbound
node_runtime -->|"routes"| node_send
node_runtime -->|"reports"| node_monitor
node_runtime -->|"persists"| node_storage_dir
node_runtime -->|"binds"| node_channel
node_channel -->|"isolates"| node_context_store
node_api_client -->|"speaks"| node_api_types
node_api_client -->|"checks"| node_session_guard
node_api_client -->|"reads"| node_config_cache
node_login_qr -->|"creates"| node_pairing
node_pairing -->|"stores"| node_accounts
node_inbound -->|"normalizes"| node_process_message
node_process_message -->|"consults"| node_context_store
node_process_message -->|"sanitizes"| node_redact
node_send -->|"delegates"| node_send_media
node_send -->|"posts"| node_api_client
node_send_media -->|"uploads"| node_cdn_upload
node_send_media -->|"posts"| node_api_client
node_cdn_upload -->|"encodes"| node_silk
node_cdn_upload -.->|"pairs"| node_media_dl
node_media_dl -->|"sanitizes"| node_redact
node_monitor -->|"logs"| node_logger
node_logger -->|"masks"| node_redact
node_storage_dir -->|"contains"| node_sync_buf

click node_index "https://github.com/tencent/openclaw-weixin/blob/main/index.ts"
click node_plugin_meta "https://github.com/tencent/openclaw-weixin/blob/main/openclaw.plugin.json"
click node_runtime "https://github.com/tencent/openclaw-weixin/blob/main/src/runtime.ts"
click node_channel "https://github.com/tencent/openclaw-weixin/blob/main/src/channel.ts"
click node_compat "https://github.com/tencent/openclaw-weixin/blob/main/src/compat.ts"
click node_api_client "https://github.com/tencent/openclaw-weixin/blob/main/src/api/api.ts"
click node_api_types "https://github.com/tencent/openclaw-weixin/blob/main/src/api/types.ts"
click node_config_cache "https://github.com/tencent/openclaw-weixin/blob/main/src/api/config-cache.ts"
click node_session_guard "https://github.com/tencent/openclaw-weixin/blob/main/src/api/session-guard.ts"
click node_accounts "https://github.com/tencent/openclaw-weixin/blob/main/src/auth/accounts.ts"
click node_login_qr "https://github.com/tencent/openclaw-weixin/blob/main/src/auth/login-qr.ts"
click node_pairing "https://github.com/tencent/openclaw-weixin/blob/main/src/auth/pairing.ts"
click node_inbound "https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/inbound.ts"
click node_process_message "https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/process-message.ts"
click node_send "https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/send.ts"
click node_send_media "https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/send-media.ts"
click node_cdn_upload "https://github.com/tencent/openclaw-weixin/blob/main/src/cdn/cdn-upload.ts"
click node_media_dl "https://github.com/tencent/openclaw-weixin/blob/main/src/media/media-download.ts"
click node_silk "https://github.com/tencent/openclaw-weixin/blob/main/src/media/silk-transcode.ts"
click node_storage_dir "https://github.com/tencent/openclaw-weixin/blob/main/src/storage/state-dir.ts"
click node_sync_buf "https://github.com/tencent/openclaw-weixin/blob/main/src/storage/sync-buf.ts"
click node_monitor "https://github.com/tencent/openclaw-weixin/blob/main/src/monitor/monitor.ts"
click node_logger "https://github.com/tencent/openclaw-weixin/blob/main/src/util/logger.ts"
click node_redact "https://github.com/tencent/openclaw-weixin/blob/main/src/util/redact.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_index,node_plugin_meta,node_storage_dir,node_sync_buf,node_monitor,node_logger,node_redact toneBlue
class node_runtime,node_channel,node_compat toneAmber
class node_api_client,node_api_types,node_config_cache,node_session_guard toneMint
class node_accounts,node_login_qr,node_pairing toneRose
class node_inbound,node_process_message,node_send,node_send_media,node_context_store toneIndigo
class node_cdn_upload,node_media_dl,node_silk toneTeal
```

## Components

### Plugin boundary

Host entrypoint and compatibility gate.

- [Entry](https://github.com/tencent/openclaw-weixin/blob/main/index.ts): plugin entry · OpenClaw plugin entrypoint and startup gate. · `index.ts`
- [Plugin meta](https://github.com/tencent/openclaw-weixin/blob/main/openclaw.plugin.json): plugin manifest · Plugin metadata and declared compatibility constraints. · `openclaw.plugin.json`

### Core runtime

Composition root and channel/session wiring.

- [Runtime](https://github.com/tencent/openclaw-weixin/blob/main/src/runtime.ts): composition root · Long-lived orchestration for config, sessions, API, and message loops. · `src/runtime.ts`
- [Channel](https://github.com/tencent/openclaw-weixin/blob/main/src/channel.ts): adapter · Maps WeChat identities and events into OpenClaw channel semantics. · `src/channel.ts`
- [Compat](https://github.com/tencent/openclaw-weixin/blob/main/src/compat.ts): host gate · Checks host/runtime compatibility before the plugin loads. · `src/compat.ts`

### Backend API

HTTP contract and request/session safeguards.

- [API client](https://github.com/tencent/openclaw-weixin/blob/main/src/api/api.ts): HTTP client · Primary backend request boundary for WeChat operations. · `src/api/api.ts`
- [API types](https://github.com/tencent/openclaw-weixin/blob/main/src/api/types.ts): contract types · Typed request/response shapes for backend endpoints. · `src/api/types.ts`
- [Config cache](https://github.com/tencent/openclaw-weixin/blob/main/src/api/config-cache.ts): cached config · Caches backend-provided configuration and tickets. · `src/api/config-cache.ts`
- [Session guard](https://github.com/tencent/openclaw-weixin/blob/main/src/api/session-guard.ts): request guard · Blocks API calls when the session is invalid or stale. · `src/api/session-guard.ts`

### Auth & accounts

QR login and persisted account state.

- [Accounts](https://github.com/tencent/openclaw-weixin/blob/main/src/auth/accounts.ts): account store · Persists and indexes WeChat account records. · `src/auth/accounts.ts`
- [QR login](https://github.com/tencent/openclaw-weixin/blob/main/src/auth/login-qr.ts): login flow · QR-code authentication and pairing entryflow. · `src/auth/login-qr.ts`
- [Pairing](https://github.com/tencent/openclaw-weixin/blob/main/src/auth/pairing.ts): pairing flow · Creates or refreshes account bindings during login. · `src/auth/pairing.ts`

### Messaging

Inbound normalization and outbound send paths.

- [Inbound](https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/inbound.ts): polling pipeline · Long-polling ingestion of raw backend updates. · `src/messaging/inbound.ts`
- [Process msg](https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/process-message.ts): normalizer · Converts raw updates into channel events and filters them. · `src/messaging/process-message.ts`
- [Send](https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/send.ts): outbound pipeline · Routes text and control messages back to WeChat. · `src/messaging/send.ts`
- [Send media](https://github.com/tencent/openclaw-weixin/blob/main/src/messaging/send-media.ts): media outbound · Uploads media first, then sends references through the API. · `src/messaging/send-media.ts`
- **Context store**: session state · Tracks conversation context tokens for isolation.

### Media & CDN

Upload, download, and transcoding for media payloads.

- [CDN upload](https://github.com/tencent/openclaw-weixin/blob/main/src/cdn/cdn-upload.ts): upload flow · Builds and executes encrypted CDN upload requests. · `src/cdn/cdn-upload.ts`
- [Media download](https://github.com/tencent/openclaw-weixin/blob/main/src/media/media-download.ts): download flow · Fetches and decodes media payloads from backend/CDN. · `src/media/media-download.ts`
- [SILK transcode](https://github.com/tencent/openclaw-weixin/blob/main/src/media/silk-transcode.ts): codec · Transcodes voice media for WeChat-compatible delivery. · `src/media/silk-transcode.ts`

### State & ops

Local persistence, monitoring, and diagnostics.

- [State dir](https://github.com/tencent/openclaw-weixin/blob/main/src/storage/state-dir.ts): persistence root · Defines the plugin's local state directory. · `src/storage/state-dir.ts`
- [Sync buffer](https://github.com/tencent/openclaw-weixin/blob/main/src/storage/sync-buf.ts): cursor store · Persists polling cursors and sync state across restarts. · `src/storage/sync-buf.ts`
- [Monitor](https://github.com/tencent/openclaw-weixin/blob/main/src/monitor/monitor.ts): watchdog · Runtime health and operational monitoring hook. · `src/monitor/monitor.ts`
- [Logger](https://github.com/tencent/openclaw-weixin/blob/main/src/util/logger.ts): logging · Structured logging support for runtime operations. · `src/util/logger.ts`
- [Redact](https://github.com/tencent/openclaw-weixin/blob/main/src/util/redact.ts): sanitizer · Masks secrets and sensitive payloads in logs. · `src/util/redact.ts`

## Connections

- 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.
