← 全部文章
25 分钟阅读

机器人

9 次阅读

1,下载 NapCat 官方安装脚本:

curl -fL
-o napcat.sh
https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh

二,直接从 GitHub 下载 先执行: cd /root rm -f napcat.sh curl -4 -fL
--connect-timeout 15
--retry 3
--retry-delay 2
-o napcat.sh
这里加了: -4:强制使用 IPv4 --retry 3:失败后重试三次

不行的话在继续下面的

要先卸载掉以及下载的包哦 方案一:让脚本自动选择代理 不要再指定 --proxy 1,让安装器自动测试直连和其他代理: cd /root rm -rf NapCat rm -f NapCat.Shell.zip

bash napcat.sh --docker n --cli y

然后检查: ls -lh napcat.sh wc -l napcat.sh head -n 3 napcat.sh 正常情况下: 文件大小大约几十 KB 行数大约一千多行 第一行是 #!/bin/bash 官方仓库当前的安装脚本约 48 KB,并且脚本入口就是 Bash。 再检查脚本语法:

bash -n napcat.sh

没有任何输出,说明基本语法正常。

图片描述

napcat启动 如果启动出现乱码的话,退出来, 在服务器执行: export LANG=C.UTF-8 export LC_ALL=C.UTF-8 export TERM=xterm-256color 永久设置utf-8; cat > /etc/default/locale <<'EOF' LANG=C.UTF-8 EOF 然后再重新启动就行了

扫码登陆启动了之后 在服务器执行:

WEBUI_FILE=$(find /root/Napcat -type f -name webui.json 2>/dev/null | head -n 1)

echo "$WEBUI_FILE"

如果找到文件,再执行:

jq '{host, port, token}' "$WEBUI_FILE" 会出现:

root@42928:~# jq '{host, port, token}' "$WEBUI_FILE"

{ "host": "::", "port": 6099, "token": "b0cbedf8bcc3" }

记住这个token,然后直接的终端

ssh -N -L 127.0.0.1:6099:127.0.0.1:6099 root@你的服务器IP

连接成功后,访问http://127.0.0.1:6099/webui/输入刚才的token,就成功进去了

用 openssl rand -hex 24这个python删生成一个随机数,用来当密钥 c42b84b9e1d87f49fc04f0d8dfc8ddb251815c3dbedcfb28 然后再上面的网址网络配置里面添加一个http的服务,把这个填进去。

然后回到服务器 export QQ_USER_ID='写入你的大号的qq号' 就可以联通了 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

QQ 网站监控机器人:从零安装、开发、部署、排错与长期运行

适用场景:在 Linux 服务器上运行 NapCat,通过 OneBot HTTP API 发送 QQ 私聊或群消息;监控程序在本地开发完成后上传服务器,定时检查网站 HTML 或 JSON API,当数据变化、网站异常或恢复时发送 QQ 通知。

本文按本次真实部署过程整理,包含正常流程、实际遇到的问题、错误原因、修复命令、最终启动方式和日常维护方法。


1. 最终成果

部署完成后的数据流程:

目标网站 / JSON API
        ↓
website_monitor.py 定时请求并提取数据
        ↓
与 state 目录中的上一次数据比较
        ↓
数据变化、故障或恢复
        ↓
notifier.py
        ↓
qq_notify.py
        ↓
http://127.0.0.1:3000
        ↓
NapCat / OneBot HTTP API
        ↓
机器人 QQ
        ↓
主 QQ 或 QQ 群收到通知

最终服务器目录:

/root/Napcat/                       # NapCat 与 Linux QQ
/root/start-napcat.sh               # NapCat 启动脚本
/root/start-monitor.sh              # 网站监控启动脚本
/root/stop-monitor.sh               # 网站监控停止脚本
/root/restart-monitor.sh            # 网站监控重启脚本
/root/start-all.sh                  # 启动全部服务

/etc/monitor-project.env            # 正式环境变量,含 HTTP Token 和 QQ 号

/opt/monitor-project/
├── .venv/                          # Linux Python 虚拟环境
├── qq_notify.py                    # QQ 私聊、群聊、登录信息接口
├── notifier.py                     # 统一通知入口
├── website_monitor.py              # 网站监控主程序
├── run_and_notify.py               # 命令执行完成提醒
├── healthcheck.py                  # 环境健康检查
├── test_notify.py                  # QQ 通知测试
├── config.yaml                     # 网站监控规则
├── requirements.txt                # Python 依赖
├── state/                          # 保存上一次监控值
└── logs/                           # 运行日志

2. 本次服务器环境

本次实际环境:

服务器类型:雨云 Linux 实例/容器环境
系统:Debian 11 系列
用户:root
SSH 主机:aam.rainplay.cn
SSH 端口:42466
Python:3.9.2
Docker:不使用
NapCat:Shell 本地安装
systemd:命令存在,但 PID 1 不是 systemd,无法使用 systemctl 管理服务

服务器上先执行了环境检查:

python3 --version || true
pip3 --version || true
docker --version || true
docker compose version || true
git --version || true
systemctl --version || true

最初结果:

Python 3.9.2
pip3: command not found
docker: command not found
git version 2.30.2
systemd 247

2.1 为什么不用安装“编译器”

这个项目是 Python 脚本,不需要 IDEA、PyCharm 或 C/C++ 编译器。服务器只需要:

Python 3
pip
python3-venv
curl
Git
jq
nano
NapCat 运行依赖

3. 安装 Linux 基础环境

由于当前用户已经是 root,命令提示符是:

root@42928:~#

因此普通命令不需要加 sudo

先更新软件源:

apt update

安装基础工具:

apt install -y \
  ca-certificates \
  curl \
  git \
  jq \
  nano \
  python3 \
  python3-pip \
  python3-venv

检查:

python3 --version
pip3 --version
git --version
curl --version

本次结果:

Python 3.9.2
pip 20.3.4
git version 2.30.2
curl 7.74.0

4. 安装非 Docker 版 NapCat

本次明确不使用 Docker,采用 NapCat Shell 本地安装方式。

4.1 下载 NapCat 安装脚本

最初使用的地址:

curl -fL \
  -o napcat.sh \
  https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh

实际报错:

curl: (28) Failed to connect to nclatest.znin.net port 443: Connection timed out

说明服务器到该下载域名网络超时,不是 curl 未安装。

改为从 GitHub Raw 下载:

cd /root
rm -f napcat.sh

curl -4 -fL \
  --connect-timeout 15 \
  --retry 3 \
  --retry-delay 2 \
  -o napcat.sh \
  https://raw.githubusercontent.com/NapNeko/NapCat-Installer/main/script/install.sh

检查脚本:

ls -lh napcat.sh
wc -l napcat.sh
head -n 3 napcat.sh
bash -n napcat.sh

bash -n 没有输出,表示 Shell 语法检查通过。

4.2 安装器提示缺少 sudo

运行:

bash napcat.sh --docker n --cli y --proxy 1

