- NapCat Docker 部署:目录创建、容器启动、首次扫码登录、OneBot配置 - 端口映射表:6099(HTTP) / 3001(WS) / 9000(WebUI) - 脚本适配说明表:NapCat vs go-cqhttp 差异、文件发送适配、变量速查 - 前提条件改为 NapCat 由本仓库部署 - 架构图标注端口号
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 创建目录结构
# 共享文件目录(用于发文件到 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 容器
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。
# 查看登录二维码
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 上报地址:
# 编辑 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
# 验证 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 下载 qqrebot 框架:
# 下载并解压
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:
[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 服务:
# /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
systemctl daemon-reload
systemctl enable --now qqrebot
第4步:安装 openclaw_bridge 插件
本仓库即 openclaw_bridge 插件的源码,需打包后部署到 qqrebot。
在目标机器上执行打包(因含 C 扩展,必须在此机器上执行):
cd /path/to/chatrebot_aireply_plug
# 安装依赖
pip install -r requirements.txt
# 打包
python3 package.py
将生成的 ZIP 复制到 qqrebot 插件目录:
cp dist/openclaw_bridge.zip /opt/qqrebot/plugins/
创建插件配置文件 /opt/qqrebot/config/openclawbridge/config.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 加载插件:
systemctl restart qqrebot
验证插件已加载:
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:
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:
{
"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
复制脚本:
cp -r /path/to/chatrebot_aireply_plug/scripts/* "${AGENT_WORKSPACE}/scripts/"
复制 Skills:
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
替换脚本中的占位符:
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
openclaw gateway restart
确认新 agent 已加载:
# 查看代理列表
openclaw config get agents.list
# 或在日志中确认
journalctl -u openclaw -f | grep "agent.${NEW_AGENT_ID}"
第8步:端到端验证
- 在 QQ 上给机器人发消息
- 检查 qqrebot 日志:
journalctl -u qqrebot -f | grep OpenClawBridge - 检查 OpenClaw 日志:
journalctl -u openclaw -f - 验证 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 处理
安全上报
当非管理员触发高危词时,插件自动:
- 通过 OneBot API 给
allowed_sender发送告警消息 - 告警内容:用户 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 列表:
HIGH_RISK_WORDS = {
"prompt_injection": ["ignore all instructions", ...],
"memory_manipulation": ["delete memory", ...],
"info_leak": ["sudo password", ...],
"system_commands": ["cat /etc/passwd", ...],
}
添加后重新打包、部署、重启 qqrebot。
许可证
MIT