← Back to Plugins
Tools

Qq Group Guard

yuweitk By yuweitk 👁 125 views ▲ 0 votes

OpenClaw plugin: permission, trigger and probability gate for the QQ official bot

GitHub

Install

npm install
pnpm

README

# qq-group-guard

OpenClaw 插件 —— 为 **QQ 官方机器人**(频道插件 id 为 `qqbot`)提供权限、触发与概率门禁。

## 功能

按照项目需求,本插件在 QQ 群聊 / 私信场景下实现三组能力:

### 1. 触发机制
- **关键词触发**:群消息中包含 `triggerKeywords` 任一子串(大小写不敏感)即触发回复。
- **前缀触发**:群消息以 `triggerPrefixes` 任一前缀开头即触发回复。
- **概率回复**:既不命中关键词、也不命中前缀的群消息,按概率回复。
  - `defaultReplyProbability` 是全局默认概率(0..1)。
  - `groups.<group_openid>.replyProbability` 可为单个群覆盖概率。

### 2. 权限控制
- **管理员白名单** `admins`:管理员消息无条件放行,可使用全部工具。
- **群聊工具禁用**:在群聊中,非管理员禁止使用危险工具 `exec`、`elevated`、`gateway`、`write`、`edit`、`apply_patch`(清单可通过 `blockedGroupTools` 调整)。
- **私信白名单** `dmAllowlist`:仅允许的 OPENID 可私信机器人。非白名单 sender 的私信被静默丢弃(或回复 `dmBlockedReply`)。管理员始终放行。
- **exec 审批**:非管理员调用 `exec` 时,触发管理员审批流程(`requireApproval`),超时按 `execApprovalTimeoutSeconds` 拒绝。

### 3. 内置指令拦截
- OpenClaw 原生的 `/` 指令(如 `/reset`、`/new` 等)在 **群聊** 中仅管理员可触发。
- 非管理员在群里发送任何 `/` 开头的消息都会被拦截,并回复 `commandBlockedReply`。

> 上述所有逻辑仅作用于 `channel === "qqbot"` 的流量;其他渠道不受影响。

## 安装

### 本地开发安装
```bash
openclaw plugins install --link ./qq-group-guard
openclaw plugins enable qq-group-guard
openclaw gateway restart
```

### 验证运行时
```bash
openclaw plugins inspect qq-group-guard --runtime --json
```

## 配置

在 `openclaw.json` 的 `plugins.entries.qq-group-guard.config` 下配置:

```json5
{
  plugins: {
    entries: {
      "qq-group-guard": {
        enabled: true,
        config: {
          // 管理员白名单(member_openid / user_openid),支持 "*"
          admins: [
            "ADMIN_MEMBER_OPENID_1",
            "ADMIN_MEMBER_OPENID_2"
          ],
          // 私信白名单;为空则不额外限制(仍受 OpenClaw 自身 dmPolicy 约束)
          dmAllowlist: ["FRIEND_OPENID_1"],
          // 非触发群消息的全局默认回复概率
          defaultReplyProbability: 0.1,
          // 单群覆盖
          groups: {
            "GROUP_OPENID_A": { replyProbability: 0.3 },
            "GROUP_OPENID_B": { replyProbability: 0.0 }
          },
          // 关键词 / 前缀触发
          triggerKeywords: ["老婆", "面试", "哲学"],
          triggerPrefixes: ["!", "?"],
          // 群聊禁用工具清单(默认值如下)
          blockedGroupTools: ["exec", "elevated", "gateway", "write", "edit", "apply_patch"],
          // exec 审批
          requireExecApproval: true,
          execApprovalTimeoutSeconds: 60,
          // 拦截回复文案
          commandBlockedReply: "⚠️ 该指令仅限管理员使用。",
          toolBlockedReply: "⚠️ 该工具仅限管理员使用。",
          dmBlockedReply: ""
        }
      }
    }
  }
}
```

### 字段说明

| 字段 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `admins` | `string[]` | `[]` | 管理员白名单。支持 `qqbot:OPENID` 前缀形式与 `*` 通配。 |
| `dmAllowlist` | `string[]` | `[]` | 私信白名单。非空时阻断非白名单 sender 的私信。 |
| `defaultReplyProbability` | `number` | `0` | 非触发群消息的全局默认回复概率(0..1)。 |
| `groups` | `Record<string, { replyProbability?: number }>` | `{}` | 按 `group_openid` 覆盖回复概率。 |
| `triggerKeywords` | `string[]` | `[]` | 子串关键词触发。 |
| `triggerPrefixes` | `string[]` | `[]` | 前缀触发。 |
| `blockedGroupTools` | `string[]` | 见上 | 群聊中非管理员禁用的工具名清单。 |
| `requireExecApproval` | `boolean` | `true` | 非管理员 exec 是否需要审批。 |
| `execApprovalTimeoutSeconds` | `integer` | `60` | exec 审批超时秒数。 |
| `commandBlockedReply` | `string` | `⚠️ 该指令仅限管理员使用。` | 非管理员群内触发指令的回复。 |
| `toolBlockedReply` | `string` | `⚠️ 该工具仅限管理员使用。` | 群内非管理员调用禁用工具的回复。 |
| `dmBlockedReply` | `string` | `""` | 非白名单私信的回复;空则静默丢弃。 |

## 实现说明

### 使用的钩子

| 钩子 | 用途 | 阻断能力 |
| --- | --- | --- |
| `inbound_claim` | 触发判定 / 概率门 / 私信白名单 / 指令拦截 | `{ handled: true }` 抑制 agent;`{ handled: true, reply: { text } }` 合成回复 |
| `before_tool_call` | 群聊工具禁用 + exec 审批 | `{ block: true }` 或 `{ requireApproval }` |
| `message_sending` | 将 block 原因替换为友好回复 | `{ content }` 重写 |

### 身份与群判定

- `event.channel === "qqbot"` 限定仅作用于 QQ 渠道。
- 管理员身份由 `event.senderId` / `ctx.senderId`(群消息为 `member_openid`,私聊为 `user_openid`)匹配 `admins` 列表。
- 群标识通过解析 `qqbot:group:<group_openid>` 或 `group:<group_openid>` 形式的 `conversationId` / `channelId` 得到,用于查 `groups` 中的概率覆盖。
- 私聊判定为 `event.isGroup !== true`。

### 与 OpenClaw 内置机制的关系

QQ 插件本身已有 `allowFrom` / `groupAllowFrom` / `dmPolicy` / `groupPolicy` 的访问控制层(`extensions/qqbot/src/engine/access/`),核心也有 `senderIsOwner` / `operator.admin` 的管理员概念。本插件不替代它们,而是在其之上叠加项目所需的业务规则(触发概率、工具细分禁用、exec 审批、群内指令拦截)。建议把真正的超级管理员同时写进 OpenClaw 的 `allowFrom` 与本插件的 `admins`,以形成纵深防御。

### exec 审批

非管理员触发 `exec` 时,本插件返回 `requireApproval`,OpenClaw 会暂停 agent 并通过审批通道询问。`allowedDecisions: ["allow-once", "deny"]` 意味着审批人只能单次放行或拒绝;`timeoutBehavior: "deny"` 保证超时即拒绝。管理员自身调用 exec 不触发审批。

## 构建

```bash
pnpm install
pnpm build   # 产出 dist/index.js + dist/index.d.ts
```

## 许可

MIT
tools

Comments

Sign in to leave a comment

Loading comments...