@jerryliang122/openclaw-qqbot

中文文档
3.1.2发布于 2026/11/01TypeScriptESM + CJS构建来源已验证

QQ Bot channel plugin for OpenClaw (independently maintained fork)

原始使用文档
文档目录26 节
  1. 🚀 当前版本: v3.1.0
  2. ✨ 功能特性
  3. 📸 功能展示
  4. 💬 引用消息上下文
  5. 🎙️ 语音消息(STT)
  6. 📄 文件理解
  7. 🖼️ 图片理解
  8. 🎨 图片发送
  9. 🔊 语音发送
  10. ⏰ 定时提醒(主动消息)
  11. 📎 文件发送
  12. 🔐 命令执行审批
  13. 🎬 视频发送
  14. 🛠️ 斜杠指令
  15. 🚀 快速开始
  16. 第一步 — 在 QQ 开放平台创建机器人
  17. 第二步 — 安装 / 升级插件
  18. 第三步 — 测试
  19. ⚙️ 进阶配置
  20. 多账户配置(Multi-Bot)
  21. Webhook 传输模式
  22. 群聊配置
  23. 📚 文档与链接
  24. 🤝 贡献者
  25. 💖 致谢
  26. ⭐ Star History

简体中文 | English

QQ Bot

QQ Bot — OpenClaw 渠道插件

让你的 AI 助手接入 QQ — 私聊、群聊、富媒体,一个插件全搞定。

本仓库为独立维护的 fork,自 v1.0.0 起独立发版(与上游 2.x 版本线完全脱钩)。 运行要求:OpenClaw >= 2026.10.5;npm 包名 @jerryliang122/openclaw-qqbot。 与旧版本的差异及升级指南见 CHANGELOG。上游仓库:tencent-connect/openclaw-qqbot。

🚀 当前版本: v3.1.0

License QQ Bot Platform Node.js TypeScript


扫描二维码加入群聊,一起交流

QQ 群二维码

✨ 功能特性

功能说明
🔄 群消息排队群空闲时即时进入框架;agent 忙时到达的群消息(含不同发言人)在插件侧攒成一批,turn 结束后一次性发出——正在处理的任务绝不被打断
👁️ 房间事件(可选)全量模式群里,bot 像普通群成员一样读到每条消息;未 @ 的消息作为被动房间事件(只读,AI 想发言走主动 message 工具)
🔔 三种唤醒方式@提及、称呼唤醒(mentionPatterns,如「沈处」)、引用 bot 消息,均触发正常回复
📤 被动优先出站所有发送优先走被动回复(msg_id)以节省每天约 1000 条主动消息预算;配额感知降级,绝不硬失败
🔒 多场景支持C2C 私聊、群聊(@提及 / 自主发言 / 房间事件模式)
👥 群聊精细管控按群配置 @触发规则、工具权限、自定义提示词、历史模式、排队策略、房间事件策略
🌐 双传输模式WebSocket(默认)或 Webhook(HTTP 回调)— 配置切换
🖼️ 富媒体消息支持图片、语音、视频、文件的收发
🎙️ 语音能力 (STT/TTS)语音转文字自动转录 & 文字转语音回复
⏰ 定时推送支持定时任务触发后主动推送消息
🔗 URL 无限制私聊可直接发送 URL
⌨️ 输入状态实时显示"Bot 正在输入中…"状态
📝 Markdown完整支持 Markdown 格式消息
🛠️ 原生命令支持 OpenClaw 原生命令
💬 引用上下文解析用户回复的原始消息内容,注入 AI 上下文,让模型准确理解"在回复哪条消息"
📦 大文件支持大文件自动分片并行上传,最大支持 100 MB
🔐 命令执行审批AI 执行命令前通过按钮消息请求审批,点击即可允许或拒绝

📸 功能展示

说明: 本插件仅作为消息通道,负责在 QQ 和 OpenClaw 之间传递消息。图片理解、语音转录、AI 画图等能力取决于你配置的 AI 模型以及在 OpenClaw 中安装的 skill,而非插件本身提供。

💬 引用消息上下文

用户在 QQ 中引用某条消息发送时,插件会自动解析被引用的消息内容并注入 AI 上下文,让模型清楚地知道"用户在回复哪条消息",从而给出更准确的回复。支持文本及媒体消息(图片/语音/视频/文件),换设备后同样可用。

引用消息上下文演示

🎙️ 语音消息(STT)

配置 STT 后,插件会自动将语音转录为文字再交给 AI 处理。整个过程对用户完全透明——发语音就像发文字一样自然,AI 听得懂你在说什么。

你:(发送一段语音)"明天深圳天气怎么样"

