From 9dff73e7bcf1b0b597cc7d13ab61d6b8454fac33 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 4 May 2026 19:47:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=80=9A=E8=BF=87=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E6=B5=8B=E8=AF=95=E5=8F=91=E7=8E=B0=E7=9A=84?= =?UTF-8?q?=2011=20=E4=B8=AA=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔴 致命(5个): - Bug1: onebot11.json 格式错误(旧 {http:{},ws:{}} → network.httpServers/httppClients) - Bug2: 端口映射错位(WebUI 6099, OneBot API 6097 独立端口) - Bug3: 变量名含空格 NAP CAT_HOST → NAPCAT_HOST(14脚本+2SKILL+README) - Bug4: heredoc 单引号阻止变量展开 - Bug5: process.py 缺失 _get_high_risk_words() 方法 🟡 重要(3个): - Bug6: onebot11.json 默认不存在(cat > 而非 edit) - Bug7: API 须登录后才响应(新增扫码引导步骤) - Bug8: qqrebot systemd 依赖 napcat 服务 🟢 中等(3个): - Bug9: Skills 占位符缺 YOUR_NAPCAT_HOST sed 覆盖 - Bug10: venv 不可用需降级方案 - Bug11: 端口 25580 冲突处理 已验证全链路:NapCat + qqrebot + 插件 + OpenClaw Gateway + AI 回复 --- README.md | 251 +++++++++++++++++-------------- scripts/qq_friend_action.py | 2 +- scripts/qq_get_file.py | 2 +- scripts/qq_get_friends.py | 2 +- scripts/qq_get_group_files.py | 2 +- scripts/qq_get_groups.py | 2 +- scripts/qq_get_history.py | 2 +- scripts/qq_group_action.py | 2 +- scripts/qq_group_manage.py | 2 +- scripts/qq_ocr_image.py | 2 +- scripts/qq_resolve_name.py | 2 +- scripts/qq_send_file.py | 2 +- scripts/qq_send_like.py | 2 +- scripts/qq_send_msg.py | 2 +- scripts/qq_upload_group_file.py | 2 +- skills/qq-messenger/SKILL.md | 2 +- skills/qq-napcat-extras/SKILL.md | 2 +- src/process.py | 19 +++ 18 files changed, 171 insertions(+), 131 deletions(-) diff --git a/README.md b/README.md index 0d79b5b..d9de030 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ ## 架构 ``` -QQ 用户 →→→ NapCat(Docker:6099) +QQ 用户 →→→ NapCat(Docker) │ - │ HTTP POST(事件推送) + │ HTTP POST(事件推送:6097→qqrebot:25580) ▼ qqrebot(HTTP Server :25580) ← 消息接收 │ @@ -25,17 +25,17 @@ QQ 用户 →→→ NapCat(Docker:6099) │ │ HTTP POST(send_private_msg / send_group_msg) ▼ - NapCat(:6099) → 回复发送到 QQ + NapCat(Docker:6097)→ 回复发送到 QQ ``` **关键通信链路(全是 HTTP,无 WebSocket):** -| 链路 | 方向 | 协议 | 端口 | +| 链路 | 方向 | 协议 | 地址 | |---|---|---|---| -| NapCat → qqrebot | 事件推送 | HTTP POST | `qqrebot:25580` | +| NapCat → qqrebot | 事件推送 | HTTP POST | `http://172.17.0.1:25580/` | | 插件 → OpenClaw | AI 请求 | HTTP POST | `127.0.0.1:18789` | -| 插件 → NapCat | 发送回复 | HTTP POST | `napcat:6099` | -| 脚本 → NapCat | 发消息/管理 | HTTP POST | `napcat:6099` | +| 插件 → NapCat | 发送回复 | HTTP POST | `127.0.0.1:6097` | +| 脚本 → NapCat | 发消息/管理 | HTTP POST | `127.0.0.1:6097` | ## 前提条件 @@ -69,7 +69,10 @@ AGENT_WORKSPACE="/home/program/${NEW_AGENT_ID}-workspace" SHARED_DIR="${SHARED_DIR:-/opt/napcat_shared}" # NapCat HTTP API 地址(同机部署走 127.0.0.1) -NAP CAT_HOST="127.0.0.1" +NAPCAT_HOST="127.0.0.1" + +# OneBot HTTP API 端口(与 WebUI 端口 6099 不同) +NAPCAT_API_PORT="${NAPCAT_API_PORT:-6097}" # 从 NapCat Docker 容器角度看到的 qqrebot 地址 # 同机部署时 NapCat 通过 Docker 网关访问宿主机 @@ -84,44 +87,35 @@ print(cfg.get('gateway', {}).get('auth', {}).get('token', '')) " 2>/dev/null) ``` -> 注意:`NAP CAT_HOST` 是**不含端口**的纯 IP/域名,后面所有用到 `send_url` 的地方拼入端口 `:6099`。 -> `QQREBOT_HOST` 带端口 `:25580`,用于 onebot11.json 的 `httpPost.url`。 +> 变量命名规则:脚本中的占位符为 `YOUR_NAPCAT_HOST:25570`(带端口),由 sed 替换为 `${NAPCAT_HOST}:${NAPCAT_API_PORT}`。请勿在 bash 变量名中使用空格。 +> `QQREBOT_HOST` 带端口 `:25580`,用于 onebot11.json 的 `httpClients` URL。 #### 1.2 向用户确认 只有以下两项无法自动推导,agent 需向用户询问: -```bash -# 向用户提问示例: -# "主人,我需要以下信息来完成部署: -# 1. ADMIN_QQ — 你的管理员 QQ 号(用于白名单和安全上报) -# 2. GATEWAY_TOKEN — 如上面自动读取的为空,请提供" -``` - | 变量 | 必须 | 说明 | |---|---|---| | `ADMIN_QQ` | ✅ | 管理员 QQ 号,用于白名单和安全告警上报 | | `GATEWAY_TOKEN` | 看情况 | 自动读取失败时(空值)才需要用户提供 | -> 其余变量(`NEW_AGENT_ID`、`SHARED_DIR`、`NAP CAT_HOST`、`QQREBOT_HOST`)全部使用默认值即可,**无需用户确认**。仅在跨机部署(NapCat 和 OpenClaw 不在同一台机器)时需要用户指定 `NAP CAT_HOST`。 +> 其余变量(`NEW_AGENT_ID`、`SHARED_DIR`、`NAPCAT_HOST`、`NAPCAT_API_PORT`、`QQREBOT_HOST`)全部使用默认值即可。仅在跨机部署时需要用户调整 `NAPCAT_HOST` 或 `NAPCAT_API_PORT`。 #### 1.3 应用变量 ```bash -# 确认 ADMIN_QQ +# 确认必填项 if [ -z "$ADMIN_QQ" ]; then echo "请提供 ADMIN_QQ" exit 1 fi - -# 确认 GATEWAY_TOKEN 非空 if [ -z "$GATEWAY_TOKEN" ]; then echo "自动读取 GATEWAY_TOKEN 失败,请提供" exit 1 fi -export ADMIN_QQ NEW_AGENT_ID AGENT_WORKSPACE SHARED_DIR NAP_CAT_HOST QQREBOT_HOST GATEWAY_TOKEN -echo "环境变量已就绪:ADMIN_QQ=$ADMIN_QQ, AGENT=$NEW_AGENT_ID, NAPCAT=$NAP CAT_HOST" +export ADMIN_QQ NEW_AGENT_ID AGENT_WORKSPACE SHARED_DIR NAPCAT_HOST NAPCAT_API_PORT QQREBOT_HOST GATEWAY_TOKEN +echo "变量已就绪:ADMIN_QQ=$ADMIN_QQ, AGENT=$NEW_AGENT_ID, NAPCAT=$NAPCAT_HOST:$NAPCAT_API_PORT" ``` --- @@ -130,7 +124,18 @@ echo "环境变量已就绪:ADMIN_QQ=$ADMIN_QQ, AGENT=$NEW_AGENT_ID, NAPCAT=$N NapCat 是 QQ 协议实现,接收 QQ 消息并通过 **HTTP POST** 推送到 qqrebot。 -#### 2.1 创建目录结构 +#### 2.1 端口说明 + +| 端口 | 是否必开 | 用途 | +|---|---|---| +| `6097` | ✅ | OneBot HTTP API(脚本发消息/群管理/取数据都用此端口) | +| `6099` | ✅ | WebUI 管理面板(NapCat 默认占用,不能与 API 共用) | +| `3001` | ❌ | WebSocket Server(本教程用 HTTP POST,不启用) | + +> NapCat v4 的 WebUI 默认绑定端口 6099。OneBot HTTP API 需要独立端口(本教程使用 6097)。 +> WebUI 用于扫码登录和管理界面,首次部署时需保持开启;生产环境可关闭或将 WebUI 绑定到 `127.0.0.1`。 + +#### 2.2 创建目录结构 ```bash # 共享文件目录(NapCat Docker 内发文件时读取) @@ -142,12 +147,57 @@ mkdir -p /opt/napcat/config mkdir -p /opt/napcat/qq_data ``` -#### 2.2 启动 NapCat Docker 容器 +#### 2.3 创建 onebot11.json 配置 + +> ⚠️ onebot11.json 默认不存在,需手动创建。NapCat v4 使用 `network` 配置格式(非旧版 `http{} ws{}` 格式)。 + +```bash +cat > /opt/napcat/config/onebot11.json << 'ONEBOTEOF' +{ + "network": { + "httpServers": [ + { + "name": "http-server", + "enable": true, + "host": "0.0.0.0", + "port": 6097, + "token": "", + "enableCors": true, + "debug": false + } + ], + "httpClients": [ + { + "name": "http-post", + "enable": true, + "url": "http://${QQREBOT_HOST}/", + "messagePostFormat": "array", + "reportSelfMessage": false, + "token": "", + "debug": false + } + ], + "websocketServers": [], + "websocketClients": [] + }, + "musicSignUrl": "", + "enableLocalFile2Url": true, + "parseMultMsg": false +} +ONEBOTEOF +``` + +> `httpServers`:OneBot HTTP API,脚本通过此端口发送消息/管理群组。 +> `httpClients`:NapCat 将消息事件通过 HTTP POST 推送到 qqrebot。 +> `httpClients[0].url` 中 `${QQREBOT_HOST}` 需替换为实际地址(同机部署时为 `172.17.0.1:25580`)。Docker 的默认 bridge 网关是 `172.17.0.1`,可通过 `docker network inspect bridge` 确认。 + +#### 2.4 启动 NapCat Docker 容器 ```bash docker run -d \ --name napcat \ --restart unless-stopped \ + -p 6097:6097 \ -p 6099:6099 \ -v /opt/napcat/config:/app/napcat/config \ -v /opt/napcat/qq_data:/app/.config/QQ \ @@ -156,81 +206,38 @@ docker run -d \ mlikiowa/napcat-docker:latest ``` -端口说明: +> 必须同时暴露 `6097`(OneBot API)和 `6099`(WebUI),缺一不可。 -| 端口 | 是否必开 | 用途 | -|---|---|---| -| `6099` | ✅ | OneBot HTTP API(脚本发消息/群管理/取数据都用这个端口) | -| `3001` | ❌ | WebSocket Server(本教程用 HTTP POST 推送,不需要) | -| `9000` | 按需 | WebUI 管理面板(首次扫码登录可临时用) | +#### 2.5 QQ 登录(扫码) -如果机器防扫描严格,**只开 6099** 即可;WebUI 按需用完即关。 - -#### 2.3 首次登录配置 - -> NapCat 首次启动需要扫码登录 QQ 账号。登录数据持久化在 `/opt/napcat/qq_data`。 +> ⚠️ OneBot HTTP API 在 QQ 登录成功之前不会启动! +> `curl /get_version_info` 类 API 调用必须在登录后才能成功。 ```bash # 查看登录二维码(日志中会打印链接) docker logs napcat 2>&1 | grep -o 'http[s]*://[^ ]*\.png' -# 或用浏览器打开 http://<服务器IP>:9000/webui 扫码登录 +# 或用浏览器打开 http://<服务器IP>:6099/webui 扫码登录 # 等待登录成功 docker logs napcat -f | grep "登录成功" + +# 登录成功后 OneBot 配置会自动加载,可以看到类似日志: +# [Notice] [OneBot11] HTTP服务: 0.0.0.0:6097, : 已启动 +# [Notice] [OneBot11] HTTP上报服务: http://172.17.0.1:25580/, : 已启动 ``` -#### 2.4 配置事件推送(HTTP POST → qqrebot) - -NapCat 需要将所有消息事件通过 HTTP POST 推送到 qqrebot(端口 `25580`)。 - -编辑 `/opt/napcat/config/onebot11.json`: - -```json -{ - "http": { - "enable": true, - "host": "0.0.0.0", - "port": 6099, - "enableHttpPost": false, - "enableHttpHeartbeat": false - }, - "httpPost": [ - { - "url": "http://${QQREBOT_HOST}/", - "secret": "" - } - ], - "ws": { - "enable": false - }, - "heartbeat": { - "enable": false - }, - "enableLocalFile2Url": true -} -``` - -> **关键说明:** -> - `httpPost` 数组中的 URL 是 NapCat 向 qqrebot 推送消息事件的目标地址 -> - 如果 NapCat 和 qqrebot 在**同一台宿主机上**,`url` 通常设置为 `http://172.17.0.1:25580/`(Docker 默认网关地址) -> - 如果**不同机器**,填 qqrebot 机器可达的真实 IP -> - `ws.enable = false` — 本教程不用 WebSocket -> - `http.enableHttpPost = false` — httpPost 由专门的 `httpPost` 数组控制 - -应用配置: +#### 2.6 验证 NapCat ```bash -docker restart napcat -``` - -#### 2.5 验证 NapCat - -```bash -# 验证 HTTP API 可访问 -curl -s http://localhost:6099/get_version_info | python3 -m json.tool +# 验证 HTTP API 可访问(仅在登录成功后可调用) +curl -s http://localhost:6097/get_version_info | python3 -m json.tool # 预期输出: # {"status": "ok", "data": {"app_name": "NapCat", ...}, ...} + +# 验证 WebUI 可访问 +curl -s -o /dev/null -w "%{http_code}" http://localhost:6099/webui +# 预期返回 200 ``` --- @@ -250,14 +257,25 @@ mv chat_rebot-connect-with-onebot-standard- /opt/qqrebot cd /opt/qqrebot ``` -#### 3.2 配置 +#### 3.2 检查端口冲突 + +```bash +# 检查 25580 是否已被占用 +if ss -tlnp | grep -q :25580; then + echo "⚠️ 端口 25580 已被占用,请修改为 25581 或其他空闲端口" + echo " 修改 qqrebot config.toml 中的 list_port" + exit 1 +fi +``` + +#### 3.3 配置 编辑 `config/config.toml`: ```toml [app] list_port = 25580 -send_url = "http://${NAP CAT_HOST}:6099" # → 插件回复时调 NapCat HTTP API 用 +send_url = "http://${NAPCAT_HOST}:${NAPCAT_API_PORT}" # 指向 NapCat OneBot API [rebot] id = "" @@ -266,12 +284,16 @@ id = "" dir = ["plugins"] ``` -> **`send_url`**:qqrebot 框架用它作为 NapCat HTTP API 的基础地址。插件中的 `ctx.group.url` 来自此值,后续所有 `send_private_msg` / `send_group_msg` 调用都走这个地址。如果 NapCat 和 qqrebot 同机,填 `http://127.0.0.1:6099`。 +> `send_url` 是 qqrebot 框架发给插件的 NapCat API 基础地址(即 `ctx.group.url`)。所有 `send_private_msg` / `send_group_msg` 调用都走此地址。 +> 如果 NapCat 和 qqrebot 同机,`send_url = "http://127.0.0.1:6097"`。 -#### 3.3 创建 systemd 服务 +#### 3.4 创建 systemd 服务 -```ini -# /etc/systemd/system/qqrebot.service +```bash +# 注意:如果 qqrebot 已有其他实例在运行,请修改端口和服务名 +# 此处假设使用端口 25580,服务名 qqrebot + +cat > /etc/systemd/system/qqrebot.service << 'SERVICEEOF' [Unit] Description=QQ Robot After=network.target docker.service @@ -288,9 +310,8 @@ StandardError=journal [Install] WantedBy=multi-user.target -``` +SERVICEEOF -```bash systemctl daemon-reload systemctl enable --now qqrebot ``` @@ -377,7 +398,7 @@ mkdir -p "${AGENT_WORKSPACE}/files" ### 第6步:获取源码并部署到 agent 的 workspace -> agent 需要在目标服务器上获取 chatrebot_aireply_plug 的 `scripts/`(26 个脚本)和 `skills/`(8 个 skill)目录。 +> agent 需要在目标服务器上获得 chatrebot_aireply_plug 的 `scripts/`(26 个脚本)和 `skills/`(8 个 skill)目录。 #### 6.1 在目标服务器上克隆仓库 @@ -448,11 +469,9 @@ 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 +# NapCat HTTP API 地址(端口 ${NAPCAT_API_PORT},非旧版 25570) +sed -i "s|YOUR_NAPCAT_HOST:25570|${NAPCAT_HOST}:${NAPCAT_API_PORT}|g" *.py +sed -i "s|YOUR_NAPCAT_HOST|${NAPCAT_HOST}:${NAPCAT_API_PORT}|g" *.py # 管理员 QQ sed -i "s|YOUR_ADMIN_QQ|${ADMIN_QQ}|g" *.py @@ -482,7 +501,7 @@ done > ⚠️ Skills 的替换很关键: > - `YOUR_WORKSPACE_PATH` → agent 的 subprocess.run 能找到脚本 > - `YOUR_SHARED_DIR` → 涉及文件发送的 Skill(qq-messenger、qq-napcat-extras)理解的宿主机共享路径 -> - 两个 Skill(qq-messenger、qq-napcat-extras)还记录了容器路径 `/app/napcat/share/`,这是一个固定常量,对应 Step 2.2 的 Docker volume `-v SHARED_DIR:/app/napcat/share`。如果修改了 volume 挂载点,需同步修改这些 SKILL.md 和 `qq_send_file.py`、`qq_ocr_image.py` 中的容器路径。 +> - 两个 Skill(qq-messenger、qq-napcat-extras)还记录了容器路径 `/app/napcat/share/`,这是一个固定常量,对应 Docker volume `-v SHARED_DIR:/app/napcat/share`。如果修改了 volume 挂载点,需同步修改这些 SKILL.md 和 `qq_send_file.py`、`qq_ocr_image.py` 中的容器路径。 **文件发送全链路路径转换示意:** @@ -491,9 +510,9 @@ agent 工作区 宿主机共享目录 NapCat 容器 /script/file.txt →cp→ /opt/napcat_shared/ ←volume→ /app/napcat/share/ ↓ qq_send_file.py 构造 - file:///app/napcat/share/file.txt + file:///app/napcat/share/file.txt ↓ - NapCat HTTP API → QQ 用户 + NapCat HTTP API → QQ 用户 ``` > 代理的思维模型:"我要发文件 → 把文件放到共享目录 → 脚本从共享目录发"。Skill 中提到的"发送文件/图片"都隐含了这一步文件复制。 @@ -507,7 +526,6 @@ ls -la "${SHARED_DIR}/" # 手动测试:复制一个文件过去,走 qq_send_file.py echo hello > /tmp/test.txt python3 "${AGENT_WORKSPACE}/scripts/qq_send_file.py" "/tmp/test.txt" --target "${ADMIN_QQ}" --private -# 如果 ADMIN_QQ 收到了"hello"文件,路径映射一切正常 ``` #### 6.5 验证完整性 @@ -516,7 +534,7 @@ python3 "${AGENT_WORKSPACE}/scripts/qq_send_file.py" "/tmp/test.txt" --target "$ # 脚本数量 echo "scripts: $(ls "${AGENT_WORKSPACE}/scripts/" | wc -l) 个" # 确认无残留占位符 -if grep -r "YOUR_ADMIN_QQ\|YOUR_WORKSPACE_PATH" "${AGENT_WORKSPACE}/"; then +if grep -r "YOUR_ADMIN_QQ\|YOUR_WORKSPACE_PATH\|YOUR_NAPCAT_HOST\|YOUR_SHARED_DIR" "${AGENT_WORKSPACE}/"; then echo "⚠️ 还有未替换的占位符!" else echo "✅ 占位符全部替换完毕" @@ -542,10 +560,13 @@ openclaw config get agents.list ### 第8步:端到端验证 -1. 在 QQ 上给机器人发消息 -2. 检查 qqrebot 日志:`journalctl -u qqrebot -f | grep OpenClawBridge` -3. 检查 OpenClaw 日志:`journalctl -u openclaw -f` -4. 验证 agent 已回复 +1. 确认 NapCat QQ 已登录(`docker logs napcat 2>&1 | grep "登录成功"`) +2. 确认 OneBot API 可访问(`curl localhost:6097/get_version_info`) +3. 确认 qqrebot 正在运行(`systemctl status qqrebot`) +4. 在 QQ 上给机器人发消息 +5. 检查 qqrebot 日志:`journalctl -u qqrebot -f | grep OpenClawBridge` +6. 检查 OpenClaw 日志:`journalctl -u openclaw -f` +7. 验证 agent 已回复 --- @@ -553,12 +574,13 @@ openclaw config get agents.list ### 端口对照 -| 组件 | go-cqhttp | NapCat(Docker) | +| 组件 | 旧版 go-cqhttp | NapCat(本教程) | |---|---|---| -| HTTP API 端口 | `25570` | **6099** | -| WebSocket | `25570`(兼用) | 不启用(本教程) | +| HTTP API 端口 | `25570` | **6097** | +| WebUI | N/A | **6099**(扫码登录用) | +| WebSocket | `25570`(兼用) | 不启用 | -> 脚本中 `CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570"` 替换后变为 `http://:6099`。 +> 脚本中 `CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570"` 替换后变为 `http://127.0.0.1:6097`。 ### 文件发送与共享目录 @@ -579,9 +601,8 @@ NapCat 运行在 Docker 内部,宿主机文件路径不能直接访问。解 | 占位符 | 替换值 | 出现位置 | |---|---|---| -| `YOUR_NAP CAT_HOST:25570` | `${NAP CAT_HOST}:6099` | 所有脚本 | -| `YOUR_NAP CAT_HOST` | `${NAP CAT_HOST}:6099` | 所有脚本 | -| `YOUR_NAPCAT_HOST` | `${NAP CAT_HOST}:6099` | 部分脚本 | +| `YOUR_NAPCAT_HOST:25570` | `${NAPCAT_HOST}:${NAPCAT_API_PORT}` | 所有脚本 | +| `YOUR_NAPCAT_HOST` | `${NAPCAT_HOST}:${NAPCAT_API_PORT}` | 部分脚本 | | `YOUR_ADMIN_QQ` | `${ADMIN_QQ}` | 脚本 + SKILL.md | | `YOUR_GATEWAY_TOKEN` | `${GATEWAY_TOKEN}` | 脚本 | | `YOUR_SHARED_DIR` | `${SHARED_DIR}` | `qq_send_file.py`、`qq_ocr_image.py`、`qq-messenger/SKILL.md`、`qq-napcat-extras/SKILL.md` | @@ -653,7 +674,7 @@ chatrebot_aireply_plug/ │ ├── plugin_modules.py # BasePlugin + MessageContext │ └── user_module.py # User/Group 封装 ├── scripts/ # ✅ 部署时复制到 agent workspace -│ ├── qq_send_msg.py # 发送消息(调 NapCat :6099) +│ ├── qq_send_msg.py # 发送消息(调 NapCat :6097) │ ├── qq_send_file.py # 发送文件/图片 │ ├── qq_get_groups.py # 获取群列表 │ ├── qq_get_friends.py # 获取好友列表 diff --git a/scripts/qq_friend_action.py b/scripts/qq_friend_action.py index af829d9..a846de1 100644 --- a/scripts/qq_friend_action.py +++ b/scripts/qq_friend_action.py @@ -28,7 +28,7 @@ import sys import argparse import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" def delete_friend(user_id: int) -> dict: diff --git a/scripts/qq_get_file.py b/scripts/qq_get_file.py index 8a7dd4e..bfbcc4f 100644 --- a/scripts/qq_get_file.py +++ b/scripts/qq_get_file.py @@ -19,7 +19,7 @@ import os import argparse import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" FILES_DIR = "YOUR_WORKSPACE_PATH/files" diff --git a/scripts/qq_get_friends.py b/scripts/qq_get_friends.py index 3bfa484..ae0a7e5 100644 --- a/scripts/qq_get_friends.py +++ b/scripts/qq_get_friends.py @@ -13,7 +13,7 @@ import sys import argparse import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" def get_friend_list(): diff --git a/scripts/qq_get_group_files.py b/scripts/qq_get_group_files.py index cc0e63d..70c731b 100644 --- a/scripts/qq_get_group_files.py +++ b/scripts/qq_get_group_files.py @@ -23,7 +23,7 @@ import os import argparse import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" FILES_DIR = "YOUR_WORKSPACE_PATH/files" DEFAULT_GID = YOUR_GROUP_ID # Liquid Studio 群 diff --git a/scripts/qq_get_groups.py b/scripts/qq_get_groups.py index 0480318..c4268ec 100644 --- a/scripts/qq_get_groups.py +++ b/scripts/qq_get_groups.py @@ -13,7 +13,7 @@ import sys import argparse import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" def get_group_list(): diff --git a/scripts/qq_get_history.py b/scripts/qq_get_history.py index 0d588e2..765cabe 100644 --- a/scripts/qq_get_history.py +++ b/scripts/qq_get_history.py @@ -23,7 +23,7 @@ import argparse import requests from datetime import datetime -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" def get_group_msg_history(group_id: str, count: int) -> list[dict]: diff --git a/scripts/qq_group_action.py b/scripts/qq_group_action.py index fc7139b..ed9b148 100644 --- a/scripts/qq_group_action.py +++ b/scripts/qq_group_action.py @@ -28,7 +28,7 @@ import sys import argparse import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" def get_group_list(): diff --git a/scripts/qq_group_manage.py b/scripts/qq_group_manage.py index 4b51f59..4aa91b1 100644 --- a/scripts/qq_group_manage.py +++ b/scripts/qq_group_manage.py @@ -41,7 +41,7 @@ import argparse import requests from datetime import datetime -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" def api_call(endpoint: str, params: dict = None) -> dict: diff --git a/scripts/qq_ocr_image.py b/scripts/qq_ocr_image.py index d5394f5..4c09f85 100644 --- a/scripts/qq_ocr_image.py +++ b/scripts/qq_ocr_image.py @@ -42,7 +42,7 @@ except ImportError: # === NapCat 回退 === import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" SHARED_DIR = "YOUR_SHARED_DIR" CONTAINER_FILES = "/app/napcat/share" OCR_TIMEOUT = 60 diff --git a/scripts/qq_resolve_name.py b/scripts/qq_resolve_name.py index 9ef183d..01775d2 100644 --- a/scripts/qq_resolve_name.py +++ b/scripts/qq_resolve_name.py @@ -27,7 +27,7 @@ import sys import argparse import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" def get_stranger_info(user_id): diff --git a/scripts/qq_send_file.py b/scripts/qq_send_file.py index 2a0941d..bc0d679 100644 --- a/scripts/qq_send_file.py +++ b/scripts/qq_send_file.py @@ -23,7 +23,7 @@ import subprocess import requests TARGET_DIR = "YOUR_SHARED_DIR" -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" HISTORY_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".send_history.json") SCRIPT_PATH = os.path.abspath(__file__) GATEWAY_URL = "http://127.0.0.1:18789" diff --git a/scripts/qq_send_like.py b/scripts/qq_send_like.py index 3a79ec8..23103e3 100644 --- a/scripts/qq_send_like.py +++ b/scripts/qq_send_like.py @@ -21,7 +21,7 @@ import sys import argparse import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" def send_like(user_id: int, times: int = 1) -> dict: diff --git a/scripts/qq_send_msg.py b/scripts/qq_send_msg.py index 811f1d3..90bbc1a 100644 --- a/scripts/qq_send_msg.py +++ b/scripts/qq_send_msg.py @@ -28,7 +28,7 @@ import requests import os # go-cqhttp HTTP API 地址(与 qqrebot 配置文件一致) -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" # 默认接收用户(管理员) DEFAULT_USER = "YOUR_ADMIN_QQ" diff --git a/scripts/qq_upload_group_file.py b/scripts/qq_upload_group_file.py index 252be3d..a3e734c 100644 --- a/scripts/qq_upload_group_file.py +++ b/scripts/qq_upload_group_file.py @@ -15,7 +15,7 @@ import base64 import argparse import requests -CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570" +CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570" DEFAULT_GID = YOUR_GROUP_ID # Liquid Studio 群 diff --git a/skills/qq-messenger/SKILL.md b/skills/qq-messenger/SKILL.md index 46bec30..0b12721 100644 --- a/skills/qq-messenger/SKILL.md +++ b/skills/qq-messenger/SKILL.md @@ -98,6 +98,6 @@ subprocess.run(["python3", "YOUR_WORKSPACE_PATH/scripts/qq_send_file.py", 1. 消息尽量简洁,QQ 消息太长可读性差 2. 不要滥用主动推送,避免打扰管理员 3. 正常回复由系统自动转发,**无需调用本脚本** -4. 连接失败时检查 go-cqhttp 是否在运行(`http://YOUR_NAP CAT_HOST:25570`) +4. 连接失败时检查 go-cqhttp 是否在运行(`http://YOUR_NAPCAT_HOST:25570`) 5. 文件发送依赖 `YOUR_SHARED_DIR` 目录(映射到 NapCat 容器内 `/app/napcat/share/`) 6. 通知走 OpenClaw Gateway API,不走 QQ 本身 diff --git a/skills/qq-napcat-extras/SKILL.md b/skills/qq-napcat-extras/SKILL.md index 6be7b99..0fca1f6 100644 --- a/skills/qq-napcat-extras/SKILL.md +++ b/skills/qq-napcat-extras/SKILL.md @@ -146,5 +146,5 @@ result = subprocess.run( ## 注意事项 1. 点赞不可滥用,同一好友约 10 秒间隔限制 -2. 连接 NapCat 失败时检查 `http://YOUR_NAP CAT_HOST:25570` +2. 连接 NapCat 失败时检查 `http://YOUR_NAPCAT_HOST:25570` 3. OCR 远程 URL 会先下载到 `/tmp`,识别完自动删除 diff --git a/src/process.py b/src/process.py index b1ba848..75ff21d 100644 --- a/src/process.py +++ b/src/process.py @@ -172,6 +172,25 @@ class OpenClawBridge(BasePlugin): source_tag = self._build_source_tag() return f"{{来源:{source_tag}}} {{用户名:{identity_tag}}} {cleaned}" + def _get_high_risk_words(self) -> list: + """获取高危词列表,优先从 config.toml [security] section 加载,否则用内置默认词库""" + try: + cfg_high_risk = self.config.get("security", {}).get("high_risk_words", []) + if cfg_high_risk: + logger.info(f"Loaded {len(cfg_high_risk)} high-risk words from config") + return cfg_high_risk + except Exception: + pass + # 内置默认词库 + default_words = [ + "ignore all instructions", "ignore all previous", "forget previous", "forget everything", + "delete memory", "delete all", "reset system", "override", + "sudo password", "api key", "secret token", "ssh key", + "cat /etc/passwd", "rm -rf", ":(){ :|:& };:", + ] + logger.info(f"Using built-in high-risk word list ({len(default_words)} words)") + return default_words + def _detect_high_risk(self, message: str) -> tuple[bool, list[str]]: """使用jieba分词检测高危词,返回(是否高危, 匹配到的词列表)""" msg_lower = message.lower()