版本:v9.9.9 生成日期:2026-08-27 适用对象:超级管理员 / 运维人员 服务器:124.222.143.14(root 登录凭据不公开,请联系管理员获取)
管家系统是一套多机器人 QQ 群管理系统:一个后台面板集中管理多个 QQ 机器人(NapCat 实例)加入的所有群聊与功能开关。
| 组件 | 说明 | 位置 / 端口 |
|---|---|---|
| 前端 | 管理面板(nginx 托管静态文件) | /guanjia/ |
| 高级管理页 | 入群审核 / 邀请码 / 管理层级独立入口 | /guanjia/manage.html |
| 后端 | Node.js 服务(pm2 进程 guanjia-backend) | 代码 /opt/hunono/hunuanguanjia/backend,监听 127.0.0.1:3456 |
| 主数据库 | SQLite(管家自己的业务库) | /opt/hunono/hunuanguanjia/backend/data/hunuanguanjia.db |
| 机器人本体库 | SQLite(机器人真正支持的功能清单) | docker 卷 hunono-qq-bot-platform_backend-data/_data/hunono.db |
| 机器人接入层 | NapCat 容器(每个 QQ 一个),OneBot HTTP 端口 | 3000–3099 段 |
| 机器人本体平台 | hunono-qq-bot-platform(真正执行机器人逻辑) | docker 容器,仅托管主 bot 2971723646 |
QQ 群 ──(NapCat 3000-3099)──► guanjia 后端 ──► hunono.db(功能真相源)
▲ │ ▲
└──── 机器人收发消息 ◄──────────┘ └── 每5分钟 AutoSync(发现+群+功能)
系统做到:机器人自己同步上来、QQ 群自己同步上来、功能也自己同步上来。三者均在后端每 5 分钟 AutoSync 自动完成,无需人工干预。
3000–3099,对每个开放端口调用 /get_login_info 探活,与 bot_instances 表对比:noRemove=true,即发现不到的机器人只标记离线,绝不删除其群数据。详见第六节。group_id 去重合并。bot_group_relations(机器人与群的归属关系),保证「A 机器人加的群只显示在 A 名下」。hunono.db 的 functions 表(机器人真正实现的 24 个功能,module_key/name)。functions 目录对齐:is_active = 1(面板显示);is_active = 0(面板永不显示)。function_key)相同或中文名相同即视为支持(兼容 music↔song、bot_master↔admin_tools、check_in↔group_checkin 这类命名差异)。「分配」指把机器人实例分配给哪个用户使用,以及谁是这个 QQ 的主人、何时到期。
bot_instances 表)| 字段 | 含义 |
|---|---|
assigned_to | 分配给的用户 ID(0 = 未分配 / 平台公有) |
owner_qq | 该机器人对应 QQ 的「主人」QQ 号 |
expire_at | 使用到期时间(Unix 时间戳,0 = 永久) |
created_by | 创建者用户 ID |
notes | 备注 |
POST /api/bots/:id/assign
{ "user_id": 12, "expire_at": 0, "notes": "分配给张三" }
user_id = 0 表示收回分配。POST /api/bots/:id/owner { "owner_qq": "2971723646" } # 绑定 QQ 主人
POST /api/bots/:id/expire { "expire_at": 0 } # 0=永久
POST /api/bots/:id/expire { "extend_days": 30 } # 在原到期日上顺延
| 角色 | 可见范围 |
|---|---|
super_admin(超管) | 全部机器人,可分配 / 解绑 / 设到期 |
admin(管理员) | 自己被分配的、或自己创建的机器人 |
user(普通用户) | 仅 assigned_to = 自己 的机器人 |
普通用户对其他机器人调用GET /api/bots/:id/groups会返回403 无权限。
| ID | 名称(库内) | 实际 QQ 昵称 | QQ 号 | 端口 | 群数 | 来源 |
|---|---|---|---|---|---|---|
| 1 | 狐糯糯Bot | 狐绵绵 | 2971723646 | 3000 | 40 | 平台主 bot(hunono.db 托管) |
| 3 | 二号Bot | 只愿伴你身边 | 3065425710 | 3024 | 44 | NapCat 容器 |
| 4 | 三号Bot | 代梦琳 | 1951957282 | 3028 | 32 | NapCat 容器 |
| 5 | 狐糯糯 | 狐糯糯 | 3833675805 | 3036 | 22 | NapCat 容器(新 bot) |
合计去重群 93 个。
除「机器人→用户」分配外,系统还支持细粒度授权:
POST /api/users/:id/group-permission(仅超管;目标须为普通用户;只能授自己有权限的群)
POST /api/users/:id/function-permission(仅超管;目标须为普通用户)
两类授权均带权限校验,越权返回 403。
3000–3099 段内空闲端口,登录目标 QQ。新 bot 接入时务必检查端口是否冗余:
3833675805 同时登录 3007 与 3036),这是冗余双登录,只需保留 1 个端口。napcat-inst1787750098574),因为它有自动重启、随 docker 自启;3833675805 在机器人本体库 hunono.db 中无记录(它不属于平台托管 bot),因此杀掉原生 3007 不影响任何平台功能,主 bot(端口 3000)完全无影响。# 在 guanjia 后端目录运行,确认自动发现无误删、无重复
node -e "require('./src/utils/bot-sync.js').discoverAndApplyBots({dryRun:false,noRemove:true}).then(r=>console.log('added',r.added,'removed',r.removed))"
# 检查群数
sqlite3 data/hunuanguanjia.db "SELECT COUNT(*) FROM bot_group_relations WHERE bot_qq=3833675805;"
pm2 restart guanjia-backend
pm2 logs guanjia-backend --lines 30 # 查看启动日志,确认 [AutoSync] 正常
# 机器人发现(默认安全:不删除,仅标记离线)
curl -X POST http://127.0.0.1:3456/api/bots/discover # 需鉴权 token
# 仅当确实要清理已死机器人时,才加 forceRemove:true
# { "forceRemove": true }
# 功能同步(按机器人本体库重算 is_active)
curl -X POST http://127.0.0.1:3456/api/bots/sync-functions
已装 pm2-logrotate:max_size=50M / retain=7 / compress,防止磁盘被日志打爆(曾因日志占用导致磁盘 86%)。
noRemove(防误删)3024 端口 token 返回 401 被误判离线,级联删掉 44 个群。noRemove=true,NapCat 短暂重启(端口瞬间关闭)不会误删任何机器人/群,仅标记离线;/discover 默认也安全,必须显式 forceRemove:true 才真删。| 现象 | 原因 / 处理 |
|---|---|
| 机器人加了群却不显示 | 旧 bug 已修;现每次同步重建归属关系。若仍异常,手动 POST /api/bots/discover |
| 功能列表出现没实现的功能 | 桩功能已被 is_active=0 屏蔽;若仍显示,跑 POST /api/bots/sync-functions 重算 |
| 调接口返回 401 | 需带有效登录 token;不是功能故障 |
| 调云端 API 返回 429 | 触发频率限制,稍等重置后再调用,或减少调用次数 |
| 文档/COS 链接下载失败 | 签名链接有时效,过期需重新生成 |
入口:登录后在 /guanjia/manage.html 使用「高级管理」页(自动入群审核 / 邀请码 / 管理层级三个标签页)。
group_add_request 事件 → 后端风控引擎 src/utils/join-audit.js 实时评分。分数 ≥ 拒绝阈值(60) → 自动拒绝;分数 ≤ 同意阈值(-20) 且开启自动同意 → 自动同意;否则转人工(不自动操作,安全)。join_audit_config 支持 全局 / Bot / 群 三级覆盖(群 > Bot > 全局);所有群默认已开启(93 个群 group_functions 均 is_enabled=1)。GET/PUT /api/join-audit/config、/lists 黑白名单、/logs 日志、/stats 统计、POST /api/join-audit/group/:id/toggle 群级开关。join_audit_log。X-Powered-By(防技术栈指纹探测);helmet 安全头已启用。credentials 同源。/api/auth 限流 30 次/15 分钟(防爆破);全局 /api/ 限流 500 次/15 分钟。users.failed_attempts / locked_until)。callBotApi 增加全局最小调用间隔(120ms) + 并发上限(5) + 失败自动重试(2 次),避免突发调用触发 QQ 风控。noRemove 安全同步与心跳检测,4 个机器人实例稳定在线。POST /api/auth/register 必须绑定邮箱 + QQ,账号唯一校验(用户名/QQ/邮箱均不重复)。支持 invite_code 邀请码,用于归建下级。DELETE /api/auth/account 校验密码后释放账号,并级联清理 QQ 绑定、群/功能权限、操作日志、强制登出。users.parent_id + users.path 物化路径实现「超管 → 管理 → 用户」三级。super_admin 可存在多个(当前 2 个)。getUserScope):GET /api/users/new-registrations 超管看全部、管理看自己下级。/users/hierarchy(层级树)、/users/parent(我的上级)、/users/new-registrations(新人列表)。POST /api/invite-codes 生成邀请码(普通用户 / 管理员两种角色,可设次数与有效期);GET 查看自己名下、DELETE 撤销。parent_id 指向邀请人)。| 条款 | 状态 | 说明 |
|---|---|---|
| 8.4 冲突策略 | ✅ | 批量继承支持 replace(覆盖) / merge(合并) / add_only(仅新增,绝不关已有功能) |
| 8.5 安全闸门 | ✅ | 批量继承支持 dry_run 预览;replace 覆盖 ≥11 个群需 confirm:true 二次确认 |
| 9.5 两层分配链 | ✅ | 用户生效权限 = 直接分配 ∪ 可见群已开启功能(两层继承) |
| 9.11 全局功能共享 | ✅ | global_function_config + GET/PUT /api/functions/global 管理 |
| 9.12 冲突裁决 | ✅ | GET /api/users/:id/functions/effective 取最宽(任一来源允许即允许) |
pm2 guanjia-backend 并重启验证;测试产生的白名单/日志/邀请码/临时授权已清理。为某个用户临时开放一个其原本无权访问的群(带有效期、可撤销),到期自动失效,不污染常驻权限。
temp_group_grants(user_id / group_id / granted_by / can_view / can_edit / expires_at / revoked)。/api/groups 可见群 = 常驻 user_group_permissions ∪ 有效临时授权(未撤销且未过期)。临时群带 is_temp_grant=1 与 temp_expires_at 标记。POST /api/temp-grants:超管或管理授权(自动校验目标用户在授权者作用域内、授权者对该群有 can_edit)。GET /api/temp-grants:超管看全部;管理看自己创建或作用域内下级。GET /api/temp-grants/my:当前用户查看自己获得的临时授权。DELETE /api/temp-grants/:id:撤销(仅创建者或超管)。/api/groups 出现目标群(is_temp_grant:1, can_edit:1);撤销后该群从可见列表消失。新增三个独立入口页面,按角色拆分管理视角的独立地址,用户无需挤在一个地址切换:
| 后台 | 地址 | 适用角色 | 可见模块 |
|---|---|---|---|
| 超管后台 | /guanjia/superadmin.html | super_admin | 全部:概览/群聊/成员/入群审核/邀请码/临时授权/管理层级/资料 |
| 管理后台 | /guanjia/admin.html | admin | 概览/群聊/成员(仅下级)/入群审核/邀请码/临时授权/管理层级/资料 |
| 用户后台 | /guanjia/user.html | user | 概览/群聊(含临时授权群)/我的上级/我的临时授权/资料 |
guanjia-console.js + 内联样式,三页面仅通过 window.CONSOLE_ROLE 区分入口;服务端始终以 JWT 角色强制鉴权,页面仅做 UX 分组,无越权风险。gc_token,与移动端 App(token)互不干扰,可同时登录不同角色。管理发展下级:超管/管理在「成员管理 → +添加下级」创建用户,自动归入自己名下(parent_id 指向当前用户),形成上下级树。
本说明书由运维整理,覆盖截至 2026-08-27 的实际运行状态。如后续代码变更,以代码与数据库为准。
实际访问地址说明:管理面板经 nginx 反代,对外入口为https://hunuonuo.fun:8443/(HTTP 站点/guanjia/仍可用,二者指向同一前端)。本期新增的子路径均挂在 8443 站点下。
https://hunuonuo.fun:8443/bind/(或 /bind/nunu/、/bind/nuonuo/,前端按路径自动选定目标大脑)。ws://hunono-bot:8080;诺诺 ws://172.19.0.1:8094)→ 页面轮询展示二维码 → 用手机 QQ 扫码登录 → 登录成功后点「绑定」,系统把该 QQ 写入 bot_instances 并通知系统主人。expire_at = 当前 + 30 天(可在绑定时传 expire_days 覆盖;0 表示永久)。POST /api/bots/scan/start、GET /api/bots/scan/:token/qrcode、GET /api/bots/scan/:token/status、POST /api/bots/scan/:token/bind、POST /api/bots/scan/:token/cancel(均仅超管可调用)。bot_instances.expire_at(Unix 时间戳,0 = 永久)已落地;扫码绑定与 POST /api/bots/:id/expire、extend_days 均可写入。initExpiryCron(),每小时检查一次(源码 src/routes/expiry-cron.js):expire_notified=1(同周期只提醒一次);is_active 置 0(停用),并通知上述对象;expire_notified,便于下次再提醒。bot_instances 管理,定时任务一视同仁。/opt/hunono/monitoring,三个容器:| 组件 | 镜像 | 端口 | 作用 |
|---|---|---|---|
| node_exporter | prom/node-exporter | 9100(host 网络) | 主机 CPU / 内存 / 磁盘 / 网络 |
| prometheus | prom/prometheus | 9090 | 抓取并存储指标,路由前缀 /prometheus |
| grafana | grafana/grafana | 3100→3000 | 可视化面板,子路径 /grafana |
node_exporter(主机)、guanjia-backend(后端 /metrics)——两者均 up。src/routes/metrics.js 暴露 /metrics(Prometheus 文本格式),含 guanjia_up、guanjia_total_requests、guanjia_heap_used_bytes、guanjia_rss_bytes、guanjia_bot_instances、guanjia_bot_online、guanjia_bot_expired。/grafana/ → 127.0.0.1:3100/grafana/、/prometheus/ → 127.0.0.1:9090/prometheus/。guanjia-host),含 CPU/内存/磁盘/网络/后端运行指标。数据源 prometheus 已自动配置。admin / 初始密码已通过邮件单独下发(请按需修改,切勿在公开渠道留存)。https://hunuonuo.fun:8443/grafana/、https://hunuonuo.fun:8443/prometheus/。utils/email.js 支持 qq / kzy / zxz 三个发信账号并自动回退;新增 sendAccountMail / sendCodeMail / sendResetEmail。baishiyu@kzyun.tech(KZY,此前误写为 kzy.tech)现已可发信——A / MX / SPF 已生效,SMTP 鉴权与真实测试邮件均通过(250 Ok: queued)。建议补 DKIM / DMARC 进一步优化外部到达率。POST /api/auth/retrieve-account(按邮箱或 QQ 找回账号)、POST /api/auth/forgot-password(发重置邮件)均已上线并在前端接入。POST /api/bind/send-code-email + POST /api/bind/confirm)。绑定邮箱同样发验证码/链接到邮箱。superadmin(2391947486)、Hunuonuo(108888126)、Humianmian(16672616),密码邮件已发送。bot_status 插件检测到「非好友且非主人」拉自己入群时,自动 set_group_leave 退群,并通知主人:主人,陌生人(3065425710)拉我强行进入「三号云端」群,已自动退群\n时间:2026-08-26 22:57:50
狐糯糯走 notify_masters、诺诺走 notify_owners_and_group,双脑一致;无法判定时保守不误退。
admin_tools 的「踢」指令加 _temp_owner_kick_guard,诺诺在 temp_owner 插件加守卫,双脑均已部署重启验证。bot_status 与 temp_owner 在上线/绑定临时主人时向系统主人推送通知,已上线。本轮目标:在既有 QQ 通知之外,补齐「邮件」这条兜底通道,让掉线 / 到期 / 临时主人三类事件都能同时通知系统主人;并为监控栈补齐报警规则与邮件报警。
src/routes/offline-monitor.js,后端启动后由 initOfflineMonitor() 挂载(见 app.js 442–443 行)。bot_instances,对比 is_online 状态:sendToSuperAdmins);noRemove/心跳逻辑——NapCat 短暂重启或 401 鉴权问题不判掉线,只在确实离线时告警。src/routes/expiry-cron.js 在原有「QQ 私聊预警所有者/创建者/系统主人」之外,新增 sendExpiryMails():expire_notified=1 避免重复,顺延到 3 天外自动重置。POST /api/app/bot/notify-email(位于 src/routes/bot-api.js),botTokenAuth 鉴权(仅 bot 插件持 BOT_ACCESS_TOKEN=huonono-bot-secret 可调用),向 3 位系统主人发邮件。temp_owner 插件:绑定 / 取消临时主人分支在 QQ 通知后,额外调用该接口;rental 插件(hunono-bot 容器内 /app/plugins/rental/__init__.py):绑定 / 取消临时主人时同步调用。huonono-bot-secret;容器内走 172.19.0.1:3456、诺诺宿主走 127.0.0.1:3456。/opt/hunono/monitoring/prometheus/alerts.yml(5 条,已加载评估,组名 host-health):| 规则 | 触发条件 |
|---|---|
HostCpuHigh | 主机 CPU > 80% 持续 2m |
HostMemoryHigh | 主机内存 > 85% 持续 2m |
HostDiskHigh | 主机磁盘 > 85% 持续 2m |
NodeExporterDown | node_exporter 失联 1m |
GuanjiaBackendDown | guanjia 后端 /metrics 失联 1m |
email-owners:收件人 3 位系统主人(2391947486@qq.com;108888126@qq.com;16672616@qq.com),发件 baishiyu@zhangxiaozhu.cn;group_wait 30s / group_interval 5m / repeat_interval 1h;grafana 数据源的 ruler API 有 RBAC 限制,报警规则用 Prometheus 侧 alerts.yml 承载,Grafana 负责可视化 + 邮件通道 + 通知策略)。baishiyu@kzyun.tech(此前误写为 kzy.tech)。kzyun.tech 的 A / MX / SPF 记录已生效,后端 SMTP_USER_KZY 已更正为 baishiyu@kzyun.tech,SMTP 鉴权与一封真实测试邮件均已通过(250 Ok: queued)。kzyun.tech 补 DKIM(qq._domainkey TXT,值从腾讯企业邮后台获取)与 DMARC(_dmarc TXT)记录,可显著提升发往 QQ / 163 / Gmail 等外部邮箱的到达率(避免进垃圾箱);并确认 CNAME 验证记录 qqmail68491757 → mail.qq.com 已落在 kzyun.tech 解析区。