QQBot:明天(3月7日 周六)深圳的天气预报 🌤️ ...

听语音演示

📄 文件理解

用户发文件给 AI,AI 同样能接住。不管是一本小说还是一份报告,AI 会自动识别文件内容并给出智能回复。

你:(发送《战争与和平》TXT 文件)

QQBot:收到!你上传了列夫·托尔斯泰的《战争与和平》中文版文本。从内容来看,这是第一章的开头……你想让我做什么?

AI理解用户发送的文件

🖼️ 图片理解

如果主模型支持视觉(如腾讯混元 hunyuan-vision),用户发图片 AI 也能看懂。这是多模态模型的通用能力,非插件专属功能。

你:(发送一张图片)

QQBot:哈哈,好可爱!这是QQ企鹅穿上小龙虾套装吗?🦞🐧 ...

图片理解演示

🎨 图片发送

你:画一只猫咪

QQBot:画好啦!一只可爱的简笔小猫咪🐱🎨

AI 可直接发送图片,支持本地文件路径和网络 URL。格式:jpg/png/gif/webp/bmp。

发图片演示

🔊 语音发送

你:给我讲一个笑话

QQBot:(发送一条语音消息)

AI 可直接发送语音消息。格式:mp3/wav/silk/ogg,无需安装 ffmpeg。

发语音演示

⏰ 定时提醒(主动消息)

你:5分钟后提醒我吃饭

QQBot:先确认已创建提醒,到点后再主动推送语音 + 文本提醒

该能力依赖 OpenClaw cron 调度与主动消息能力。若未收到提醒,常见原因是 QQ 侧拦截了机器人主动消息。

定时提醒演示

📎 文件发送

你:战争与和平的第一章截取一下发文件给我

QQBot:(发送 .txt 文件)

AI 可直接发送文件,任意格式均可。

发文件演示

v1.6.6 起支持大文件传输:图片最大 20MB,视频最大 30MB,附件最大 100MB,每日累计传输上限 2GB。

大文件传输演示

🔐 命令执行审批

当 AI 需要执行命令时,插件会通过 QQ 消息发送带按钮的审批请求,你可以点击 ✅ 允许一次、⭐ 始终允许 或 ❌ 拒绝 来控制命令是否执行。

通过 /bot-approve 指令可以管理审批模式(白名单 / 关闭 / 严格模式)。

命令执行审批演示

🎬 视频发送

你:发一个演示视频给我

QQBot:(发送视频)

AI 可直接发送视频,支持本地文件和公网 URL。

发视频演示

底层细节: 上传去重缓存、有序队列发送、音频格式多层降级。

🛠️ 斜杠指令

插件内置一组斜杠指令,在消息进入 AI 队列前拦截处理,即时响应,用于诊断和管理。

/bot-ping — 延迟测试

你:/bot-ping

QQBot:✅ pong!⏱ 延迟: 602ms(网络传输: 602ms,插件处理: 0ms)

测量从 QQ 服务器推送到插件响应的端到端延迟,细分网络传输和插件处理两段耗时。

Ping 演示

/bot-version — 版本信息

你:/bot-version

QQBot:🦞框架版本:OpenClaw 2026.10.5 / 🤖QQBot 插件版本:v3.1.0 / 🌟GitHub 仓库

一目了然查看框架版本、插件版本,并可直接跳转官方仓库。

Version 演示

/bot-help — 指令列表

你:/bot-help

QQBot:列出所有可用的斜杠指令及说明,指令可点击快速输入。

Help 演示

/bot-logs — 日志导出

你:/bot-logs

QQBot:📋 日志已打包(约 2000 行),正在发送文件… (发送 .txt 文件)

导出最近约 2000 行网关日志为文件,方便快速排查问题。

Logs 演示

用法查询

所有指令都支持 ? 后缀查看用法说明:

你:/bot-ping ?

QQBot:📖 /bot-ping 用法:…

/bot-approve — 审批配置管理

你:/bot-approve

QQBot:🔐 命令执行审批配置 — 开启审批 / 关闭审批 / 严格模式 / 恢复默认 / 查看当前配置

管理 AI 命令执行审批策略,支持以下子命令:

子命令说明
/bot-approve on开启审批(白名单模式,推荐)
/bot-approve off关闭审批,命令直接执行
/bot-approve always严格模式,每次执行都需审批
/bot-approve reset恢复框架默认值
/bot-approve status查看当前审批配置

/bot-clear-storage — 清理通过 QQBot 对话产生的文件以及下载的资源(保存在 OpenClaw 运行环境的主机上)

