OpenClaw OneBot 11 Channel Plugin 🐧
中文
OpenClaw 的 OneBot 11 协议通道插件,让 QQ 成为 OpenClaw 一等消息通道。
支持 NapCat、go-cqhttp 等所有兼容 OneBot 11 协议的 QQ 机器人框架。
说明:
- 插件
id是openclaw-onebot - 通道
id仍然是onebot - 因此
plugins.allow/plugins.entries/plugins.installs使用openclaw-onebot channels.onebot保持不变- 当前版本对齐 OpenClaw
2026.4.9/ plugin-sdk2026.4.9,并声明setupEntry
功能
- 🔌 原生通道插件 — QQ 与 Discord / Telegram / WhatsApp 同级
- 📨 私聊和群聊收发消息
- 😀 Reaction 支持(群聊) — 通过 NapCat
set_msg_emoji_like给群消息加表情回应;QQ 私聊目前不稳定/通常不生效 - 👍 群聊自动 reaction — 对入站群消息自动点表情,可配置开关,默认开启
- 🌊 Block streaming — 支持 OpenClaw 分块回复,QQ 端会连续收到多条流式消息
- 🧭 OpenClaw 文本命令全支持 —
/status、/help、/commands、/model、/new、/reset等命令走统一文本命令链路 - 🎤 语音完整链路 — QQ 语音 (SILK/AMR) → MP3 → STT → TTS → 发送 QQ 语音
- 📦 消息聚合 — 连续多条消息 1.5s 内自动合并(类似 Telegram 风格)
- 🖼️ 图片、语音、文件附件发送
- 🛠️ 通用
sendMedia出站适配,delivery recovery / mirror / message tool 等通路都能发送图片、语音、文件 - 🔄 WebSocket 自动重连(指数退避)
- 🔒 可选 access token 鉴权
- 🎯
allowFrom消息来源过滤(私聊/群聊/用户级别) - ✅ 116 个测试用例全部通过
- 📈 覆盖率可通过
npm run coverage复核
架构
QQ 机器人框架 (NapCat / go-cqhttp)
├── WebSocket → 接收消息 (含语音 SILK/AMR 自动转 MP3)
└── HTTP API → 发送消息 (文字/图片/语音)
↕
OpenClaw OneBot Plugin (ChannelPlugin)
├── 消息聚合 (1.5s debounce)
├── 语音处理 (SILK → pilk → PCM → ffmpeg → MP3)
└── allowFrom 过滤
↕
OpenClaw Gateway (统一消息管线)
├── STT (语音转文字)
├── Agent 对话
├── Block streaming (多段消息回复)
├── Reaction action
└── TTS (文字转语音) → sendRecord → QQ 语音
快速开始
1. 安装插件
# 自动安装
bash scripts/install.sh
# 或手动(先在仓库根目录准备发布包)
npm install && npm run prepare:clawhub:plugin
mkdir -p ~/.openclaw/plugins/onebot
cp -r .clawhub-plugin/openclaw-onebot-plugin/* ~/.openclaw/plugins/onebot/
cd ~/.openclaw/plugins/onebot && npm install --omit=dev --omit=peer --no-package-lock --no-audit --no-fund
scripts/install.sh 会先在源码仓库生成 .clawhub-plugin/openclaw-onebot-plugin 精简发布包,再把这份运行时 payload 安装到 OpenClaw 目录,并自动尝试执行 scripts/sync-openclaw-cli.mjs,把 --shared-dir / --container-shared-dir 接到本机 OpenClaw CLI。
2. 配置
在 openclaw.json 中添加:
{
"plugins": {
"allow": ["openclaw-onebot"],
"entries": {
"openclaw-onebot": {
"enabled": true
}
}
},
"channels": {
"onebot": {
"enabled": true,
"wsUrl": "ws://your-host:3001",
"httpUrl": "http://your-host:3001",
"accessToken": "your_token",
"sharedDir": "/Users/you/napcat/shared",
"containerSharedDir": "/shared",
"groupAutoReact": true,
"groupAutoReactEmojiId": 1
}
}
}
说明:
- 插件配置键使用
openclaw-onebot - 通道配置键使用
channels.onebot - 如果你是通过本地路径/扩展目录安装插件,通常还需要在
plugins.installs.openclaw-onebot中指向实际安装目录;如果用 OpenClaw 自己的插件安装流程,这一项会自动生成
也支持环境变量:
ONEBOT_WS_URL=ws://your-host:3001
ONEBOT_HTTP_URL=http://your-host:3001
ONEBOT_ACCESS_TOKEN=your_token # 可选
OneBot setup 也支持:
--token wsUrl,httpUrl[,accessToken[,sharedDir[,containerSharedDir]]]- 或
openclaw channels add --channel onebot --shared-dir <hostPath> --container-shared-dir /shared - 如果 OpenClaw 升级后覆盖了 CLI dist,可在插件目录执行
npm run sync:openclaw-cli重新同步参数接线
3. 重启 Gateway
openclaw gateway restart
高级配置
{
"channels": {
"onebot": {
"enabled": true,
"wsUrl": "ws://your-host:3001",
"httpUrl": "http://your-host:3001",
"accessToken": "your_token",
"sharedDir": "/Users/you/napcat/shared",
"containerSharedDir": "/shared",
"allowFrom": ["private:12345", "group:67890"],
"groupAutoReact": true,
"groupAutoReactEmojiId": 1
}
}
}
| 参数 | 说明 |
|---|---|
allowFrom | 消息来源白名单 — private:<QQ号>、group:<群号>、或 *(允许所有) |
accessToken | HTTP API 用 Bearer token,WebSocket 用 query 参数 |
sharedDir | 宿主机共享目录;默认 ~/napcat/shared,用于把语音/图片 stage 给 NapCat |
containerSharedDir | 容器内共享目录;默认 /shared,与 sharedDir 对应 |
groupAutoReact | 是否对入站群消息自动添加 reaction,默认 true |
groupAutoReactEmojiId | 群聊自动 reaction 使用的 QQ emoji id,默认 1 |
Reaction 与流式回复
- Reaction
- 插件实现了 OpenClaw channel action
react - 通过 NapCat
set_msg_emoji_like对群消息或指定群消息message_id添加表情 - QQ 私聊 reaction 目前不可靠,接口可能返回成功,但不会真正落到消息上
- 入站群消息还支持自动 reaction,受
groupAutoReact/groupAutoReactEmojiId控制,默认开启
- 插件实现了 OpenClaw channel action
- 流式回复
- 这里支持的是 OpenClaw block streaming
- QQ 端表现为连续多条分块消息,不是“编辑同一条消息”的 draft stream
- 开启方式:
{
"agents": {
"defaults": {
"blockStreamingDefault": "on"
}
}
}
- 可选调优:
{
"channels": {
"onebot": {
"blockStreamingCoalesce": {
"minChars": 80,
"idleMs": 600
}
}
}
}
验证
- Reaction
- 先让家庭群里出现一条新消息
- 从 gateway 日志里拿到
msg=<message_id> - 再执行:
npm run build
npm run react-test -- --message-id <message_id> --emoji 76
-
当前建议只把这项验证用于群聊消息;私聊 reaction 在 QQ/NapCat 上通常不生效
-
Streaming
- 在 OpenClaw 配置里开启
agents.defaults.blockStreamingDefault = "on" - 然后在 QQ 里发一条明确要求“分段回复”的消息
- 成功时,QQ 会连续收到多条消息,日志里会出现
deliver(block),最后再有deliver(final)
- 在 OpenClaw 配置里开启
语音支持(可选)
支持 QQ 语音消息的完整自动处理链路:
- 入站:QQ 语音 (SILK/AMR) → 下载 → 转 MP3 → OpenClaw STT 转文字 → Agent 生成回复
- 出站:Agent 回复 → TTS 生成音频 →
sendRecord发送 QQ 语音
依赖:
ffmpeg— 音频格式转换uv— 运行pilk解码 SILK 格式(AMR 仅需 ffmpeg)
不需要语音功能时可以跳过这些依赖。
消息目标格式
private:<QQ号>— 私聊消息group:<群号>— 群聊消息<QQ号>— 自动识别为私聊
NapCat 部署参考
推荐使用 Docker 部署 NapCat:
# docker-compose.yml
services:
napcat:
image: mlikiowa/napcat-docker:latest
restart: always
ports:
- "3001:3001" # OneBot 11 WS + HTTP
- "6099:6099" # WebUI
volumes:
- ./napcat-data:/app/.config/QQ
- ./shared:/shared # 文件共享目录
开发
npm install
npm test # 116 tests
npm run build # 编译 TypeScript
npm run coverage # 覆盖率报告
npm run sync:openclaw-cli # 重新同步 OpenClaw CLI 的 shared-dir 参数
发布准备
npm ci --ignore-scripts
npm run release:check
npm publish
git tag v<package-version>
git push origin main --tags
说明:
npm run release:check会串行执行build、全量vitest、npm pack --dry-run、prepare:clawhub:plugin- ClawHub 发布产物输出到
.clawhub-plugin/openclaw-onebot-plugin/ - GitHub Release 建议直接复用同一个
v<package-version>tag
English
An OpenClaw native channel plugin that connects to NapCat, go-cqhttp, or any OneBot 11 compatible QQ bot framework.
Note:
- Plugin
id:openclaw-onebot - Channel
id:onebot - Use
openclaw-onebotinplugins.allow/plugins.entries/plugins.installs - Keep
channels.onebotunchanged - This release targets OpenClaw
2026.4.9/ plugin-sdk2026.4.9and declaressetupEntry
Features
- 🔌 Native channel plugin — QQ on par with Discord / Telegram / WhatsApp
- 📨 Private & group chat (inbound + outbound)
- 😀 Reaction support (groups) — react to a QQ group message via NapCat
set_msg_emoji_like; QQ private-chat reactions are currently unreliable - 👍 Automatic group reactions — auto-react to inbound group messages with a configurable switch, enabled by default
- 🌊 Block streaming — OpenClaw partial replies arrive as multiple QQ messages
- 🎤 Full voice pipeline — QQ voice (SILK/AMR) → MP3 → STT → TTS → send QQ voice
- 📦 Message batching — auto-merge rapid messages within 1.5s (Telegram-style)
- 🖼️ Image, audio, and file attachments
- 🛠️ Generic
sendMediaoutbound adapter so delivery recovery, mirror, and message-tool paths can all send images, audio, and files - 🔄 WebSocket auto-reconnect with exponential backoff
- 🔒 Optional access token authentication
- 🎯
allowFromfiltering (private/group/user-level) - 🧭 Full OpenClaw text-command passthrough (
/status,/help,/commands,/model,/new,/reset, etc.) - ✅ 116 tests passing
- 📈 Coverage can be re-generated with
npm run coverage
Quick Start
1. Install
# Auto install
bash scripts/install.sh
# Or manual (prepare the release payload from the repo root first)
npm install && npm run prepare:clawhub:plugin
mkdir -p ~/.openclaw/plugins/onebot
cp -r .clawhub-plugin/openclaw-onebot-plugin/* ~/.openclaw/plugins/onebot/
cd ~/.openclaw/plugins/onebot && npm install --omit=dev --omit=peer --no-package-lock --no-audit --no-fund
scripts/install.sh prepares .clawhub-plugin/openclaw-onebot-plugin in the source repo first, installs that trimmed runtime payload, and then runs scripts/sync-openclaw-cli.mjs so the local OpenClaw CLI keeps the OneBot --shared-dir / --container-shared-dir flags wired in after install.
2. Configure
Add to openclaw.json:
{
"plugins": {
"allow": ["openclaw-onebot"],
"entries": {
"openclaw-onebot": {
"enabled": true
}
}
},
"channels": {
"onebot": {
"enabled": true,
"wsUrl": "ws://your-host:3001",
"httpUrl": "http://your-host:3001",
"groupAutoReact": true,
"groupAutoReactEmojiId": 1
}
}
}
Notes:
- Use
openclaw-onebotfor plugin config keys - Keep runtime channel config under
channels.onebot - If you install from a local path / extension directory, you may also need
plugins.installs.openclaw-onebotpointing at the actual install directory; OpenClaw usually writes this automatically during plugin install
Or via environment variables:
ONEBOT_WS_URL=ws://your-host:3001
ONEBOT_HTTP_URL=http://your-host:3001
ONEBOT_ACCESS_TOKEN=your_token # optional
OneBot setup also supports:
--token wsUrl,httpUrl[,accessToken[,sharedDir[,containerSharedDir]]]- or
openclaw channels add --channel onebot --shared-dir <hostPath> --container-shared-dir /shared - if an OpenClaw upgrade overwrites the installed CLI dist, run
npm run sync:openclaw-clifrom the plugin directory to re-apply the flags
3. Restart Gateway
openclaw gateway restart
Voice Support (Optional)
End-to-end voice flow:
- Inbound: QQ voice (SILK/AMR) → download → MP3 → OpenClaw STT → Agent reply
- Outbound: Agent reply → TTS audio →
sendRecord→ QQ voice
Dependencies: ffmpeg + uv (for SILK decoding via pilk). Skip if text/image only.
Reactions and Streaming Replies
- Reactions
- The plugin implements the OpenClaw
reactchannel action - It maps to NapCat
set_msg_emoji_like - Group-message reactions are supported
- QQ private-chat reactions are currently unreliable: the API may return success while no visible reaction is persisted
- Inbound group messages can also be auto-reacted, controlled by
groupAutoReact/groupAutoReactEmojiId, enabled by default
- The plugin implements the OpenClaw
- Streaming replies
- This plugin supports OpenClaw block streaming
- QQ receives multiple incremental messages instead of a single edited draft message
- Enable it with:
{
"agents": {
"defaults": {
"blockStreamingDefault": "on"
}
}
}
- Optional coalescing hint for OneBot:
{
"channels": {
"onebot": {
"blockStreamingCoalesce": {
"minChars": 80,
"idleMs": 600
}
}
}
}
Verification
- Reaction
- Send a fresh QQ group message first
- Read the inbound
msg=<message_id>from the gateway log - Then run:
npm run build
npm run react-test -- --message-id <message_id> --emoji 76
-
For now, treat this as a group-chat verification flow; private-chat reactions are not a reliable capability
-
Streaming
- Enable
agents.defaults.blockStreamingDefault = "on"in OpenClaw config - Send a QQ prompt that explicitly asks for chunked / stepwise output
- Success looks like multiple QQ messages plus
deliver(block)entries in the gateway log, followed bydeliver(final)
- Enable
Configuration
| Option | Description |
|---|---|
allowFrom | Whitelist — private:<qq>, group:<id>, or * (allow all) |
accessToken | Bearer token for HTTP, query param for WebSocket |
sharedDir | Host-side shared directory; defaults to ~/napcat/shared for staging outbound media |
containerSharedDir | Container-side mount path; defaults to /shared and should map to sharedDir |
groupAutoReact | Whether to auto-react to inbound group messages; defaults to true |
groupAutoReactEmojiId | QQ emoji id used for automatic group reactions; defaults to 1 |
Target Format
private:<qq_number>— Private messagegroup:<group_id>— Group message<qq_number>— Auto-detected as private
Development
npm install
npm test # Run 116 tests
npm run build # Compile TypeScript
npm run coverage # Coverage report
npm run sync:openclaw-cli # Re-apply shared-dir CLI wiring after OpenClaw upgrades
Release Prep
npm ci --ignore-scripts
npm run release:check
npm publish
git tag v<package-version>
git push origin main --tags
Notes:
npm run release:checkrunsbuild, the fullvitestsuite,npm pack --dry-run, andprepare:clawhub:plugin- The ClawHub payload is written to
.clawhub-plugin/openclaw-onebot-plugin/ - Reuse the same
v<package-version>tag when drafting the GitHub Release
License
MIT