From 2dbe121446ecb32ad5c0075de4ced17f1a1ab337 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 4 May 2026 18:59:02 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=A2=9E=E5=8A=A0NapCat=20Docker?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=20+=20=E8=84=9A=E6=9C=AC=E9=80=82=E9=85=8D?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - NapCat Docker 部署:目录创建、容器启动、首次扫码登录、OneBot配置 - 端口映射表:6099(HTTP) / 3001(WS) / 9000(WebUI) - 脚本适配说明表:NapCat vs go-cqhttp 差异、文件发送适配、变量速查 - 前提条件改为 NapCat 由本仓库部署 - 架构图标注端口号 --- README.md | 242 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 203 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 099416e..4531610 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # OpenClaw Bridge — QQ AI Reply Plugin > 将 QQ 消息转发到 OpenClaw Gateway,由 AI agent 自动处理并回复。 -> 本 README 面向 AI agent(OpenClaw 基础智能体),引导其完成除 NapCat 外的全部后端部署。 +> 本 README 面向 AI agent(OpenClaw 基础智能体),引导其完成全流程部署(NapCat → qqrebot → 插件 → agent)。 ## 架构 @@ -10,27 +10,32 @@ QQ 客户端 服务器 │ │ │ QQ 协议 │ ▼ │ -NapCat / go-cqhttp │ ← 假设已运行 +NapCat(Docker) │ ← 第2步部署 │ OneBot HTTP │ - ├── POST 消息 → qqrebot (:25580) + ├── POST 消息 → qqrebot (:25580) ← 第3步部署 │ ├── openclaw_bridge 插件 │ │ │ │ │ ▼ - │ │ OpenClaw Gateway (:18789) + │ │ OpenClaw Gateway (:18789) ← 已有 │ │ │ │ │ ▼ - │ │ 新建的 qq-agent + │ │ 新建的 qq-agent ← 第5步创建 │ │ │ ◄── 回复/操作 ←─── qqrebot ◄─────┘ + +NapCat Docker 端口映射: + 6099/tcp ← HTTP API(脚本发消息/管理都走这个端口) + 3001/tcp ← WebSocket(qqrebot 内部使用这个通道) + 9000/tcp ← WebUI 管理面板 ``` ## 前提条件 | 组件 | 状态 | 由本仓库部署 | |---|---|---| -| NapCat / go-cqhttp | 假设已运行 | ❌(由用户自行部署) | | OpenClaw Gateway | 假设已运行 | ❌(由用户自行部署) | -| qqrebot(消息接收器) | 需部署 | ✅ | +| NapCat(Docker) | 需部署 | ✅ | +| qqrebot(消息接收器)| 需部署 | ✅ | | openclaw_bridge 插件 | 需部署 | ✅ | | qq-agent(AI agent) | 需创建 | ✅ | | QQ 技能/脚本 | 需部署 | ✅ | @@ -45,14 +50,116 @@ NapCat / go-cqhttp │ ← 假设已运行 | 信息 | 说明 | 示例 | |---|---|---| -| `ADMIN_QQ` | 管理员的 QQ 号(用于白名单) | `123456789` | -| `GATEWAY_TOKEN` | OpenClaw Gateway 的认证 Token | 从 `~/.openclaw/openclaw.json` 中读取 | -| `NAPCAT_HOST` | NapCat 的 HTTP API 地址 | `127.0.0.1:25570` | +| `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步:部署 qqrebot(消息接收器) +### 第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 框架: @@ -64,27 +171,30 @@ mv chat_rebot-connect-with-onebot-standard- /opt/qqrebot cd /opt/qqrebot ``` -**编辑 `config/config.toml`,填入 NapCat 地址:** +**配置 `config/config.toml`:** ```toml [app] list_port = 25580 -send_url = "http://${NAPCAT_HOST}" +send_url = "http://${NAP CAT_HOST}:6099" # NapCat HTTP 端口 6099 [rebot] -id = "" +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 +After=network.target docker.service +Requires=docker.service [Service] Type=simple @@ -106,7 +216,7 @@ systemctl enable --now qqrebot --- -### 第3步:安装 openclaw_bridge 插件 +### 第4步:安装 openclaw_bridge 插件 本仓库即 openclaw_bridge 插件的源码,需打包后部署到 qqrebot。 @@ -158,9 +268,9 @@ Config loaded: url=http://127.0.0.1:18789, allowed=123456789 --- -### 第4步:创建新的 OpenClaw agent +### 第5步:创建新的 OpenClaw agent -使用 Gateway API 在 `~/.openclaw/openclaw.json` 的 `agents.list` 中添加新 agent: +在 `~/.openclaw/openclaw.json` 的 `agents.list` 中添加新 agent: ```bash AGENT_ID="${NEW_AGENT_ID}" @@ -187,18 +297,9 @@ mkdir -p "${AGENT_WORKSPACE}/files" > **注意**:通过 `GET /api/config/all` 获取当前配置,找到 `agents.list` 数组,push 上述对象,然后通过 `POST /api/config/set` 写入。或者直接编辑 `~/.openclaw/openclaw.json` 文件后重启 Gateway。 -设置该 agent 的安全相关配置: - -```json -{ - "agents.defaults.compaction.mode": "safeguard", - "agents.list[${index}].model": "kimi/kimi-for-coding" -} -``` - --- -### 第5步:部署脚本和 Skills 到新 agent 的 workspace +### 第6步:部署脚本和 Skills 到新 agent 的 workspace **复制脚本:** @@ -216,16 +317,14 @@ done **替换脚本中的占位符:** -所有脚本中 `YOUR_ADMIN_QQ`、`YOUR_NAP CAT_HOST`、`YOUR_GATEWAY_TOKEN`、`YOUR_GROUP_ID`、`YOUR_BOT_QQ`、`YOUR_WORKSPACE_PATH`、`YOUR_SHARED_DIR` 等需要替换为用户的实际值。 - -可以用 sed 批量替换占位符(以 `${AGENT_WORKSPACE}/scripts/` 为例): - ```bash cd "${AGENT_WORKSPACE}/scripts" -# 替换 NapCat 地址 -sed -i "s|YOUR_NAP CAT_HOST|${NAPCAT_HOST}|g" *.py -sed -i "s|YOUR_NAPCAT_HOST|${NAPCAT_HOST}|g" *.py +# 替换 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 @@ -235,13 +334,20 @@ 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`。 --- -### 第6步:重启 OpenClaw Gateway +### 第7步:重启 OpenClaw Gateway ```bash openclaw gateway restart @@ -259,13 +365,71 @@ journalctl -u openclaw -f | grep "agent.${NEW_AGENT_ID}" --- -### 第7步:端到端验证 +### 第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` 中实现): @@ -332,8 +496,8 @@ chatrebot_aireply_plug/ │ ├── plugin_modules.py # BasePlugin + MessageContext │ └── user_module.py # User/Group 封装 ├── scripts/ # ✅ 部署时复制到 agent workspace -│ ├── qq_send_msg.py # 发送消息 -│ ├── qq_send_file.py # 发送文件/图片 +│ ├── qq_send_msg.py # 发送消息(端口 6099) +│ ├── qq_send_file.py # 发送文件/图片(共享目录映射) │ ├── qq_get_groups.py # 获取群列表 │ ├── qq_get_friends.py # 获取好友列表 │ ├── qq_group_manage.py # 群管理(踢/禁言/设管理)