/bot-clear-storage 列出对话产生的文件以及下载的资源目录里的文件,使用/bot-clear-storage -- force确定删除。

/bot-group-always — 群消息响应模式切换

你:/bot-group-always

QQBot:🤖 群自主发言状态:❌ 仅被 @ 时回复

运行时动态切换群聊默认 @触发行为,修改即时持久化,无需重启:

子命令说明
/bot-group-always onAI 自主判断何时发言(无需 @)
/bot-group-always off仅在被 @ 时回复
/bot-group-always(无参数)查看当前设置

⚠️ 此指令修改账户级 defaultRequireMention,优先级低于具体群的 groups.{groupId}.requireMention 配置。

/bot-group-info — 群推送模式与生效配置查询(群内使用)

你:/bot-group-info(在群里发送)

QQBot:🤖 群信息 — 推送模式推断(AT 系 / 全量)、requireMention、排队策略、历史模式、房间事件策略、今日主动消息用量

回答「这个群为什么没上下文」这类排障问题:推送模式由群主拉 bot 进群时选择(仅 @ / @+最近N / 全量),此指令展示插件实际观测到的模式与所有生效配置值。

同时展示裁决后的未 @ 消息入站策略——来自哪一层(群级 / 按 agent / 全局)、以及是否因 message 工具不可用被自动降级。「我开了 room_event 但群里一直没反应」时先看这里。



🚀 快速开始

第一步 — 在 QQ 开放平台创建机器人

  1. 前往 QQ 开放平台,用手机 QQ 扫描页面二维码即可注册/登录。若尚未注册,扫码后系统会自动完成注册并绑定你的 QQ 账号。
Clipboard_Screenshot_1772980354
  1. 手机 QQ 扫码后选择同意,即完成注册,进入 QQ 机器人配置页。
  2. 点击创建机器人,即可直接新建一个 QQ 机器人。
创建机器人

⚠️ 机器人创建后会自动出现在你的 QQ 消息列表中,并发送第一条消息。但在完成下面的配置之前,发消息会提示"该机器人去火星了",属于正常现象。

机器人打招呼
  1. 在机器人页面中找到 AppID 和 AppSecret,分别点击右侧复制按钮,保存到记事本或备忘录中。AppSecret 不支持明文保存,离开页面后再查看会强制重置,请务必妥善保存。
找到 AppID 和 AppSecret

详细图文教程请参阅 官方指南。

第二步 — 安装 / 升级插件

无 scope 的 npm 包名 openclaw-qqbot 属于上游原项目——本 fork 以 @jerryliang122/openclaw-qqbot 发布。要求 OpenClaw >= 2026.10.5。

方式 A:从 npm 安装(推荐)

openclaw plugins install @jerryliang122/openclaw-qqbot

# 或安装指定版本
openclaw plugins install @jerryliang122/[email protected]

方式 B:从 GitHub 安装

openclaw plugins install git+https://github.com/jerryliang122/qqbot-openclaw.git

# 或安装指定版本
openclaw plugins install git+https://github.com/jerryliang122/qqbot-openclaw.git#v1.0.0

方式 C:源码安装

git clone https://github.com/jerryliang122/qqbot-openclaw.git
cd openclaw-qqbot

# 构建
npm install
npm run build

# 安装到 OpenClaw(方式一:link)
openclaw plugins link .

# 或(方式二:pack)
npm pack
openclaw plugins install ./jerryliang122-openclaw-qqbot-1.0.0.tgz

配置凭证

# 扫码登录(推荐,无需手动填写凭证)
openclaw channels login --channel qqbot

# 或手动配置
openclaw channels add --channel qqbot --token "AppID:AppSecret"

# 启动 / 重启
openclaw gateway restart

环境变量 QQBOT_APPID / QQBOT_SECRET 同样支持。

从旧版本(上游 2.x)升级? 请阅读 CHANGELOG——其中列出了全部破坏性变更(已移除的配置项、环境变量与行为)及迁移对照表。

第三步 — 测试

打开 QQ,找到你的机器人,发条消息试试!

聊天演示

⚙️ 进阶配置

多账户配置(Multi-Bot)

支持在同一个 OpenClaw 实例下同时运行多个 QQ 机器人。

配置方式

编辑 ~/.openclaw/openclaw.json,在 channels.qqbot 下增加 accounts 字段:

{
  "channels": {
    "qqbot": {
      "enabled": true,
      "appId": "111111111",
      "clientSecret": "secret-of-bot-1",

      "accounts": {
        "bot2": {
          "enabled": true,
          "appId": "222222222",
          "clientSecret": "secret-of-bot-2"
        },
        "bot3": {
          "enabled": true,
          "appId": "333333333",
          "clientSecret": "secret-of-bot-3"
        }
      }
    }
  }
}