安装器提示:

sudo不存在,请手动安装
Debian/Ubuntu: apt-get install -y sudo

虽然当前是 root,人工执行命令不需要 sudo,但 NapCat 安装脚本内部会检查或调用 sudo,因此仍需安装软件包:

apt update
apt install -y sudo

检查:

command -v sudo
sudo --version | head -n 1

然后重新运行:

cd /root
bash napcat.sh --docker n --cli y --proxy 1

参数含义:

--docker n    不使用 Docker
--cli y       安装 NapCat TUI/CLI 管理工具
--proxy 1     使用安装器的第 1 条下载代理

4.3 下载 NapCat 包时代理失效

依赖安装成功后,下载 NapCat 包时报错:

手动指定代理: https://ghfast.top
curl: (35) OpenSSL SSL_connect: Connection reset by peer
文件下载失败

原因:代理 1 当前不可用或线路被重置。

可选处理方式:

方法 A:让安装器自动测试线路

cd /root
rm -rf NapCat
rm -f NapCat.Shell.zip
bash napcat.sh --docker n --cli y

方法 B:更换代理编号

bash napcat.sh --docker n --cli y --proxy 2

失败后依次尝试:

bash napcat.sh --docker n --cli y --proxy 3
bash napcat.sh --docker n --cli y --proxy 4
bash napcat.sh --docker n --cli y --proxy 5

方法 C:本地下载压缩包再上传

Windows 下载 NapCat Shell 包,上传到服务器 /root/NapCat.Shell.zip,再运行安装器。安装脚本会检测同目录压缩包并继续安装。


5. NapCat 安装后的首次启动

安装完成后刷新命令缓存:

hash -r
command -v napcat

进入 NapCat TUI:

napcat

5.1 TUI 中文乱码

首次打开菜单时,中文显示为乱码,但 STARTSTOPCONFIG 等英文可见。

原因:服务器 Locale 与 SSH 终端编码不一致。

临时修复:

export LANG=C.UTF-8
export LC_ALL=C.UTF-8
export TERM=xterm-256color

检查:

locale

重新进入:

napcat

永久写入 root 的 Bash 配置:

cat >> /root/.bashrc <<'EOF'

export LANG=C.UTF-8
export LC_ALL=C.UTF-8
export TERM=xterm-256color
EOF

source /root/.bashrc

5.2 只看到 TUI 进程,没有 6099 端口

检查:

ps aux | grep -Ei 'napcat|qq' | grep -v grep
ss -lntp | grep -E ':6099|:610[0-9]'

最初只看到:

/usr/local/bin/napcat
/usr/local/bin/_napcat_Boot
dialog ... GOTO_CONFIG

但没有 6099 监听。

这表示当前只是管理菜单或配置向导在等待按键,QQ/NapCat 主程序还没有真正启动。

处理:

进入 CONFIG 或 GOTO_CONFIG
填写机器人 QQ 号
保存配置
返回主菜单选择 START

真正启动后,进程中出现:

/root/Napcat/opt/QQ/qq --no-sandbox -q <机器人QQ号>

并且:

ss -lntp | grep -E ':6099|:610[0-9]'

出现:

LISTEN ... *:6099 ... users:(("qq",pid=...))

这时才说明 NapCat WebUI 已启动。


6. 通过 SSH 隧道访问 NapCat WebUI

NapCat WebUI 位于服务器本机 6099 端口。为了不把后台直接暴露公网,在 Windows PowerShell 建立 SSH 隧道:

ssh -p 42466 -N -L 127.0.0.1:6099:127.0.0.1:6099 root@aam.rainplay.cn

参数含义:

-p 42466                         SSH 连接端口
-N                               只建立隧道,不打开远程命令行
-L 本机地址:本机端口:远端地址:远端端口
127.0.0.1:6099                  Windows 本机监听端口
127.0.0.1:6099                  服务器内部 NapCat WebUI 端口

建立后浏览器打开:

http://127.0.0.1:6099/webui

6.1 channel 1: open failed: connect failed

曾出现:

channel 1: open failed: connect failed

含义:

Windows 到 SSH 服务器连接成功
但服务器内部无法连接 127.0.0.1:6099

常见原因:

NapCat 没启动
6099 没有监听
NapCat 改用了其他端口
关闭原 SSH 后前台 NapCat 跟着退出

服务器检查:

ss -lntp | grep ':6099'
curl -I --max-time 5 http://127.0.0.1:6099/

本次成功结果:

HTTP/1.1 301 Moved Permanently
Location: /webui

301 不是错误,表示访问 / 会自动跳转到 /webui,说明 WebUI 正常。


7. 登录机器人 QQ 与配置 OneBot HTTP 服务

进入 WebUI 后:

QQ 登录
→ QRCode
→ 使用机器人 QQ 小号扫码
→ 手机确认

建议机器人 QQ 使用专门小号,不要使用重要主号。

然后进入:

网络配置
→ 新建
→ HTTP 服务端

推荐配置:

名称:monitor-http
Host:127.0.0.1
Port:3000
Token:随机生成的复杂字符串
消息格式:array
Debug:关闭
启用:打开

生成随机 Token:

openssl rand -hex 24

注意两个 Token 不同:

WebUI Token      登录 NapCat 管理后台
HTTP Token       Python 程序调用 OneBot API

保存后检查:

ss -lntp | grep ':3000'

测试登录信息:

export NAPCAT_TOKEN='替换为真实HTTP Token'

curl -sS \
  -H "Authorization: Bearer ${NAPCAT_TOKEN}" \
  http://127.0.0.1:3000/get_login_info | jq

测试发送私聊:

export QQ_USER_ID='替换为接收提醒的主QQ号'

curl -sS \
  -X POST \
  -H "Authorization: Bearer ${NAPCAT_TOKEN}" \
  -H "Content-Type: application/json" \
  http://127.0.0.1:3000/send_private_msg \
  -d "{
    \"user_id\": \"${QQ_USER_ID}\",
    \"message\": \"Linux服务器QQ通知测试成功\"
  }" | jq

成功后 QQ 收到测试消息。


8. 本地开发 monitor-project

本次采用传统流程:

本机 Agent 开发
→ 本机检查代码
→ 压缩项目
→ SCP 上传服务器
→ 服务器创建 Linux 虚拟环境
→ 安装依赖并运行

本机项目结构:

monitor-project/
├── qq_notify.py
├── notifier.py
├── website_monitor.py
├── run_and_notify.py
├── healthcheck.py
├── test_notify.py
├── config.yaml
├── requirements.txt
├── .env.example
├── .gitignore
├── state/
└── logs/

8.1 本地与服务器的 NAPCAT_URL 不同

本机若通过 SSH 转发服务器的 3000:

ssh -p 42466 -N `
  -L 127.0.0.1:13000:127.0.0.1:3000 `
  root@aam.rainplay.cn

则本机配置:

NAPCAT_URL=http://127.0.0.1:13000

