Moltbot China is an open-source extension set that adds China-region messaging channels to Moltbot (Feishu, DingTalk, WeCom, QQ). The goal is to provide simple, reliable chat connectivity and a clean plugin surface for Moltbot users in China, with voice features implemented via Node.
openclaw-china/
├── package.json
├── pnpm-workspace.yaml
├── tsconfig.base.json
│
├── packages/
│ ├── channels/ # @openclaw-china/channels 统一包
│ │ ├── package.json
│ │ ├── moltbot.plugin.json
│ │ ├── clawdbot.plugin.json
│ │ ├── tsconfig.json
│ │ └── src/
│ │ └── index.ts
│ │
│ └── shared/ # 共享工具库
│ ├── package.json
│ ├── tsconfig.json
│ └── src/
│ ├── index.ts
│ ├── logger/ # 日志工具
│ │ ├── index.ts
│ │ └── logger.ts
│ ├── policy/ # 策略引擎
│ │ ├── index.ts
│ │ ├── dm-policy.ts
│ │ └── group-policy.ts
│ ├── http/ # HTTP 工具
│ │ ├── index.ts
│ │ ├── client.ts
│ │ └── retry.ts
│ ├── file/ # 文件工具
│ │ ├── index.ts
│ │ └── file-utils.ts
│ └── types/
│ └── common.ts
│
├── extensions/
│ ├── dingtalk/ # @openclaw-china/dingtalk
│ ├── feishu/ # @openclaw-china/feishu-china
│ ├── wecom/ # @openclaw-china/wecom
│ ├── wecom-app/ # @openclaw-china/wecom-app
│ └── qqbot/ # @openclaw-china/qqbot
│
└── doc/
├── architecture.md # 架构设计文档
├── moltbot/ # Moltbot 插件规范
└── reference-projects/ # 参考实现
- Each plugin must include
openclaw.plugin.jsonwith a JSON Schema (even if empty). - Plugins register channels via
api.registerChannel({ plugin }). - Channel configuration lives under
channels.<id>; multi-account useschannels.<id>.accounts.<accountId>. - Keep channels focused on message receive/send. Defer extra features unless required.
- Voice features use Node-based tooling (no Python voice stack).
extensions/<channel-id>/openclaw.plugin.jsonextensions/<channel-id>/package.jsonextensions/<channel-id>/index.tsextensions/<channel-id>/src/*
- All code must be written in TypeScript.
- Use
strict: truein tsconfig. - Prefer
async/awaitover callbacks. - Avoid
any; useunknownwith type guards when needed. - Handle errors at async boundaries; never swallow silently.
- Set timeouts on network requests.
- Use
pnpm release:allfor full release, orpnpm release:channel --channel <id>for single channel release. - Default publish tag is
latest. - Only publish to
nextwhen explicitly passing--tag next. --versionaccepts:x.y.z(stable semver, publishes as-is)x.y.z.w(legacy 4-segment input, normalized to npm semverx.y.z-w)x.y.z-w(npm prerelease style)
- Auto bump rules (when
--versionis omitted):- Baseline is the higher one between local
package.jsonversion and npm published versions. - If baseline is
x.y.z, next isx.y.(z+1). - If baseline is
x.y.z.w/x.y.z-w, next isx.y.z.(w+1)(published asx.y.z-(w+1)).
- Baseline is the higher one between local
- Version comparison in release script uses numeric
major.minor.patch.revisionordering (missing revision =0). - Recommended commands:
- Stable release (latest):
pnpm release:all --version 2026.3.5 - Pre-release to next:
pnpm release:all --version 2026.3.5.1 --tag next
- Stable release (latest):
- Treat all inbound messages as untrusted input.
- Do not commit real tokens, secrets, or IDs; use obvious placeholders.
- When aligning channel behavior with OpenClaw, remember the reply dispatcher can skip payloads with
onSkipreasons:empty,silent, orheartbeat. Use these to avoid sending non-user-visible messages.