说明:

  • 顶层的 appId / clientSecret 是默认账户(accountId = "default")
  • accounts 下的每个 key(如 bot2、bot3)就是该账户的 accountId
  • 每个账户都可以独立配置 enabled、name、allowFrom、systemPrompt 等字段
  • 也可以不配顶层默认账户,只在 accounts 里配置所有机器人
  • 不想把密钥写在配置里时,可以改用文件:"clientSecretFile": "/etc/openclaw/qqbot.secret"(文件内容会去掉首尾空白后作为密钥使用;运行期才读盘,所以轮换文件后重启该账户即生效)。默认账户与命名账户都支持。

通过 CLI 添加第二个机器人(如果框架支持 --account 参数):

openclaw channels add --channel qqbot --account bot2 --token "222222222:secret-of-bot-2"

向指定账户的用户发送消息

使用 openclaw message send 发消息时,需要通过 --account 参数指定使用哪个机器人发送:

# 使用默认机器人发送(不指定 --account 时自动使用 default)
openclaw message send --channel "qqbot" \
  --target "qqbot:c2c:OPENID" \
  --message "hello from default bot"

# 使用 bot2 发送
openclaw message send --channel "qqbot" \
  --account bot2 \
  --target "qqbot:c2c:OPENID" \
  --message "hello from bot2"

Target 格式支持:

格式说明
qqbot:c2c:OPENID私聊
qqbot:group:GROUP_OPENID群聊
qqbot:channel:CHANNEL_ID频道

⚠️ 注意:每个机器人的用户 OpenID 是不同的。机器人 A 收到的用户 OpenID 不能用机器人 B 去发消息,否则会返回 500 错误。必须用对应机器人的 accountId 去给该机器人的用户发消息。

工作原理

  • 启动 openclaw gateway 后,所有 enabled: true 的账户会同时启动连接(WebSocket 或 Webhook,取决于 transport 配置)
  • 每个账户独立维护 Token 缓存(基于 appId 隔离),互不干扰
  • 接收消息时,日志会带上 [qqbot:accountId] 前缀方便排查

Webhook 传输模式

默认情况下,插件通过 WebSocket 连接 QQ 平台(出站连接,无需公网 IP)。你也可以切换为 Webhook 模式,由 QQ 平台主动 POST 事件到你的 HTTP 端点。

WebSocket(默认)Webhook
连接方式插件主动连接 QQ 网关QQ 平台 POST 到你的服务器
公网 IP不需要需要
适用场景开发调试、单实例部署生产环境、水平扩展、Serverless
会话恢复支持 RESUME无状态,无需恢复
签名验证平台内置插件自动 Ed25519 验签

配置方式

{
  "channels": {
    "qqbot": {
      "appId": "111111111",
      "clientSecret": "your-secret",
      "transport": "webhook",
      "webhook": {
        "path": "/qqbot/webhook"
      }
    }
  }
}
字段默认值说明
transport"websocket""websocket" 或 "webhook"
webhook.path"/qqbot/webhook"接收回调的 HTTP 路径

平台配置步骤

  1. 登录 QQ 开放平台 → 开发设置 → 消息接收方式
  2. 选择 HTTP 回调
  3. 填写回调 URL:https://your-domain.com/qqbot/webhook
  4. 平台发送 op:13 验证请求,插件自动处理签名验证
  5. 验证通过后,所有事件将以 POST 方式推送到该地址

群聊配置

插件提供灵活的群聊管控能力,支持按群定制触发规则、工具权限和 AI 行为策略。

@提及触发模式(requireMention)

默认情况下,群聊中必须 @机器人才会触发 AI 回复。你可以通过配置让 AI 自主判断是否需要发言:

模式配置值行为
仅 @时回复true(默认)群消息中只有 @了机器人才会触发回复
自主发言falseAI 自主判断每条消息是否需要回复,无需 @

优先级链(从高到低):

具体群 groups.{groupOpenid}.requireMention
  > 通配符 groups."*".requireMention
    > 账户级 defaultRequireMention
      > 默认值 true

配置示例:

{
  "channels": {
    "qqbot": {
      // 账户级:所有群的默认行为
      "defaultRequireMention": false,

      "accounts": {
        "default": {
          "groups": {
            "*": {
              // 通配符:所有群的兜底规则
              "requireMention": false
            },
            "GROUP_OPENID": {
              // 单群覆盖:这个群仍然需要 @
              "requireMention": true
            }
          }
        }
      }
    }
  }
}

