# @jerryliang122/openclaw-qqbot 中文文档

规范地址：https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/

版本：3\.1\.2
npm 元数据更新时间：2026-11-01T07:02:14.626Z
中文译文更新时间：2026-11-01T13:29:35.958Z
软件包许可：未声明

本文由上游 README 机器翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40jerryliang122/openclaw-qqbot
原文对照：https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/?lang=original
项目主页：https://github.com/jerryliang122/qqbot-openclaw
源码仓库：https://github.com/jerryliang122/qqbot-openclaw

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：3.9 MB，128 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：2 个
- peer 依赖：openclaw \>=2026\.10\.5，@tencent-connect/qqbot-connector 1\.2\.0
- 首次发布：2026-09-10T01:58:36.564Z
- 最新版本发布：2026-11-01T07:02:14.246Z
- 已发布版本数：29（近 12 个月 29 个）

## 中文简介

OpenClaw QQ Bot频道插件（独立维护的分叉）

## 安装

```sh
npm install @jerryliang122/openclaw-qqbot
```

也可以使用：`pnpm add @jerryliang122/openclaw-qqbot`、`yarn add @jerryliang122/openclaw-qqbot`、`bun add @jerryliang122/openclaw-qqbot`

## README

**简体中文 | [English](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/README.md)**