上传到服务器运行后,Python 与 NapCat 在同一台服务器,必须改为:

NAPCAT_URL=http://127.0.0.1:3000

9. 在 Windows 本地正确压缩项目

最初在项目目录中执行:

PS C:\Users\lqpp\Desktop\monitor-project>

然后压缩最后指定 monitor-project,tar 实际查找:

C:\Users\lqpp\Desktop\monitor-project\monitor-project

因此报错:

tar.exe: Couldn't visit directory: No such file or directory

正确方法是先进入项目上一级:

cd C:\Users\lqpp\Desktop

再压缩:

tar --exclude=monitor-project/.venv --exclude=monitor-project/.git --exclude=monitor-project/.env --exclude=monitor-project/__pycache__ --exclude=monitor-project/logs --exclude=monitor-project/state -czf monitor-project.tar.gz monitor-project

检查:

Get-Item .\monitor-project.tar.gz
tar -tzf .\monitor-project.tar.gz | Select-Object -First 30

压缩包位于:

C:\Users\lqpp\Desktop\monitor-project.tar.gz

不要上传 Windows .venv,因为 Windows 虚拟环境不能在 Linux 运行。


10. 使用 SCP 上传项目

首次在 Windows PowerShell 执行:

scp -P 42466 "C:\Users\lqpp\Desktop\monitor-project.tar.gz" root@aam.rainplay.cn:/root/

服务器报错:

/usr/lib/sftp-server: No such file or directory
scp.exe: Connection closed

原因:新版 scp 默认优先使用 SFTP,但服务器没有对应的 SFTP 服务程序。

使用传统 SCP 协议:

scp -O -P 42466 "C:\Users\lqpp\Desktop\monitor-project.tar.gz" root@aam.rainplay.cn:/root/

参数:

-O    强制使用传统 SCP 协议
-P    SCP 指定 SSH 端口,必须大写

10.1 不要在 Linux 服务器执行 Windows 路径命令

曾在:

root@42928:~#

执行:

scp -P 42466 C:\Users\lqpp\Desktop\monitor-project.tar.gz ...

这会失败,因为 Linux 服务器没有 C:\Users\... 路径。

记忆:

PS C:\...>       Windows 本机命令
root@42928:~#    Linux 服务器命令

上传命令必须在存放文件的 Windows 电脑上执行。


11. 服务器解压项目

确认上传:

ls -lh /root/monitor-project.tar.gz

本次实际文件:

-rw-r--r-- 1 root root 7.7K ... /root/monitor-project.tar.gz

解压:

mkdir -p /opt
tar -xzf /root/monitor-project.tar.gz -C /opt

检查:

ls -la /opt/monitor-project

发现项目内有一个只有 29 字节的错误压缩包:

/opt/monitor-project/monitor-project.tar.gz

这是早前本地压缩失败产生的文件,删除:

rm -f /opt/monitor-project/monitor-project.tar.gz

上传后的文件权限曾是 777,过于宽松。修复:

find /opt/monitor-project -type d -exec chmod 755 {} \;
find /opt/monitor-project -type f -exec chmod 644 {} \;

12. 创建 Linux Python 虚拟环境

进入项目:

cd /opt/monitor-project

创建虚拟环境:

python3 -m venv .venv

安装依赖:

.venv/bin/pip install -r requirements.txt

12.1 PyPI 下载超时

连接官方 PyPI 时反复出现:

ReadTimeoutError: HTTPSConnectionPool(host='pypi.org', port=443)
WARNING: Retrying ...

先按:

Ctrl + C

停止重试,然后使用国内镜像。

清华镜像:

.venv/bin/python -m pip install \
  -r requirements.txt \
  -i https://pypi.tuna.tsinghua.edu.cn/simple \
  --timeout 120 \
  --retries 3

阿里云备用:

.venv/bin/python -m pip install \
  -r requirements.txt \
  -i https://mirrors.aliyun.com/pypi/simple/ \
  --timeout 120 \
  --retries 3

检查依赖:

.venv/bin/python -c "import requests, bs4, yaml, dotenv; print('依赖安装成功')"

语法检查:

.venv/bin/python -m compileall \
  -q \
  qq_notify.py \
  notifier.py \
  website_monitor.py \
  run_and_notify.py \
  healthcheck.py \
  test_notify.py

echo $?

输出 0 表示语法检查成功。


13. 配置正式环境变量

复制示例:

cd /opt/monitor-project
cp .env.example /etc/monitor-project.env
nano /etc/monitor-project.env

服务器最终配置模板:

NAPCAT_URL=http://127.0.0.1:3000
NAPCAT_TOKEN=<新的NapCat HTTP Token>
NAPCAT_TIMEOUT=10

ENABLE_QQ_PRIVATE=true
ENABLE_QQ_GROUP=false

QQ_USER_ID=<接收提醒的主QQ号>
QQ_GROUP_ID=

设置权限:

chmod 600 /etc/monitor-project.env

安全查看配置,不显示完整 Token:

sed -E 's/^(NAPCAT_TOKEN=).*/\1***REDACTED***/' /etc/monitor-project.env

13.1 错误:服务器仍配置为 13000

实际错误:

HTTPConnection(host='127.0.0.1', port=13000)
Connection refused

原因:13000 是 Windows 本机 SSH 隧道端口,不是服务器 NapCat 端口。

修复:

NAPCAT_URL=http://127.0.0.1:3000

13.2 错误:配置被终端提示符污染

配置文件中曾出现:

ENABLE_QQ_PRIVATE=trueroot@42928:/opt/monitor-project#

原因:复制粘贴时把终端提示符一起粘进文件。

正确:

ENABLE_QQ_PRIVATE=true

13.3 HTTP Token 已公开

部署过程中完整 HTTP Token 曾被粘贴出来。正确处理:

openssl rand -hex 24

进入 NapCat WebUI 修改 HTTP 服务 Token,再同步修改:

nano /etc/monitor-project.env

旧 Token 不再使用。


14. 加载环境变量并测试项目

每次新开 SSH 终端都要加载:

set -a
source /etc/monitor-project.env
set +a

只检查非敏感变量:

echo "$NAPCAT_URL"
echo "$QQ_USER_ID"
echo "$ENABLE_QQ_PRIVATE"

健康检查:

cd /opt/monitor-project
.venv/bin/python healthcheck.py

发送测试消息:

.venv/bin/python test_notify.py

成功后 QQ 收到:

monitor-project QQ通知测试成功

15. 配置网站监控规则

编辑:

nano /opt/monitor-project/config.yaml

15.1 HTML 网站示例

monitors:
  - id: website-status
    enabled: true
    name: "目标网站状态监控"
    type: html
    url: "https://example.com/status"
    selector: "#status"
    interval_seconds: 60
    timeout_seconds: 20
    headers:
      User-Agent: "Mozilla/5.0"

选择器示例:

<span id="status">处理中</span>

对应:

selector: "#status"
<div class="price">99.00</div>

对应:

selector: ".price"