使用场景举例:

  • 工作群设为 requireMention: true — 避免 AI 对每条闲聊都插嘴
  • 专属 AI 陪伴群设为 requireMention: false — 像真人一样自然参与对话
  • 通过 /bot-group-always on|off 指令可在运行时动态切换账户级默认值

其他群配置项

除 requireMention 外,每个群还支持以下配置:

字段类型默认值说明
ignoreOtherMentionsbooleanfalse是否忽略 @了其他人但没 @机器人的消息。开启后这类消息直接丢弃,不记录历史、不触发 AI
toolPolicy"full" | "restricted" | "none""restricted"群聊中 AI 可使用的工具范围。full=全部可用;restricted=限制敏感工具(如命令执行、文件操作);none=禁止所有工具调用
promptstring内置默认提示词该群专属的系统提示词,会追加到全局 systemPrompt 之后
historyLimitnumber20群历史消息缓存条数(0 禁用)
historyMode"clear" | "rolling""clear"clear:每次回复后清空历史(旧行为)。rolling:bot 自己的发言也计入历史,回复后裁剪到 bot 最后一条发言之后(AI 能看到自己上次说到哪)
unmentionedInbound"user_request" | "room_event""user_request"room_event:像普通群成员一样读到所有消息,未 @ 的作为被动房间事件(详见下文;需群主开启全量推送模式)。也可在 agents.entries.<id>.groupChat.unmentionedInbound(按 agent)或 messages.groupChat.unmentionedInbound(全局)声明
roomEventRequireMessageToolbooleantrueroom_event 下是否强制要求 message 工具可用。true(默认):工具确定不可用时该群自动降级为 user_request(恢复正常回复权)并打一条 WARN;false:不降级,保持严格静默语义(由用户自行保证工具面)
toolsobject—群级工具白名单(allow / alsoAllow / deny),显式声明时原样透传给框架,优先级高于 toolPolicy。⚠️ room_event 群若在此排除 message,该群将失去唯一发声通道(插件会自动降级并告警)
coalesceobject{enabled: true, strategy: "plugin", maxBatchSize: 10, maxHoldMs: 300000}群消息排队与合批配置(详见下文「群消息排队与合批」)。enabled=false→排队但不合并(followup)

群消息排队与合批(插件侧)

群消息的排队与合并由插件自己完成:当某个群的 agent 正在工作时,到达的消息会攒进一个批次,turn 结束后一次性作为一个 turn 发给框架。

为什么不用框架的 collect 队列:框架 followup 队列的 collect 模式按 senderId 分组,且分组时遇到第一个 key 不同的消息就断开 ⇒ 同一群里不同发言人发的消息永远合并不了。而「群里几个人同时问、bot 忙完一次性回」恰恰是群聊最常见的诉求。插件侧合批按群为键,因此可以跨发言人合并。

字段类型默认值说明
enabledbooleantruefalse → 只排队不合并(followup),不打断正在处理的 turn
strategy"plugin" | "framework""plugin"plugin=插件侧合批(可跨发言人);framework=交回框架 collect 队列(仅同发言人的连续消息可合并)
maxBatchSizeinteger10单批最多合并多少条群消息。超出时丢弃较早的消息,并在合并正文里留一行丢弃说明(模型不会静默缺内容)
maxHoldMsinteger300000单批最长持有时长(毫秒)。兜底用:turn 永久挂起时批次会滞留内存且随进程重启丢失。0=永不强制冲刷

回落链与其他群配置项一致:群级 coalesce > 账号级 groupCoalesce > 默认值。

行为示例:

成员A:「问题1」→ 群空闲 → 立即进入框架,开始处理
成员B:「问题2」→ agent 忙 → 进批次
成员C:「问题3」→ agent 忙 → 进批次

「问题1」处理完成 → [问题2, 问题3] 一次性发出 → AI 看到合并后的上下文,只回一次

合并后的 Web UI 形态:

Carol                          ← 气泡标签 = 载体(批次内最后一条)的发送者
[消息 1/3]
[Alice (U_ALICE)] 问题1 (@you)

[消息 2/3]
[Bob (U_BOB)] 问题2

[消息 3/3]
[Carol (U_CAROL)] 问题3
  • 一个批次在 Web UI 上是一个用户气泡(不是每条一个):正文按 [消息 i/N] 分节,每节带该条自己的 [sender (openid)] 归属。
  • 气泡上方的发送者标签是载体(最后一条)的发送者——各发言人的区分靠正文里的逐条归属。标签刻意不改成「3 条消息」这类合成值:同一个字段也会进模型的 Conversation info.sender,合成标签会让模型误判作者。
  • 批次挂起期间这些消息还没进框架,所以 Web UI 不会逐条回显(QQ 群里成员自己的消息照常可见)。
  • room_event 群的批次同理,其 transcript 行也不再带 #ROBOT1.0_… 前缀(消息 id 与正文在平台层是分开的,此前是框架把两者合并进了同一行)。