![QQ Bot](https://img.shields.io/badge/%F0%9F%A4%96-QQ_Bot-blue?style=for-the-badge)

# QQ Bot — OpenClaw 渠道插件

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

> 本仓库为**独立维护的 fork**，自 v1.0.0 起独立发版（与上游 2.x 版本线完全脱钩）。 运行要求：OpenClaw `>= 2026.10.5`；npm 包名 [`@jerryliang122/openclaw-qqbot`](https://www.npmjs.com/package/@jerryliang122/openclaw-qqbot)。 与旧版本的差异及升级指南见 [CHANGELOG](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/CHANGELOG.md)。上游仓库：[tencent-connect/openclaw-qqbot](https://github.com/tencent-connect/openclaw-qqbot)。

### 🚀 当前版本： `v3.1.0`

[![License](https://img.shields.io/badge/license-MIT-green)](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/LICENSE) [![QQ Bot](https://img.shields.io/badge/QQ_Bot-API_v2-red)](https://bot.q.qq.com/wiki/) [![Platform](https://img.shields.io/badge/OpenClaw-%3E%3D2026.10.5-orange)](https://github.com/jerryliang122/qqbot-openclaw) [![Node.js](https://img.shields.io/badge/Node.js-%3E=18-339933?logo=node.js&logoColor=white)](https://nodejs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)

  

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

![QQ 群二维码](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/developer-group.png)

* * *

## ✨ 功能特性

| 功能 | 说明 |
| --- | --- |
| 🔄 **群消息排队** | 群空闲时即时进入框架；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 上下文，让模型清楚地知道"用户在回复哪条消息"，从而给出更准确的回复。支持文本及媒体消息（图片/语音/视频/文件），换设备后同样可用。

![引用消息上下文演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/ref-msg.png)

### 🎙️ 语音消息（STT）

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

> **你**：_（发送一段语音）_"明天深圳天气怎么样"
> 
> **QQBot**：明天（3月7日 周六）深圳的天气预报 🌤️ ...

![听语音演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/voice-stt.jpg)

### 📄 文件理解

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

> **你**：_（发送《战争与和平》TXT 文件）_
> 
> **QQBot**：收到！你上传了列夫·托尔斯泰的《战争与和平》中文版文本。从内容来看，这是第一章的开头……你想让我做什么？

![AI理解用户发送的文件](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/file-understand.jpg)

### 🖼️ 图片理解

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

> **你**：_（发送一张图片）_
> 
> **QQBot**：哈哈，好可爱！这是QQ企鹅穿上小龙虾套装吗？🦞🐧 ...

![图片理解演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/image-understand.jpg)

### 🎨 图片发送

> **你**：画一只猫咪
> 
> **QQBot**：画好啦！一只可爱的简笔小猫咪🐱🎨

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

![发图片演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/image-send.jpg)

### 🔊 语音发送

> **你**：给我讲一个笑话
> 
> **QQBot**：_（发送一条语音消息）_

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

![发语音演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/voice-send.jpg)

### ⏰ 定时提醒（主动消息）

> **你**：5分钟后提醒我吃饭
> 
> **QQBot**：先确认已创建提醒，到点后再主动推送语音 + 文本提醒

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

![定时提醒演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/reminder.jpg)

### 📎 文件发送

> **你**：战争与和平的第一章截取一下发文件给我
> 
> **QQBot**：_（发送 .txt 文件）_

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

![发文件演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/file-send.jpg)

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

![大文件传输演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/large-file-transfer.jpg)

### 🔐 命令执行审批

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

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

![命令执行审批演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/approve.png)

### 🎬 视频发送

> **你**：发一个演示视频给我
> 
> **QQBot**：_（发送视频）_

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

![发视频演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/video-send.jpg)

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

### 🛠️ 斜杠指令

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

#### `/bot-ping` — 延迟测试

> **你**：`/bot-ping`
> 
> **QQBot**：✅ pong！⏱ 延迟: 602ms（网络传输: 602ms，插件处理: 0ms）

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

![Ping 演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/slash-ping.jpg)

#### `/bot-version` — 版本信息

> **你**：`/bot-version`
> 
> **QQBot**：🦞框架版本：OpenClaw 2026.10.5 / 🤖QQBot 插件版本：v3.1.0 / 🌟GitHub 仓库

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

![Version 演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/slash-version.jpg)

#### `/bot-help` — 指令列表

> **你**：`/bot-help`
> 
> **QQBot**：列出所有可用的斜杠指令及说明，指令可点击快速输入。

![Help 演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/slash-help.jpg)

#### `/bot-logs` — 日志导出

> **你**：`/bot-logs`
> 
> **QQBot**：📋 日志已打包（约 2000 行），正在发送文件… _（发送 .txt 文件）_

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

![Logs 演示](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/slash-logs.jpg)

#### 用法查询

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

> **你**：`/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 on` | AI 自主判断何时发言（无需 @） |
| `/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 开放平台](https://q.qq.com/)，用**手机 QQ 扫描页面二维码**即可注册/登录。若尚未注册，扫码后系统会自动完成注册并绑定你的 QQ 账号。

![Clipboard\_Screenshot\_1772980354](https://github.com/user-attachments/assets/d8491859-57e8-47e4-9d39-b21138be54d0)

2.  手机 QQ 扫码后选择**同意**，即完成注册，进入 QQ 机器人配置页。
3.  点击**创建机器人**，即可直接新建一个 QQ 机器人。

![创建机器人](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/create-robot.png)

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

![机器人打招呼](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/bot-say-hello.jpg)

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

![找到 AppID 和 AppSecret](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/find-appid-secret.png)

> 详细图文教程请参阅 [官方指南](https://cloud.tencent.com/developer/article/2626045)。

### 第二步 — 安装 / 升级插件

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

**方式 A：从 npm 安装（推荐）**

```bash
openclaw plugins install @jerryliang122/openclaw-qqbot

# 或安装指定版本
openclaw plugins install @jerryliang122/openclaw-qqbot@3.1.0
```

**方式 B：从 GitHub 安装**

```bash
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：源码安装**

```bash
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
```

**配置凭证**

```bash
# 扫码登录（推荐，无需手动填写凭证）
openclaw channels login --channel qqbot

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

# 启动 / 重启
openclaw gateway restart
```

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

**从旧版本（上游 2.x）升级？** 请阅读 [CHANGELOG](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/CHANGELOG.md)——其中列出了全部破坏性变更（已移除的配置项、环境变量与行为）及迁移对照表。

### 第三步 — 测试

打开 QQ，找到你的机器人，发条消息试试！

![聊天演示](https://github.com/user-attachments/assets/b2776c8b-de72-4e37-b34d-e8287ce45de1)

* * *

## ⚙️ 进阶配置

### 多账户配置（Multi-Bot）

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

#### 配置方式

编辑 `~/.openclaw/openclaw.json`，在 `channels.qqbot` 下增加 `accounts` 字段：

```json
{
  "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` 参数）：

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

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

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

```bash
# 使用默认机器人发送（不指定 --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 验签 |

#### 配置方式

```json
{
  "channels": {
    "qqbot": {
      "appId": "111111111",
      "clientSecret": "your-secret",
      "transport": "webhook",
      "webhook": {
        "path": "/qqbot/webhook"
      }
    }
  }
}
```

| 字段 | 默认值 | 说明 |
| --- | --- | --- |
| `transport` | `"websocket"` | `"websocket"` 或 `"webhook"` |
| `webhook.path` | `"/qqbot/webhook"` | 接收回调的 HTTP 路径 |

#### 平台配置步骤

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

* * *

### 群聊配置

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

#### @提及触发模式（requireMention）

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

| 模式 | 配置值 | 行为 |
| --- | --- | --- |
| **仅 @时回复** | `true`（默认） | 群消息中只有 @了机器人才会触发回复 |
| **自主发言** | `false` | AI 自主判断每条消息是否需要回复，无需 @ |

**优先级链**（从高到低）：

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

**配置示例：**

```json
{
  "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` 外，每个群还支持以下配置：

| 字段 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `ignoreOtherMentions` | `boolean` | `false` | 是否忽略 @了其他人但没 @机器人的消息。开启后这类消息直接丢弃，不记录历史、不触发 AI |
| `toolPolicy` | `"full" | "restricted" | "none"` | `"restricted"` | 群聊中 AI 可使用的工具范围。`full`\=全部可用；`restricted`\=限制敏感工具（如命令执行、文件操作）；`none`\=禁止所有工具调用 |
| `prompt` | `string` | 内置默认提示词 | 该群专属的系统提示词，会追加到全局 systemPrompt 之后 |
| `historyLimit` | `number` | `20` | 群历史消息缓存条数（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`（全局）声明 |
| `roomEventRequireMessageTool` | `boolean` | `true` | room\_event 下是否强制要求 `message` 工具可用。`true`（默认）：工具确定不可用时该群**自动降级为 `user_request`**（恢复正常回复权）并打一条 WARN；`false`：不降级，保持严格静默语义（由用户自行保证工具面） |
| `tools` | `object` | — | 群级工具白名单（`allow` / `alsoAllow` / `deny`），显式声明时原样透传给框架，优先级高于 `toolPolicy`。⚠️ room\_event 群若在此排除 `message`，该群将失去唯一发声通道（插件会自动降级并告警） |
| `coalesce` | `object` | `{enabled: true, strategy: "plugin", maxBatchSize: 10, maxHoldMs: 300000}` | 群消息排队与合批配置（详见下文「群消息排队与合批」）。`enabled=false`→排队但不合并（followup） |

#### 群消息排队与合批（插件侧）

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

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

| 字段 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `enabled` | `boolean` | `true` | `false` → 只排队不合并（followup），不打断正在处理的 turn |
| `strategy` | `"plugin"` | `"framework"` | `"plugin"` | `plugin`\=插件侧合批（可跨发言人）；`framework`\=交回框架 collect 队列（仅同发言人的连续消息可合并） |
| `maxBatchSize` | `integer` | `10` | 单批最多合并多少条群消息。超出时丢弃**较早**的消息，并在合并正文里留一行丢弃说明（模型不会静默缺内容） |
| `maxHoldMs` | `integer` | `300000` | 单批最长持有时长（毫秒）。兜底用：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.`。插件侧合批会显著减少进入该队列的条目数，但繁忙群仍建议调大：

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

#### 房间事件模式（全量模式群，可选）

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

```json
"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） | 视为可用 |

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

```json
{ "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` 下）配置：

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

（旧的 `agents.list` 数组形态同样兼容。）

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

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

**完整群配置示例：**

```json
{
  "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"` | 禁止所有私聊 |

```json
{
  "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"` | 禁止所有群聊 |

```json
{
  "channels": {
    "qqbot": {
      "groupPolicy": "allowlist",
      "groupAllowFrom": ["ALLOWED_GROUP_OPENID_1", "ALLOWED_GROUP_OPENID_2"]
    }
  }
}
```

> `groupAllowFrom` 为空或含 `"*"` 时不做限制。
> 
> **群场景只在明确叫 bot 时才回告**：本群不在 `groupAllowFrom` 里且消息 **@ 了机器人或引用了机器人的消息**时，机器人会公开回复一条含 `groupOpenid` 的诊断消息；普通闲聊（未点名 bot）仍然静默丢弃，避免在陌生群里对外广播白名单配置。

> 也可通过 [**`/bot-group-always`** 指令](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/#readme-bot-group-always--%E7%BE%A4%E6%B6%88%E6%81%AF%E5%93%8D%E5%BA%94%E6%A8%A1%E5%BC%8F%E5%88%87%E6%8D%A2) 在运行时动态切换账户级默认值，无需重启。

* * *

#### STT（语音转文字）— 自动转录用户发来的语音消息

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

```json
{
  "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` | 框架级 |

```json
{
  "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 流式接口逐段下发回复（打字机效果）。群聊不支持流式（平台限制）。未配置即关闭。

```json
{
  "channels": {
    "qqbot": {
      "streaming": {
        "mode": "partial",
        "sendMode": "stream"
      }
    }
  }
}
```

| 字段 | 默认 | 说明 |
| --- | --- | --- |
| `mode` | _（未配置 = 关闭）_ | `"partial"` 开启流式接收；`"off"` 关闭 |
| `sendMode` | `"stream"` | `"stream"` — QQ 流式打印机（打字机；**一段 = 一条消息**：模型在一轮里产出的每段 assistant 消息各成一条消息，内容原样送达、互不重叠，绝不跨段截断拼接；工具调用只封口当前段、不结束整轮）。`"static"` — 生成期间只累积，结束时一条完整消息发出（无打字机） |

-   流式分片（`session.update`）仍消耗触发消息的被动回复配额
-   流式出错时控制器自动降级为单条静态消息

#### 正在输入指示器（typing）— 仅 C2C 私聊

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

```json
{
  "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 间距保护）。最终回复发出后任务完成，不再补发

* * *

## 📚 文档与链接

-   [更新日志](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/CHANGELOG.md) — 与旧版本的差异、破坏性变更与各版本记录
-   [命令参考](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/commands.md) — OpenClaw CLI 常用命令

## 🤝 贡献者

感谢所有为本项目做出贡献的开发者！上游贡献者见 [tencent-connect/openclaw-qqbot](https://github.com/tencent-connect/openclaw-qqbot/graphs/contributors)。

[![](https://contrib.rocks/image?repo=jerryliang122/qqbot-openclaw)](https://github.com/jerryliang122/qqbot-openclaw/graphs/contributors)

## 💖 致谢

特别感谢 [@sliverp](https://github.com/sliverp) 对项目的核心贡献！

[![sliverp](https://avatars.githubusercontent.com/u/38134380?v=4 "sliverp")](https://github.com/sliverp)

感谢[腾讯云Lighthouse](https://cloud.tencent.com/product/lighthouse)的深度合作，养小龙虾，首选腾讯云Lighthouse！

[![腾讯云 Lighthouse](https://npmcn.com/package/%40jerryliang122/openclaw-qqbot/docs/images/lighthouse-head.png)](https://cloud.tencent.com/product/lighthouse)

## ⭐ Star History

[![Star History Chart](https://api.star-history.com/svg?repos=jerryliang122/qqbot-openclaw&type=date&legend=top-left)](https://www.star-history.com/#jerryliang122/qqbot-openclaw&type=date&legend=top-left)

## 常见问题

### @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 和提交记录判断。