15.2 JSON API 示例

接口返回:

{
  "data": {
    "status": "completed"
  }
}

配置:

monitors:
  - id: api-status
    enabled: true
    name: "接口状态监控"
    type: json
    url: "https://example.com/api/status"
    json_path: "data.status"
    interval_seconds: 60
    timeout_seconds: 20
    headers:
      User-Agent: "Mozilla/5.0"

16. YAML 配置错误与修复

首次运行时报错:

yaml.scanner.ScannerError
while scanning a simple key
config.yaml, line 7, column 5
could not find expected ':'
line 8, column 5

原因:config.yaml 某一行漏了冒号、缩进错误或使用了 Tab。

查看带行号内容:

nl -ba /opt/monitor-project/config.yaml

备份:

cp config.yaml "config.yaml.bak.$(date +%Y%m%d-%H%M%S)"

写入正确示例:

cat > /opt/monitor-project/config.yaml <<'EOF'
monitors:
  - id: example-title
    enabled: true
    name: "示例网站标题监控"
    type: html
    url: "https://example.com"
    selector: "title"
    interval_seconds: 60
    timeout_seconds: 20
    headers:
      User-Agent: "Mozilla/5.0"
EOF

验证 YAML:

cd /opt/monitor-project

.venv/bin/python - <<'PY'
import yaml
from pprint import pprint

with open("config.yaml", "r", encoding="utf-8") as file:
    config = yaml.safe_load(file)

print("config.yaml 解析成功:")
pprint(config)
PY

以后每次改配置都可以先验证:

.venv/bin/python -c 'import yaml; yaml.safe_load(open("config.yaml", encoding="utf-8")); print("YAML正确")'

YAML 注意事项:

只能用空格缩进,不能使用 Tab
键名后必须有冒号
同一级字段必须对齐
字符串建议使用双引号

17. 前台测试网站监控

创建目录:

cd /opt/monitor-project
mkdir -p state logs

加载环境变量:

set -a
source /etc/monitor-project.env
set +a

启动:

PYTHONUNBUFFERED=1 .venv/bin/python website_monitor.py

第一次运行行为:

请求目标网站
提取目标值
保存到 state/<monitor-id>.json
不发送“数据变化”通知

检查状态文件:

ls -la /opt/monitor-project/state
cat /opt/monitor-project/state/*.json

确认保存的值正是想监控的数据,而不是“登录”“首页”“加载中”或空字符串。

观察一到两个检查周期后按:

Ctrl + C

停止前台测试。


18. 为什么 systemctl 不能使用

曾创建 napcat.service 并执行:

systemctl daemon-reload
systemctl enable --now napcat

报错:

System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

原因:系统安装了 systemctl 命令,但当前实例的 PID 1 不是 systemd,可能是容器或特殊虚拟化环境。

检查 PID 1 的正确命令:

ps -p 1 -o pid=,comm=,args=

注意字段是 args,不是 arg

删除无效服务配置:

rm -f /etc/systemd/system/multi-user.target.wants/napcat.service
rm -f /etc/systemd/system/napcat.service

本次最终不用 systemd,改为 nohup + PID 文件 + 雨云启动命令


19. NapCat 后台运行

曾尝试用 screen:

/root/start-napcat.sh
screen -ls

结果:

No Sockets found in /run/screen/S-root.

表示 screen 中的 QQ 进程启动后立即退出,因此会话自动消失。

最终建议使用 nohup 启动脚本。

19.1 NapCat 启动脚本

<机器人QQ号> 替换成机器人 QQ 号,不要照抄尖括号。

cat > /root/start-napcat.sh <<'EOF'
#!/usr/bin/env bash

set -u

QQ_ID="<机器人QQ号>"
QQ_DIR="/root/Napcat/opt/QQ"
LOG_FILE="/root/Napcat/napcat.log"
PID_FILE="/root/Napcat/napcat.pid"

export HOME="/root"
export LANG="C.UTF-8"
export LC_ALL="C.UTF-8"

if pgrep -f "${QQ_DIR}/qq.*-q ${QQ_ID}" >/dev/null 2>&1; then
    echo "NapCat 已经运行"
    exit 0
fi

cd "$QQ_DIR" || {
    echo "NapCat目录不存在:$QQ_DIR"
    exit 1
}

nohup /usr/bin/xvfb-run -a \
    ./qq --no-sandbox -q "$QQ_ID" \
    >> "$LOG_FILE" 2>&1 </dev/null &

echo $! > "$PID_FILE"

sleep 8

if pgrep -f "${QQ_DIR}/qq.*-q ${QQ_ID}" >/dev/null 2>&1; then
    echo "NapCat 启动成功"
    exit 0
fi

echo "NapCat 启动失败,最近日志:"
tail -n 50 "$LOG_FILE" 2>/dev/null
exit 1
EOF

chmod +x /root/start-napcat.sh

启动:

/root/start-napcat.sh

检查:

pgrep -af '/root/Napcat/opt/QQ/qq'
ss -lntp | grep -E ':3000|:6099'
tail -n 100 /root/Napcat/napcat.log

20. 网站监控后台运行

20.1 启动脚本

cat > /root/start-monitor.sh <<'EOF'
#!/usr/bin/env bash

PROJECT_DIR="/opt/monitor-project"
ENV_FILE="/etc/monitor-project.env"
PID_FILE="${PROJECT_DIR}/website-monitor.pid"
LOG_FILE="${PROJECT_DIR}/logs/website-monitor.log"

mkdir -p "${PROJECT_DIR}/state" "${PROJECT_DIR}/logs"

if [ ! -f "$ENV_FILE" ]; then
    echo "配置文件不存在:$ENV_FILE"
    exit 1
fi

if [ -f "$PID_FILE" ]; then
    PID="$(cat "$PID_FILE" 2>/dev/null)"

    if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null; then
        echo "网站监控已经运行,PID:$PID"
        exit 0
    fi

    rm -f "$PID_FILE"
fi

set -a
source "$ENV_FILE"
set +a

cd "$PROJECT_DIR" || exit 1

nohup env PYTHONUNBUFFERED=1 \
    "$PROJECT_DIR/.venv/bin/python" \
    "$PROJECT_DIR/website_monitor.py" \
    >> "$LOG_FILE" 2>&1 </dev/null &

PID=$!
echo "$PID" > "$PID_FILE"

sleep 3

if kill -0 "$PID" 2>/dev/null; then
    echo "网站监控启动成功,PID:$PID"
    echo "日志位置:$LOG_FILE"
else
    echo "网站监控启动失败"
    rm -f "$PID_FILE"
    tail -n 50 "$LOG_FILE"
    exit 1
fi
EOF

chmod +x /root/start-monitor.sh

启动:

/root/start-monitor.sh

检查:

pgrep -af 'website_monitor.py'
cat /opt/monitor-project/website-monitor.pid
tail -n 100 /opt/monitor-project/logs/website-monitor.log

实时日志:

tail -f /opt/monitor-project/logs/website-monitor.log

Ctrl+C 只退出日志查看,不会停止监控。

20.2 停止脚本

cat > /root/stop-monitor.sh <<'EOF'
#!/usr/bin/env bash

PID_FILE="/opt/monitor-project/website-monitor.pid"

if [ ! -f "$PID_FILE" ]; then
    echo "监控程序没有PID文件,可能未运行"
    exit 0
fi

PID="$(cat "$PID_FILE" 2>/dev/null)"

if [ -z "$PID" ]; then
    rm -f "$PID_FILE"
    echo "PID文件为空"
    exit 0
fi

if kill -0 "$PID" 2>/dev/null; then
    kill "$PID"

    for _ in $(seq 1 10); do
        if ! kill -0 "$PID" 2>/dev/null; then
            break
        fi
        sleep 1
    done
fi

if kill -0 "$PID" 2>/dev/null; then
    kill -9 "$PID"
fi

rm -f "$PID_FILE"
echo "网站监控已停止"
EOF

chmod +x /root/stop-monitor.sh

20.3 重启脚本

cat > /root/restart-monitor.sh <<'EOF'
#!/usr/bin/env bash

/root/stop-monitor.sh
sleep 2
/root/start-monitor.sh
EOF

chmod +x /root/restart-monitor.sh

使用:

/root/start-monitor.sh
/root/stop-monitor.sh
/root/restart-monitor.sh

21. 启动全部服务

创建统一启动脚本:

cat > /root/start-all.sh <<'EOF'
#!/usr/bin/env bash

LOG_FILE="/root/start-all.log"

{
    echo "========================================"
    echo "开始启动:$(date '+%F %T')"

    echo "启动 NapCat..."
    /root/start-napcat.sh

    echo "等待 NapCat HTTP 接口..."
    NAPCAT_READY=false

    for _ in $(seq 1 60); do
        if curl -sS --max-time 2 \
            http://127.0.0.1:3000/ \
            >/dev/null 2>&1; then
            NAPCAT_READY=true
            break
        fi

        sleep 2
    done

    if [ "$NAPCAT_READY" = "true" ]; then
        echo "NapCat HTTP 接口已经就绪"
    else
        echo "警告:等待 NapCat HTTP 接口超时"
    fi

    echo "启动网站监控..."
    /root/start-monitor.sh

    echo "启动流程完成:$(date '+%F %T')"
} >> "$LOG_FILE" 2>&1
EOF

chmod +x /root/start-all.sh

手动执行:

/root/start-all.sh

查看启动日志:

cat /root/start-all.log

22. 雨云实例自动启动

由于 systemd 不可用,需要在雨云控制面板寻找:

启动命令
开机命令
实例启动脚本
容器启动命令
自定义启动脚本

填写:

/bin/bash /root/start-all.sh

如果面板支持输出重定向:

/bin/bash /root/start-all.sh >> /root/rain-startup.log 2>&1

保存后重启实例,再检查:

ss -lntp | grep -E ':3000|:6099'
pgrep -af 'website_monitor.py'
tail -n 100 /root/start-all.log
tail -n 50 /opt/monitor-project/logs/website-monitor.log

23. 日常使用与维护

23.1 检查完整状态

echo "===== NapCat端口 ====="
ss -lntp | grep -E ':3000|:6099' || true

echo "===== NapCat进程 ====="
pgrep -af '/root/Napcat/opt/QQ/qq' || true

echo "===== 监控进程 ====="
pgrep -af 'website_monitor.py' || true

echo "===== 监控日志 ====="
tail -n 30 /opt/monitor-project/logs/website-monitor.log

23.2 修改监控规则

nano /opt/monitor-project/config.yaml

验证:

cd /opt/monitor-project
.venv/bin/python -c 'import yaml; yaml.safe_load(open("config.yaml", encoding="utf-8")); print("YAML配置正确")'

重启:

/root/restart-monitor.sh

23.3 查看状态数据

ls -la /opt/monitor-project/state
cat /opt/monitor-project/state/*.json

23.4 查看日志

tail -n 100 /opt/monitor-project/logs/website-monitor.log
tail -f /opt/monitor-project/logs/website-monitor.log

23.5 测试 QQ 通知

set -a
source /etc/monitor-project.env
set +a

cd /opt/monitor-project
.venv/bin/python test_notify.py

23.6 测试 NapCat API

set -a
source /etc/monitor-project.env
set +a

curl -sS \
  -H "Authorization: Bearer ${NAPCAT_TOKEN}" \
  "${NAPCAT_URL}/get_login_info" | jq

24. 后续更新项目代码

本机开发修改后,重新打包:

cd C:\Users\lqpp\Desktop

tar --exclude=monitor-project/.venv --exclude=monitor-project/.git --exclude=monitor-project/.env --exclude=monitor-project/__pycache__ --exclude=monitor-project/logs --exclude=monitor-project/state -czf monitor-project.tar.gz monitor-project

上传:

scp -O -P 42466 "C:\Users\lqpp\Desktop\monitor-project.tar.gz" root@aam.rainplay.cn:/root/

服务器先停止监控:

/root/stop-monitor.sh

备份旧项目:

mv /opt/monitor-project "/opt/monitor-project.bak.$(date +%Y%m%d-%H%M%S)"

解压新版本:

tar -xzf /root/monitor-project.tar.gz -C /opt
cd /opt/monitor-project
python3 -m venv .venv

安装依赖:

.venv/bin/python -m pip install \
  -r requirements.txt \
  -i https://pypi.tuna.tsinghua.edu.cn/simple \
  --timeout 120

恢复或重新填写 config.yaml,确保 /etc/monitor-project.env 不被覆盖,然后启动:

/root/start-monitor.sh

25. 安全注意事项

  1. NAPCAT_TOKEN 不要写进 GitHub、截图、聊天或前端代码。
  2. Token 泄露后立即在 NapCat WebUI 中重新生成,并修改 /etc/monitor-project.env
  3. 环境变量文件权限保持:
chmod 600 /etc/monitor-project.env
  1. 30006099 不应在雨云防火墙或端口映射中公开。
  2. WebUI 建议绑定 127.0.0.1,通过 SSH 隧道访问。
  3. 使用专门机器人 QQ 小号,避免重要主号受登录或风控影响。
  4. 不要把 Cookie、Authorization 等网站登录信息直接提交到 Git。

26. 本次问题汇总速查表

问题 原因 解决方法
sudo: command not found root 系统没有安装 sudo,但安装器内部需要 apt install -y sudo
NapCat 安装地址连接超时 下载域名线路不可达 改 GitHub Raw、切换代理或本地下载上传
ghfast.top SSL reset 安装器代理 1 失效 自动选择线路或 --proxy 2/3/4/5
TUI 中文乱码 Locale/终端编码不一致 LANG=C.UTF-8LC_ALL=C.UTF-8
只有 TUI 进程,没有 6099 主程序还未启动,在等配置 CONFIG 后选择 START
SSH 隧道 channel open failed 服务器内部 6099 未监听 启动 NapCat并用 curl 127.0.0.1:6099 检查
301 Location: /webui WebUI 正常跳转 浏览器访问 /webui
systemctl 无法使用 PID 1 不是 systemd 使用 nohup 脚本和雨云启动命令
tar 找不到 monitor-project 在项目目录内又指定了同名子目录 回到 Desktop 上一级再压缩
SCP 缺少 sftp-server 新版 scp 默认使用 SFTP 使用 scp -O
在服务器执行 Windows 路径 混淆本机与服务器终端 C:\... 只能在 Windows PowerShell 使用
pip 连接 pypi.org 超时 服务器到官方 PyPI 线路差 使用清华或阿里云镜像
Python 请求 127.0.0.1:13000 被拒 13000 只属于本机 SSH 隧道 服务器配置改成 127.0.0.1:3000
.env 出现 trueroot@... 粘贴时混入终端提示符 编辑文件,只保留 ENABLE_QQ_PRIVATE=true
YAML could not find expected ':' 漏冒号、缩进错误或 Tab 替换正确 YAML并先用 PyYAML 验证
第一次没有变化提醒 程序需要先保存初始值 等待后续实际变化,属于正常行为
screen 会话立即消失 screen 内的 QQ 进程启动后退出 查看日志,最终使用 nohup 方式

27. 最终验收标准

[✓] NapCat QQ 进程存在
[✓] 6099 WebUI 可通过 SSH 隧道访问
[✓] 3000 OneBot HTTP API 可访问
[✓] test_notify.py 可以发送 QQ 消息
[✓] config.yaml 可以正常解析
[✓] website_monitor.py 能获取目标数据
[✓] state 目录产生对应 JSON 状态文件
[✓] 数据变化后 QQ 收到通知
[✓] 关闭 SSH 后监控进程继续运行
[✓] 雨云实例重启后 start-all.sh 自动启动
[✓] HTTP Token 已更换且未公开
[✓] 3000、6099 未直接暴露公网

28. 最常用命令速记

# 启动所有
/root/start-all.sh

# 启动网站监控
/root/start-monitor.sh

# 停止网站监控
/root/stop-monitor.sh

# 重启网站监控
/root/restart-monitor.sh

# 查看 NapCat 端口
ss -lntp | grep -E ':3000|:6099'

# 查看网站监控进程
pgrep -af 'website_monitor.py'

# 查看监控日志
tail -f /opt/monitor-project/logs/website-monitor.log

# 编辑网站监控配置
nano /opt/monitor-project/config.yaml

# 验证 YAML
cd /opt/monitor-project
.venv/bin/python -c 'import yaml; yaml.safe_load(open("config.yaml", encoding="utf-8")); print("YAML配置正确")'

# 测试 QQ 消息
set -a
source /etc/monitor-project.env
set +a
cd /opt/monitor-project
.venv/bin/python test_notify.py

Windows 打开 WebUI 隧道:

ssh -p 42466 -N -L 127.0.0.1:6099:127.0.0.1:6099 root@aam.rainplay.cn

浏览器:

http://127.0.0.1:6099/webui

文档中的 QQ 号和 Token 均使用占位符。实际部署时请填写自己的值,不要把真实 Token 上传到代码仓库或公开聊天中。

QQ 机器人(NapCat + OneBot 11)部署与排障教学文档

适用范围:本次实际部署的 QQ 机器人,而非 Telegram。虽然导出的聊天 HTML 文件名包含“TG”,但聊天记录、目录和日志均表明使用的是 NapCat + QQ + OneBot 11

部署目录:/opt/monitor-project
NapCat 目录:/root/Napcat
OneBot HTTP 端口:3000(仅本机监听)
OneBot WebSocket 端口:3001(仅本机监听)


1. 完成效果与架构

部署完成后,QQ 用户给机器人账号发送私聊消息,NapCat 接收 QQ 事件;机器人服务根据已有规则或 AI 配置生成回复,再通过 OneBot 11 调用由 NapCat 发回 QQ。

flowchart LR
    A[QQ 用户] --> B[QQ 客户端 / QQ 网络]
    B --> C[NapCat]
    C -->|OneBot 11 WebSocket<br/>ws://127.0.0.1:3001| D[机器人服务<br/>/opt/monitor-project]
    D -->|OneBot 11 HTTP Action API<br/>http://127.0.0.1:3000| C
    C --> B

本次已经确认过的事实:

  • NapCat 使用 非 Docker 安装方式;
  • OneBot HTTP 服务配置为 127.0.0.1:3000
  • OneBot WebSocket 服务配置为 127.0.0.1:3001
  • 两个接口都设置了 token;
  • 在此前 QQ 登录有效时,日志中已经出现“接收私聊”和“发送 AI 自动回复”,说明消息收发闭环曾正常工作;
  • 当前一次排查时,QQ 登录态失效并被提示账号安全风险,导致 NapCat 未完成登录,因此 3001 没有监听。这是 QQ 登录问题,不是端口或机器人代码本身的问题。

2. 准备信息

部署前请准备:

  • 一台 Linux 服务器(本次用 root 用户操作);
  • 服务器公网 IP 或域名;
  • 可以登录 QQ 的手机,并已安装最新版手机 QQ;
  • 用作机器人的 QQ 账号;
  • 已部署或准备部署的机器人服务代码;本次服务目录为 /opt/monitor-project
  • 一个随机且不泄露的 OneBot token;
  • 如机器人调用大模型,准备相应 API Key,并只写入服务器环境变量或私有 .env 文件。

安全原则:不要把 QQ 密码、OneBot token、WebUI token、二维码登录 URL、模型 API Key 写入 Git 仓库、教程截图或公开聊天记录。


3. 从本地 SSH 登录服务器

3.1 Windows PowerShell

在 Windows PowerShell 中执行,替换为你的服务器公网 IP:

ssh root@<服务器公网IP>

例如:

ssh root@203.0.113.10

首次连接会询问是否信任主机指纹,核对 IP 无误后输入 yes。随后输入服务器 root 密码,或使用已配置的 SSH 密钥。

如果 SSH 不是默认的 22 端口:

ssh -p <端口号> root@<服务器公网IP>

若使用密钥:

ssh -i "$HOME\.ssh\id_ed25519" root@<服务器公网IP>

3.2 登录后的确认

whoami
pwd
uname -a

本次终端提示符形如:

root@42928:/opt/monitor-project#

说明当时已以 root 身份进入机器人项目目录 /opt/monitor-project


4. 安装 NapCat

4.1 本次实际执行的安装选择

聊天记录中的安装命令是:

bash napcat.sh --docker n --cli y --proxy 1

参数含义:

参数 本次选择 含义
--docker n n 不通过 Docker 安装/运行 NapCat
--cli y y 使用命令行方式安装或管理
--proxy 1 1 使用安装脚本提供的第 1 个代理/下载选项

运行后,安装脚本会继续在终端中交互。你看到“像图片一样”的内容,通常是终端打印的 QQ 登录二维码字符画,不是命令损坏,也不是图片文件。请在手机 QQ 中扫描并授权;如果终端显示二维码解码 URL,也应把它视为一次性敏感登录凭据,不要发给他人。

4.2 确认安装结果

安装完成后执行:

which napcat
ps aux | grep '[n]apcat'
ls -la /root/Napcat

本次记录中可见的进程包括:

/bin/bash /usr/local/bin/napcat
/bin/bash /usr/local/bin/_napcat_Boot

它们是 NapCat 安装程序创建或调用的启动脚本,不是本次手工编写的机器人业务脚本。不要随意修改 /usr/local/bin/_napcat_Boot;升级/重装 NapCat 时它可能会被覆盖。


5. QQ 登录与启动 NapCat

在服务器上启动:

napcat

若安装器明确提供其他启动命令,以安装器输出为准。启动后,查看最新日志:

LOG=$(find /root/Napcat -type f -name '*.log' -printf '%T@ %p\n' 2>/dev/null | sort -nr | head -1 | cut -d' ' -f2-)
echo "$LOG"
tail -n 100 "$LOG"

成功登录后,应能看到类似信息:

网络已连接
正在快速登录 <QQ号码>

并且在收到消息后出现:

接收 <- 私聊 (<用户QQ号>) <消息内容>
发送 -> 私聊 (<用户QQ号>) <机器人回复>

这些“接收”和“发送”日志是确认 QQ 端闭环最直接的证据。

5.1 登录态失效时的处理

本次排查出现过:

快速登录错误:登录态已失效,请重新登录。
Login Error ... 你的账号近期存在安全风险,部分功能使用受限,请登录最新手机QQ并根据提示恢复账号使用。

处理顺序:

  1. 在手机 QQ 登录该机器人账号;
  2. 按 QQ 的安全提示完成验证或解除限制;
  3. 确认手机 QQ 可以正常收发消息;
  4. 回到服务器停止并重新启动 NapCat;
  5. 再次扫描新生成的二维码并在手机确认;
  6. 用另一个 QQ 账号向机器人发测试消息。

不要通过绕过 QQ 风控、共享登录二维码、公开密码等方式解决。账号限制只能由账号本人按 QQ 的官方验证流程恢复。


6. 配置 OneBot 11

6.1 配置文件位置

本次登录账号对应的配置文件为:

/root/Napcat/opt/QQ/resources/app/app_launcher/napcat/config/onebot11_<QQ号码>.json

同目录通常还会有:

onebot11.json
napcat.json
napcat_<QQ号码>.json
webui.json

修改前先备份:

CFG='/root/Napcat/opt/QQ/resources/app/app_launcher/napcat/config/onebot11_<QQ号码>.json'
cp "$CFG" "${CFG}.bak.$(date +%F-%H%M%S)"

编辑文件:

nano "$CFG"

也可以使用 vim

vim "$CFG"

6.2 本次生效的关键配置

下面是根据聊天记录整理后的脱敏版本。将 <ONEBOT_TOKEN> 替换为你自己生成的随机 token;HTTP 和 WebSocket 连接双方必须使用同一套约定。

{
  "network": {
    "httpServers": [
      {
        "enable": true,
        "name": "<机器人名称>",
        "host": "127.0.0.1",
        "port": 3000,
        "enableCors": true,
        "enableWebsocket": false,
        "messagePostFormat": "array",
        "token": "<ONEBOT_TOKEN>",
        "debug": true
      }
    ],
    "httpSseServers": [],
    "httpClients": [],
    "websocketServers": [
      {
        "enable": true,
        "name": "chat-ws",
        "host": "127.0.0.1",
        "port": 3001,
        "reportSelfMessage": false,
        "enableForcePushEvent": true,
        "messagePostFormat": "array",
        "token": "<ONEBOT_TOKEN>",
        "debug": false,
        "heartInterval": 30000
      }
    ],
    "websocketClients": [],
    "plugins": []
  }
}

配置含义:

配置 用途
httpServers / 127.0.0.1:3000 本机机器人服务调用 OneBot Action API,例如发送私聊消息
websocketServers / 127.0.0.1:3001 本机机器人服务连入后接收 QQ 事件,例如私聊消息通知
host: 127.0.0.1 只允许同一台服务器访问,避免把控制接口直接暴露到公网
token 调用 HTTP API 或连接 WebSocket 时的鉴权凭据
reportSelfMessage: false 不把机器人自己发出的消息再次上报,避免形成自触发循环
enableForcePushEvent: true 强制推送事件,保证机器人服务能接收到消息事件
heartInterval: 30000 每 30 秒发送一次心跳,便于客户端发现断连

6.3 校验 JSON 是否写坏

python3 -m json.tool "$CFG" >/dev/null && echo 'JSON 配置正确'

只要命令输出 JSON 配置正确,说明 JSON 格式正常;若报错,按报出的行号检查引号、逗号和大括号。

6.4 查看配置时隐藏 token

不要直接把原始配置截图或粘贴到群聊。可以执行下面的脱敏查看命令:

python3 - <<'PY'
import json

p = '/root/Napcat/opt/QQ/resources/app/app_launcher/napcat/config/onebot11_<QQ号码>.json'
with open(p, encoding='utf-8') as f:
    data = json.load(f)

def hide(value):
    if isinstance(value, dict):
        return {
            k: ('***' if v else '')
            if any(x in k.lower() for x in ('token', 'secret', 'password'))
            else hide(v)
            for k, v in value.items()
        }
    if isinstance(value, list):
        return [hide(x) for x in value]
    return value

print(json.dumps(hide(data), ensure_ascii=False, indent=2))
PY

这段脚本只用于读取并脱敏展示配置,不会改动配置文件。


7. 配置并启动机器人业务服务

7.1 本次已知项目目录

聊天记录中项目工作目录是:

cd /opt/monitor-project
pwd

7.2 机器人服务需要做的两件事

机器人业务代码必须:

  1. 连接 ws://127.0.0.1:3001,接收 OneBot 11 的消息事件;
  2. 通过 http://127.0.0.1:3000 调用 Action API,发送回复。

如果你的代码使用环境变量,推荐把地址和 token 放在私有 .env(并加入 .gitignore):

ONEBOT_WS_URL=ws://127.0.0.1:3001
ONEBOT_HTTP_URL=http://127.0.0.1:3000
ONEBOT_ACCESS_TOKEN=<ONEBOT_TOKEN>

聊天记录没有保留 /opt/monitor-project 中业务程序的文件名和源码,因此不能把某个 app.pybot.pymain.js 断言为“本次实际写过的脚本”。已能确认的脚本/命令只有:

名称 来源/作用 是否手工业务代码
napcat.sh NapCat 安装脚本,曾以 bash napcat.sh --docker n --cli y --proxy 1 执行
/usr/local/bin/napcat NapCat 启动脚本
/usr/local/bin/_napcat_Boot NapCat 内部引导脚本
第 6.4 节 Python 脚本 脱敏打印 OneBot 配置 运维辅助脚本,不是机器人业务逻辑

因此,若需把业务服务精确写入后续版本文档,请补充 /opt/monitor-project 下的目录清单、启动命令或服务文件,再把实际脚本名补入本节。

7.3 典型启动方式

在项目目录内先找启动说明:

cd /opt/monitor-project
find . -maxdepth 2 -type f \( -name 'README*' -o -name 'requirements.txt' -o -name 'package.json' -o -name 'docker-compose.yml' -o -name '*.service' \) -print

按项目技术栈启动(只选择符合项目文件的那一种):

# Python 项目示例
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python3 app.py

# Node.js 项目示例
npm ci
npm run start

上面的 app.pynpm run start 是通用示例,并非从聊天记录确认的真实文件名或真实启动命令。不要不检查项目文件就直接执行。


8. 启动后的验证清单

8.1 确认 NapCat 进程

ps aux | grep '[n]apcat'

8.2 确认 OneBot 端口

ss -lntp | grep -E ':3000|:3001'

正常且登录成功时,预期能看到类似:

LISTEN ... 127.0.0.1:3000 ...
LISTEN ... 127.0.0.1:3001 ...

8.3 查看 NapCat 最近日志

LOG=$(find /root/Napcat -type f -name '*.log' -printf '%T@ %p\n' 2>/dev/null | sort -nr | head -1 | cut -d' ' -f2-)
tail -n 100 "$LOG"

8.4 端到端测试

  1. 用另一个 QQ 账号给机器人账号发送一条纯文字消息,例如“你好”;
  2. 服务器日志应先出现“接收 <- 私聊”;
  3. 机器人业务服务日志应出现接收到 OneBot 事件;
  4. 业务服务调用 OneBot HTTP API;
  5. NapCat 日志出现“发送 -> 私聊”;
  6. 测试 QQ 账号收到回复。

优先测试纯文本。聊天记录中的机器人已明确对图片、语音、文件采取“暂时只处理文字”的回复策略,所以这些类型不应作为第一轮连通性验证依据。


9. 本次遇到的问题与解答

问题 1:执行安装命令后终端变成“图片”

现象:执行以下命令后出现大块图案:

bash napcat.sh --docker n --cli y --proxy 1

原因:大概率是 NapCat/QQ 在命令行输出二维码字符画,用于手机 QQ 扫码登录。

解决:用手机 QQ 扫描二维码并授权;若不好扫,使用程序显示的二维码文件或按其官方提示处理。二维码和解码链接等同于临时登录凭据,不要公开。

问题 2:ss -lntp | grep 3001 没有输出

现象:检查 3001 端口时没有监听记录。

原因:日志显示 NapCat 启动后 QQ 快速登录失败,随后扫码登录又因 QQ 账号安全风险被拒绝。OneBot WebSocket 服务往往不会在 QQ 登录未完成时进入可用状态。

解决:先按第 5.1 节恢复 QQ 账号可用状态并重新登录,再检查端口。不要先把问题误判为防火墙或 WebSocket 配置错误。

问题 3:日志出现大量 DBus 错误

现象:有类似:

Failed to connect to the bus
Failed to connect to socket /run/dbus/system_bus_socket

结论:在无桌面、无 system DBus 的服务器环境中,这类 Electron/QQ 组件日志很常见。若后续出现 NapCat 核心加载成功、网络已连接等信息,它通常不是阻塞部署的根因。

处理原则:以 QQ 登录结果、OneBot 端口监听和实际收发消息为准;只有服务完全无法继续启动时,才进一步调查该错误。

问题 4:快速登录提示“登录态已失效”

原因:此前保存的 QQ 会话已过期或被 QQ 失效。

解决:重新扫码登录;若仍提示账号安全风险,先在最新手机 QQ 完成安全验证。

问题 5:机器人之前能回复,现在不工作

按下面顺序定位:

# 1) NapCat 是否在运行
ps aux | grep '[n]apcat'

# 2) QQ 登录/收消息日志是否正常
LOG=$(find /root/Napcat -type f -name '*.log' -printf '%T@ %p\n' 2>/dev/null | sort -nr | head -1 | cut -d' ' -f2-)
tail -n 100 "$LOG"

# 3) OneBot 端口是否监听
ss -lntp | grep -E ':3000|:3001'

# 4) 机器人项目是否仍在运行(按实际项目调整关键字)
ps aux | grep -E '[p]ython|[n]ode'

判断方法:

  • 没有“接收 <- 私聊”:优先查 QQ 登录/NapCat;
  • 有接收、无业务服务日志:优先查 WebSocket 地址、token、机器人进程;
  • 有业务服务日志、无“发送 -> 私聊”:优先查 HTTP 地址、token、Action API 调用;
  • 有“发送 -> 私聊”但手机未收到:查目标账号、QQ 网络与 QQ 平台限制。

10. 日常运维命令

查看 OneBot 配置文件

ls -l /root/Napcat/opt/QQ/resources/app/app_launcher/napcat/config/

实时跟踪 NapCat 日志

LOG=$(find /root/Napcat -type f -name '*.log' -printf '%T@ %p\n' 2>/dev/null | sort -nr | head -1 | cut -d' ' -f2-)
tail -f "$LOG"

Ctrl+C 停止实时查看,不会停止 NapCat。

修改配置后的安全步骤

CFG='/root/Napcat/opt/QQ/resources/app/app_launcher/napcat/config/onebot11_<QQ号码>.json'
python3 -m json.tool "$CFG" >/dev/null && echo 'JSON 配置正确'

确认配置正确后,重启 NapCat,再执行端口和收发消息测试。

防火墙说明

当前 30003001 都绑定 127.0.0.1,不需要对公网开放,也不应开放。机器人业务服务与 NapCat 在同一台服务器时,无需增加云安全组或 UFW 规则。

只有确实需要让另一台可信服务器连接 OneBot 时,才应改为受控内网地址,并结合防火墙白名单、强 token、TLS/反向代理等措施;这属于架构变更,不建议在当前部署中直接照做。


11. 最终交付检查表

  • 可通过 ssh root@<服务器公网IP> 登录服务器;
  • NapCat 进程存在;
  • 手机 QQ 已完成机器人账号安全验证与登录;
  • /root/Napcat/.../onebot11_<QQ号码>.json JSON 格式正确;
  • 30003001 均仅监听在 127.0.0.1
  • 机器人业务服务使用正确的 WebSocket 地址、HTTP 地址和 token;
  • 另一 QQ 账号发送文字消息后,NapCat 日志出现接收与发送记录;
  • 没有将 token、WebUI URL、二维码 URL、密码或模型 API Key 提交到仓库或文档。

完成这份清单后,QQ 机器人部署即具备可复现、可验证、可排障的基础闭环。

Conversation

留下你的回声