已知限制:当 turn 被框架排队(defer 到活动 turn 之后)时,插件的 dispatch promise 在「仅入队」时就 resolve,busy 信号会提前归零 ⇒ 那一小段窗口内到达的群消息不会被合批。消息仍全部送达、顺序不变,只是没被合成一轮。

建议同时调大框架队列上限:OpenClaw followup 队列默认 messages.queue.cap: 20,溢出时会丢弃最老的一条并在 transcript 里显示 [Queue overflow] Dropped N messages due to cap.。插件侧合批会显著减少进入该队列的条目数,但繁忙群仍建议调大:

{
  "messages": {
    "queue": {
      "cap": 60,
      "drop": "summarize"
    }
  }
}

房间事件模式(全量模式群,可选)

前提:群主把该群的推送范围设为「接收所有消息」(全量模式)。AT 模式的群收不到未 @ 消息,此配置无效果。

"groups": {
  "GROUP_OPENID": { "unmentionedInbound": "room_event" }
}

该开关的回落链与其他通道一致(群级最具体,框架级兜底):

channels.qqbot.groups.<id>.unmentionedInbound          (群级,最高)
  > agents.entries.<id>.groupChat.unmentionedInbound    (按 agent)
    > messages.groupChat.unmentionedInbound             (全局)
      > "user_request"                                   (默认)

开启后的行为:

  • 被 @ / 被称呼 / 引用 bot 消息 → 正常回复(完整回复权)
  • 其余所有消息 → 被动房间事件:AI 只读上下文,最终文本不投递(结构性沉默),想发言必须主动调用 message 工具
  • 房间事件绝不打断正在处理的任务,只排队
  • 房间事件若以错误告终,不会往群里发失败提示(保持安静,错误只落日志);同群里被 @ 的那条仍按正常 turn 走失败提示
  • ⚠️ 成本提示:每条消息跑一次推理(「读」消息),活跃群请按群显式开启

message 工具是唯一的声音出口,且插件会替你把关:房间事件的最终文本永远不投递,能说话的唯一通道是 message 工具。若该群的有效工具面里没有 message,群里就会永久沉默——这正是 2026-10-06 线上事故的形态(空允许清单把工具集清空)。

因此插件在进入房间事件模式前会检查有效工具面,确定不可用时自动把该群降级回 user_request(恢复正常回复权),每群只告警一次:

[room-event] group=GROUP_X 降级为 user_request:群工具白名单不含 message 工具。…

判定刻意保守,只在确定缺失时降级:

工具面判定
groups.<id>.tools.allow(非空)不含 message(且 alsoAllow 也不含)不可用 → 降级
groups.<id>.tools.deny 命中 message(精确或通配,如 mess*)不可用 → 降级
agent / 全局显式 allow 白名单不含 message不可用 → 降级
agent / 全局显式 deny 含 message 或 *不可用 → 降级
allow 缺失/为空 + alsoAllow 非空不限制(框架会把它合成隐式全放行)
agent tools.profile(含 minimal / coding)不算阻塞——框架在房间事件 turn 会强制授予 message
其余情况(含未知 profile)视为可用

想主动保持严格静默语义,关掉降级即可:

{ "groups": { "GROUP_OPENID": { "unmentionedInbound": "room_event", "roomEventRequireMessageTool": false } } }

可见回复模式:messages.groupChat.visibleReplies 决定群 turn 的最终文本是否自动投递("automatic",默认)或只走 message 工具("message_tool")。房间事件恒为 "message_tool"——即上面的结构性沉默;同一群里被 @ 的那条仍自动投递。

messages.groupChat.* 只作用于群/频道会话;私聊读的是 messages.visibleReplies——群里配的可见回复模式不会把私聊也压成静默。

称呼唤醒(群友不打 @、直接叫名字):在 agents 段(不在 channels.qqbot 下)配置:

"agents": {
  "entries": { "default": { "groupChat": { "mentionPatterns": ["沈处"] } } }
}

(旧的 agents.list 数组形态同样兼容。)

称呼命中在门控层同样算「在叫 bot」——消息不会在到达 agent 之前被丢掉,房间事件群与普通群都生效。

误唤醒有兜底:LLM 判断「只是在聊我、不是在叫我」时可输出 NO_REPLY 保持沉默(框架自动注入该指引,无需改提示词)。

