fix: 通过本地完整测试发现的 11 个 bug
🔴 致命(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 回复
This commit is contained in:
251
README.md
251
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://<host>: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 # 获取好友列表
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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 群
|
||||
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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]:
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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 群
|
||||
|
||||
|
||||
|
||||
@ -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 本身
|
||||
|
||||
@ -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`,识别完自动删除
|
||||
|
||||
@ -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()
|
||||
|
||||
Reference in New Issue
Block a user