# OpenClaw Bridge — QQ AI Reply Plugin > 将 QQ 消息转发到 OpenClaw Gateway,由 AI agent 自动处理并回复。 > 本 README 面向 AI agent(OpenClaw 基础智能体),引导其完成全流程部署(NapCat → qqrebot → 插件 → agent)。 ## 架构 ``` QQ 客户端 服务器 │ │ │ QQ 协议 │ ▼ │ NapCat(Docker) │ ← 第2步部署 │ OneBot HTTP │ ├── POST 消息 → qqrebot (:25580) ← 第3步部署 │ ├── openclaw_bridge 插件 │ │ │ │ │ ▼ │ │ OpenClaw Gateway (:18789) ← 已有 │ │ │ │ │ ▼ │ │ 新建的 qq-agent ← 第5步创建 │ │ │ ◄── 回复/操作 ←─── qqrebot ◄─────┘ NapCat Docker 端口映射: 6099/tcp ← HTTP API(脚本发消息/管理都走这个端口) 3001/tcp ← WebSocket(qqrebot 内部使用这个通道) 9000/tcp ← WebUI 管理面板 ``` ## 前提条件 | 组件 | 状态 | 由本仓库部署 | |---|---|---| | OpenClaw Gateway | 假设已运行 | ❌(由用户自行部署) | | NapCat(Docker) | 需部署 | ✅ | | qqrebot(消息接收器)| 需部署 | ✅ | | openclaw_bridge 插件 | 需部署 | ✅ | | qq-agent(AI agent) | 需创建 | ✅ | | QQ 技能/脚本 | 需部署 | ✅ | ## 部署步骤(阅读此文档的 AI agent 请按以下顺序执行) --- ### 第1步:询问用户信息 在执行任何操作前,请 **向用户询问以下信息**,不要使用仓库中的占位符: | 信息 | 说明 | 示例 | |---|---|---| | `ADMIN_QQ` | 管理员的 QQ 号(白名单使用) | `123456789` | | `GATEWAY_TOKEN` | OpenClaw Gateway 的认证 Token | 读取 `~/.openclaw/openclaw.json` 的 `gateway.auth.token` | | `NAP CAT_HOST` | 服务器 IP(NapCat 所在机器) | `192.168.1.100` | | `NEW_AGENT_ID` | 新 agent 的唯一 ID | `qq-agent` | | `SHARED_DIR` | NapCat 与宿主机共享目录路径 | `/opt/napcat_shared` | --- ### 第2步:通过 Docker 部署 NapCat NapCat 接收 QQ 消息并通过 OneBot HTTP 协议转发给下游(qqrebot)。 #### 2.1 创建目录结构 ```bash # 共享文件目录(用于发文件到 QQ) SHARED_DIR="${SHARED_DIR:-/opt/napcat_shared}" mkdir -p "${SHARED_DIR}" # NapCat 配置目录 mkdir -p /opt/napcat/config mkdir -p /opt/napcat/qq_data ``` #### 2.2 启动 NapCat Docker 容器 ```bash docker run -d \ --name napcat \ --restart unless-stopped \ -p 6099:6099 \ -p 3001:3001 \ -p 9000:9000 \ -v /opt/napcat/config:/app/napcat/config \ -v /opt/napcat/qq_data:/app/.config/QQ \ -v "${SHARED_DIR}:/app/napcat/share" \ --dns=114.114.114.114 \ mlikiowa/napcat-docker:latest ``` 端口说明: | 端口 | 用途 | |---|---| | 6099 | OneBot HTTP API(脚本发消息/管理用) | | 3001 | OneBot WebSocket(qqrebot 接收消息用) | | 9000 | WebUI 管理面板(首次本地扫码登录用) | #### 2.3 首次登录配置 > NapCat 首次启动需要扫码登录 QQ 账号。登录后自动持久化 `/opt/napcat/qq_data`。 ```bash # 查看登录二维码 docker logs napcat 2>&1 | grep -o 'http[s]*://[^ ]*\.png' # 或用浏览器打开 http://<服务器IP>:9000/webui/扫码登录 # 等待登录成功 docker logs napcat -f | grep "登录成功" ``` #### 2.4 配置 OneBot HTTP 端点 登录成功后,通过 WebUI 或直接编辑配置文件配置 HTTP 上报地址: ```bash # 编辑 NapCat OneBot 配置 cat > /opt/napcat/config/onebot11.json << 'EOF' { "http": { "enable": true, "host": "0.0.0.0", "port": 6099, "enableHttpPost": false, "enableHttpHeartbeat": false }, "ws": { "enable": true, "host": "0.0.0.0", "port": 3001 }, "reverseWs": { "enable": false }, "heartbeat": { "enable": true, "interval": 30000 }, "enableLocalFile2Url": true } EOF docker restart napcat ``` > **注意**:NapCat 通过 `reverseWs` 或 WebSocket 推送消息给 qqrebot。本配置使用 WebSocket Server 模式,qqrebot 作为客户端连接 `ws://napcat_host:3001`。 #### 2.5 验证 NapCat ```bash # 验证 HTTP API 可访问 curl -s http://localhost:6099/get_version_info | python3 -m json.tool # 预期输出: # {"status": "ok", "data": {"app_name": "NapCat", ...}, ...} ``` --- ### 第3步:部署 qqrebot(消息接收器) 从 [chatrebot1.0 release](https://jianfgit.xyz/jianf/chat_rebot-connect-with-onebot-standard-/src/tag/chatrebot1.0/) 下载 qqrebot 框架: ```bash # 下载并解压 wget https://jianfgit.xyz/jianf/chat_rebot-connect-with-onebot-standard-/archive/chatrebot1.0.tar.gz tar xzf chatrebot1.0.tar.gz mv chat_rebot-connect-with-onebot-standard- /opt/qqrebot cd /opt/qqrebot ``` **配置 `config/config.toml`:** ```toml [app] list_port = 25580 send_url = "http://${NAP CAT_HOST}:6099" # NapCat HTTP 端口 6099 [rebot] id = "" # 不需要 bot_id [plugins] dir = ["plugins"] ``` **注意**:NapCat 的 HTTP API 端口是 `6099`(不是 go-cqhttp 的 `25570`),所有脚本中的 `CQHTTP_URL` 最终也要替换为 `http://${NAP CAT_HOST}:6099`。 **创建 systemd 服务:** ```ini # /etc/systemd/system/qqrebot.service [Unit] Description=QQ Robot After=network.target docker.service Requires=docker.service [Service] Type=simple WorkingDirectory=/opt/qqrebot ExecStart=/opt/qqrebot/run.sh Restart=always RestartSec=3 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target ``` ```bash systemctl daemon-reload systemctl enable --now qqrebot ``` --- ### 第4步:安装 openclaw_bridge 插件 本仓库即 openclaw_bridge 插件的源码,需打包后部署到 qqrebot。 **在目标机器上执行打包(因含 C 扩展,必须在此机器上执行):** ```bash cd /path/to/chatrebot_aireply_plug # 安装依赖 pip install -r requirements.txt # 打包 python3 package.py ``` **将生成的 ZIP 复制到 qqrebot 插件目录:** ```bash cp dist/openclaw_bridge.zip /opt/qqrebot/plugins/ ``` **创建插件配置文件 `/opt/qqrebot/config/openclawbridge/config.toml`:** ```toml [openclaw] gateway_url = "http://127.0.0.1:18789" gateway_token = "${GATEWAY_TOKEN}" allowed_sender = "${ADMIN_QQ}" model = "openclaw/${NEW_AGENT_ID}" agent_id = "${NEW_AGENT_ID}" ``` **重启 qqrebot 加载插件:** ```bash systemctl restart qqrebot ``` **验证插件已加载:** ```bash journalctl -u qqrebot -f | grep OpenClawBridge ``` 预期输出: ``` Config loaded: url=http://127.0.0.1:18789, allowed=123456789 ``` --- ### 第5步:创建新的 OpenClaw agent 在 `~/.openclaw/openclaw.json` 的 `agents.list` 中添加新 agent: ```bash AGENT_ID="${NEW_AGENT_ID}" AGENT_WORKSPACE="/home/program/${AGENT_ID}-workspace" # 创建 workspace 目录 mkdir -p "${AGENT_WORKSPACE}/scripts" mkdir -p "${AGENT_WORKSPACE}/skills" mkdir -p "${AGENT_WORKSPACE}/self-workplace" mkdir -p "${AGENT_WORKSPACE}/memory" mkdir -p "${AGENT_WORKSPACE}/files" ``` 添加 agent 配置项到 OpenClaw 的 `agents.list`: ```json { "id": "${NEW_AGENT_ID}", "name": "${NEW_AGENT_ID}", "model": "kimi/kimi-for-coding", "workspace": "/home/program/${NEW_AGENT_ID}-workspace" } ``` > **注意**:通过 `GET /api/config/all` 获取当前配置,找到 `agents.list` 数组,push 上述对象,然后通过 `POST /api/config/set` 写入。或者直接编辑 `~/.openclaw/openclaw.json` 文件后重启 Gateway。 --- ### 第6步:部署脚本和 Skills 到新 agent 的 workspace **复制脚本:** ```bash cp -r /path/to/chatrebot_aireply_plug/scripts/* "${AGENT_WORKSPACE}/scripts/" ``` **复制 Skills:** ```bash for SKILL in qq-messenger qq-management qq-resolver qq-napcat-extras mc-query nix-helper browser file-process; do cp -r "/path/to/chatrebot_aireply_plug/skills/${SKILL}" "${AGENT_WORKSPACE}/skills/" done ``` **替换脚本中的占位符:** ```bash cd "${AGENT_WORKSPACE}/scripts" # 替换 NapCat HTTP API 地址 → 端口 6099 sed -i "s|YOUR_NAP CAT_HOST:25570|${NAP CAT_HOST}:6099|g" *.py sed -i "s|YOUR_NAP CAT_HOST|${NAP CAT_HOST}:6099|g" *.py sed -i "s|YOUR_NAPCAT_HOST:25570|${NAP CAT_HOST}:6099|g" *.py sed -i "s|YOUR_NAPCAT_HOST|${NAP CAT_HOST}:6099|g" *.py # 替换管理员 QQ sed -i "s|YOUR_ADMIN_QQ|${ADMIN_QQ}|g" *.py # 替换 Gateway Token sed -i "s|YOUR_GATEWAY_TOKEN|${GATEWAY_TOKEN}|g" *.py # 替换工作区路径 sed -i "s|YOUR_WORKSPACE_PATH|${AGENT_WORKSPACE}|g" *.py # 替换共享目录(Docker 挂载的 shared 目录) sed -i "s|YOUR_SHARED_DIR|${SHARED_DIR}|g" *.py # 替换群 ID 占位符(可选:群 ID 通常按需传入,但 DEFAULT_GID 需用户指定) # sed -i "s|YOUR_GROUP_ID|${DEFAULT_GROUP_ID}|g" *.py # sed -i "s|YOUR_BOT_QQ|${BOT_QQ}|g" *.py ``` 同样处理 `skills/` 目录下的 SKILL.md 文件中的 `YOUR_WORKSPACE_PATH` 和 `YOUR_ADMIN_QQ`。 --- ### 第7步:重启 OpenClaw Gateway ```bash openclaw gateway restart ``` 确认新 agent 已加载: ```bash # 查看代理列表 openclaw config get agents.list # 或在日志中确认 journalctl -u openclaw -f | grep "agent.${NEW_AGENT_ID}" ``` --- ### 第8步:端到端验证 1. 在 QQ 上给机器人发消息 2. 检查 qqrebot 日志:`journalctl -u qqrebot -f | grep OpenClawBridge` 3. 检查 OpenClaw 日志:`journalctl -u openclaw -f` 4. 验证 agent 已回复 --- ## 脚本适配说明(NapCat vs go-cqhttp) 如果从 go-cqhttp 迁移到 NapCat,或者混合使用,以下脚本需要关注差异点: ### 端口差异 | 组件 | go-cqhttp | NapCat(Docker) | |---|---|---| | HTTP API 端口 | `25570` | **6099** | | WebSocket 端口 | `25570` | **3001** | | qqrebot 配置中 `send_url` | `http://host:25570` | `http://host:6099` | > 所有脚本中的 `CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570"` 在替换时会自动改为 `6099`。 ### 文件发送适配 #### 跨主机文件访问 NapCat 运行在 Docker 中,宿主机文件不能直接在 NapCat 内部访问。需要用 Docker volume 映射: ``` 宿主机 ${SHARED_DIR}/ ⇔ NapCat 容器内 /app/napcat/share/ ``` 受影响的脚本: | 脚本 | 依赖 | 影响说明 | |---|---|---| | `qq_send_file.py` | 文件先复制到 `TARGET_DIR`,再由 NapCat 读取 | 需确保 `TARGET_DIR` = `SHARED_DIR` | | `qq_ocr_image.py` | NapCat 回退时需文件在共享目录 | 需复制到 `SHARED_DIR` | | `qq_get_file.py` | NapCat 返回文件 URL 或 base64 | 自动处理,不需要共享目录 | #### 文件上传方式对比 | 方式 | 支持 NapCat | 说明 | |---|---|---| | `upload_group_file` API | ✅ | NapCat 原生支持,底层走共享目录 | | `base64://` 方式 | ✅ | 小文件(<10MB)直接编码嵌入,无需共享目录 | | 文件路径引用 | ✅ | 文件路径需在 NapCat 容器内可访问 | `qq_upload_group_file.py` 使用 base64 方式上传,可以跨主机工作不依赖共享目录,但大文件可能有性能问题。 ### 脚本变量速查 | 占位符 | 替换值 | 出现位置 | |---|---|---| | `YOUR_NAP CAT_HOST:25570` | `${NAP CAT_HOST}:6099` | 所有 py 脚本 | | `YOUR_NAP CAT_HOST` | `${NAP CAT_HOST}:6099` | 所有 py 脚本 | | `YOUR_NAPCAT_HOST` | `${NAP CAT_HOST}:6099` | 部分 py 脚本 | | `YOUR_ADMIN_QQ` | `${ADMIN_QQ}` | py 脚本 + SKILL.md | | `YOUR_GATEWAY_TOKEN` | `${GATEWAY_TOKEN}` | py 脚本 | | `YOUR_SHARED_DIR` | `${SHARED_DIR}` | `qq_send_file.py`、`qq_ocr_image.py` | | `YOUR_WORKSPACE_PATH` | `${AGENT_WORKSPACE}` | SKILL.md + py 脚本 | --- ## 安全模块说明 部署完成后,新 agent 将具备以下安全能力(全部在 `src/process.py` 中实现): ### 高危词检测 内置 `HIGH_RISK_WORDS` 词库,覆盖以下类别: | 类别 | 示例关键词 | |---|---| | 越狱/提示词攻击 | `ignore all instructions`、`forget previous` | | 记忆操控 | `delete memory`、`forget everything` | | 敏感信息泄漏 | `sudo password`、`api key` | | 系统命令 | `cat /etc/passwd`、`rm -rf` | **触发时行为:** - 非管理员 → 自动拦截 + 上报管理员 + 该用户加入黑名单 - 管理员 → 记录日志 + 发送告警到 admin 私聊 ### 管理员白名单 | 配置项 | 说明 | |---|---| | `allowed_sender` | 唯一的管理员 QQ 号 | | 非管理员操作 | MC 指令过滤(`/` 开头消息跳过 AI 处理) | ### 消息过滤 - 纯媒体消息(无文字:纯图片/文件/视频)自动跳过 - 系统通知(`[系统通知]`、`[文件回执]`)自动跳过 - 非管理员发送的操作指令(`/` 开头)跳过 AI 处理 ### 安全上报 当非管理员触发高危词时,插件自动: 1. 通过 OneBot API 给 `allowed_sender` 发送告警消息 2. 告警内容:用户 QQ、所在群、触发的原文摘要 ### 错误脱敏 所有 HTTP 响应体、异常详情不暴露给 QQ 用户,仅记录日志。 ## 配置文件参考 | 配置项 | 必填 | 说明 | |---|---|---| | `gateway_url` | ✅ | OpenClaw Gateway 地址 | | `gateway_token` | ✅ | Gateway 认证 Token(从用户处获取) | | `allowed_sender` | ✅ | 管理员 QQ 号(从用户处获取) | | `model` | ✅ | Agent 模型 ID(格式:`openclaw/${AGENT_ID}`) | | `agent_id` | ✅ | Agent ID(与 `agents.list` 中一致) | ## 目录结构 ``` chatrebot_aireply_plug/ ├── config/ │ └── openclawbridge/ │ └── config.toml # 插件配置模板 ├── src/ │ ├── process.py # 插件核心逻辑(含全部安全模块) │ ├── config.toml # 本地测试配置 │ └── modules/ │ ├── plugin_modules.py # BasePlugin + MessageContext │ └── user_module.py # User/Group 封装 ├── scripts/ # ✅ 部署时复制到 agent workspace │ ├── qq_send_msg.py # 发送消息(端口 6099) │ ├── qq_send_file.py # 发送文件/图片(共享目录映射) │ ├── qq_get_groups.py # 获取群列表 │ ├── qq_get_friends.py # 获取好友列表 │ ├── qq_group_manage.py # 群管理(踢/禁言/设管理) │ ├── ... # 详见技能文档 ├── skills/ # ✅ 部署时复制到 agent skills/ │ ├── qq-messenger/SKILL.md │ ├── qq-management/SKILL.md │ ├── qq-resolver/SKILL.md │ ├── qq-napcat-extras/SKILL.md │ ├── mc-query/SKILL.md │ └── ... ├── dependence.py # 依赖安装工具 ├── package.py # ZIP 打包器 ├── packup.sh / packup.bat # 一键打包脚本 ├── test.py # 本地测试 ├── requirements.txt # Python 依赖 └── README.md # 本文件 ``` ## 自定义安全词库 编辑 `src/process.py` 中的 `HIGH_RISK_WORDS` 列表: ```python HIGH_RISK_WORDS = { "prompt_injection": ["ignore all instructions", ...], "memory_manipulation": ["delete memory", ...], "info_leak": ["sudo password", ...], "system_commands": ["cat /etc/passwd", ...], } ``` 添加后重新打包、部署、重启 qqrebot。 ## 许可证 MIT