完整群配置示例:

{
  "channels": {
    "qqbot": {
      "defaultRequireMention": false,
      "accounts": {
        "default": {
          "groups": {
            "*": {
              "requireMention": true,
              "toolPolicy": "restricted",
              "ignoreOtherMentions": true
            },
            "WORK_GROUP_OPENID": {
              "requireMention": true,
              "toolPolicy": "none",
              "prompt": "你是工作助手,只回答与工作相关的问题"
            },
            "FRIEND_GROUP_OPENID": {
              "requireMention": false,
              "toolPolicy": "full",
              "prompt": "你是群里的朋友,轻松随意地聊天"
            }
          }
        }
      }
    }
  }
}

私聊访问控制(dmPolicy / allowFrom)

通过 dmPolicy 控制哪些用户可以私聊机器人(默认 allowlist):

策略说明
"allowlist"(默认)仅 allowFrom 白名单中的用户可私聊
"open"所有用户均可私聊
"pairing"白名单 + 配对码:陌生用户私聊时收到配对码,管理员 /bot-pairing approve <code> 放行
"disabled"禁止所有私聊
{
  "channels": {
    "qqbot": {
      "dmPolicy": "allowlist",
      "allowFrom": ["USER_OPENID_1", "USER_OPENID_2"]
    }
  }
}

allowFrom 为空或含 "*" 时不做限制(所有用户均可私聊)。

⚠️ OpenID 是 per-account 的:机器人 A 拿到的用户 OpenID 在机器人 B 上无意义,多账号场景下每个账号都要单独配置自己的 allowFrom。

被拒绝时会收到提示:私聊消息的 OpenID 不在白名单里时,机器人不会静默丢弃,而是回复一条诊断消息,其中包含你自己的 OpenID 与配置位置——直接把它加进 allowFrom 保存配置即生效(热更新,无需重启)。同一用户 10 分钟内只提示一次,每个账号每天最多提示 50 条(防刷屏)。

群访问控制(groupPolicy)

通过 groupPolicy 控制哪些群允许机器人加入并接收消息:

策略说明
"open"(默认)所有群均可使用
"allowlist"仅 groupAllowFrom 白名单中的群可使用
"disabled"禁止所有群聊
{
  "channels": {
    "qqbot": {
      "groupPolicy": "allowlist",
      "groupAllowFrom": ["ALLOWED_GROUP_OPENID_1", "ALLOWED_GROUP_OPENID_2"]
    }
  }
}

groupAllowFrom 为空或含 "*" 时不做限制。

群场景只在明确叫 bot 时才回告:本群不在 groupAllowFrom 里且消息 @ 了机器人或引用了机器人的消息时,机器人会公开回复一条含 groupOpenid 的诊断消息;普通闲聊(未点名 bot)仍然静默丢弃,避免在陌生群里对外广播白名单配置。

也可通过 /bot-group-always 指令 在运行时动态切换账户级默认值,无需重启。


STT(语音转文字)— 自动转录用户发来的语音消息

转录统一走框架音频理解管线(openclaw/plugin-sdk/media-understanding-runtime),STT 配置只认框架级 tools.media.models(与内置 Telegram 通道一致)——插件不再自带 OpenAI 兼容 HTTP 调用:

{
  "tools": {
    "media": {
      "models": [
        {
          "type": "cli",
          "command": "your-asr-cli",
          "args": ["-m", "your-model", "{{AttachmentPath}}"],
          "maxBytes": 52428800,
          "timeoutSeconds": 120,
          "capabilities": ["audio"]
        }
      ]
    }
  }
}

也支持 provider 形态(如 { "provider": "openai", "model": "whisper-1", "capabilities": ["audio"] })。capabilities 必须包含 "audio"——模型列表按能力标签选择,无标签条目不参与语音转录。

语音消息处理顺序(2026-10 起硬编码,无插件级开关):

  1. 框架 STT 已配置(tools.media.models 存在 capabilities 含 "audio" 的条目)→ 下载语音、转换(SILK→WAV)后经框架管线转录;严格信框架——转录失败或为空时输出占位文本([Voice message - transcription failed]),不回退平台转写。
  2. 框架 STT 未配置 → 直接采用 QQ 平台转写(asr_refer_text,QQ 平台对语音消息自动 STT 并随事件 JSON 下发)作为唯一来源——无需下载、不发起任何外部调用。
  3. 未配置且无平台转写 → 占位文本([Voice message - transcription unavailable]),音频 URL 仍通过 - Voice: 行引用。

channels.qqbot.stt 整块已废弃并被忽略(旧凭证键 + 历史 enabled/asrFallback 开关,2026-10-04 移除);检测到任何键时会打一次性迁移提示日志。STT 启停只由框架配置控制——删掉 tools.media.models 的 audio 条目、或设 tools.media.audio.enabled: false 即关闭框架转录。

TTS(文字转语音)— 机器人发送语音消息

优先级配置路径作用域
1(highest)channels.qqbot.tts插件专属
2(fallback)messages.tts框架级
{
  "channels": {
    "qqbot": {
      "tts": {
        "provider": "your-provider",
        "model": "your-tts-model",
        "voice": "your-voice"
      }
    }
  }
}
  • provider — 引用 models.providers 中的 key,自动继承 baseUrl 和 apiKey
  • voice — 语音音色
  • 设置 enabled: false 可禁用(默认:true)
  • 配置后,AI 可生成并发送语音消息

流式回复 — 仅 C2C 私聊

通过 QQ 流式接口逐段下发回复(打字机效果)。群聊不支持流式(平台限制)。未配置即关闭。

{
  "channels": {
    "qqbot": {
      "streaming": {
        "mode": "partial",
        "sendMode": "stream"
      }
    }
  }
}
字段默认说明
mode(未配置 = 关闭)"partial" 开启流式接收;"off" 关闭
sendMode"stream""stream" — QQ 流式打印机(打字机;一段 = 一条消息:模型在一轮里产出的每段 assistant 消息各成一条消息,内容原样送达、互不重叠,绝不跨段截断拼接;工具调用只封口当前段、不结束整轮)。"static" — 生成期间只累积,结束时一条完整消息发出(无打字机)
  • 流式分片(session.update)仍消耗触发消息的被动回复配额
  • 流式出错时控制器自动降级为单条静态消息

正在输入指示器(typing)— 仅 C2C 私聊

机器人收到私聊消息后会显示"正在输入中…",并在 AI 处理期间周期性续期。

{
  "channels": {
    "qqbot": {
      "typing": {
        "enabled": true,
        "intervalMs": 20000
      }
    }
  }
}
  • enabled — 是否启用(默认:true),设为 false 可完全关闭
  • intervalMs — 续期间隔毫秒(默认:20000)。QQ 客户端退出聊天界面再进入后指示器会消失,只有新的推送才会重新显示,因此需要续期;受 QPS 限制,低于 20000 的值会被钳制到 20000
  • 配额说明:typing 通知与回复消息共享同一条用户消息的被动回复配额(QQ 开放平台同一条消息被动回复上限约 5 条)。被动配额耗尽后,typing 与回复消息一样自动降级为主动发送(不带 msg_id),续期不会中断
  • 中间消息续期:机器人发出消息(如思维链等中间输出)后 QQ 客户端会终止指示器显示;若框架任务仍在进行,插件会在消息发出 5 秒后自动补发一次续期恢复显示(同样受 20s QPS 间距保护)。最终回复发出后任务完成,不再补发

📚 文档与链接

🤝 贡献者

感谢所有为本项目做出贡献的开发者!上游贡献者见 tencent-connect/openclaw-qqbot。

💖 致谢

特别感谢 @sliverp 对项目的核心贡献!

sliverp

感谢腾讯云Lighthouse的深度合作,养小龙虾,首选腾讯云Lighthouse!

腾讯云 Lighthouse

⭐ Star History

Star History Chart

版本与发布记录

@jerryliang122/openclaw-qqbot 共发布 29 个版本,首次发布于 2026/09/10;过去 12 个月发布了 29 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.1.2latest2026/11/012 天前
3.1.12026/10/304 天前
3.1.02026/10/2410 天前
3.0.12026/10/2211 天前
3.0.02026/10/2212 天前
2.8.12026/10/2212 天前

关于 @jerryliang122/openclaw-qqbot 的常见问题

@jerryliang122/openclaw-qqbot 是什么?

OpenClaw QQ Bot频道插件(独立维护的分叉)

如何安装 @jerryliang122/openclaw-qqbot?

在项目目录运行 npm install @jerryliang122/openclaw-qqbot,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:openclaw(>=2026.10.5)、@tencent-connect/qqbot-connector(1.2.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@jerryliang122/openclaw-qqbot 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@jerryliang122/openclaw-qqbot 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@jerryliang122/openclaw-qqbot 可以商用吗?

@jerryliang122/openclaw-qqbot 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@jerryliang122/openclaw-qqbot 还在维护吗?

最新版本 3.1.2 发布于 2026/11/01(2 天前);至今共发布 29 个版本,其中过去 12 个月发布了 29 个;首次发布于 2026/09/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。