kt-template-online-api/API.md

74 KiB
Raw Blame History

KT Template Online API

本文是当前 API 的人工索引。字段细节、Swagger 示例和 DTO 以运行态 Swagger/Knife4j 为准:

  • 全量 Swagger/api
  • OpenAPI JSON/api-json
  • Admin 分组:/api/admin
  • QQBot 分组:/api/qqbot
  • WordPress 分组:/api/wordpress
  • 基础能力分组:/api/basic

通用约定

后端固定监听 48085。根路径 GET / 重定向到 /api#/

除文件下载、SSE、反向 WebSocket 等特殊接口外,业务接口统一返回:

{
  "code": 200,
  "msg": "操作成功",
  "data": {}
}

错误响应统一把 err 输出为字符串:

{
  "code": 400,
  "msg": "操作失败",
  "err": "错误原因"
}

认证

Admin、Component、Dict、MinIO、Blog 管理、WordPress 管理和 QQBot 管理接口默认需要后台登录态。

支持两种 access token 传递方式:

  • Authorization: Bearer <accessToken>
  • 登录接口写入的 httpOnly admin_access_token cookie

公开接口包括 /auth/login/auth/refresh/auth/logout、部分 Blog public 接口和根路径。具体以 Controller 上的 @Public() 为准。

ID 与时间

  • 后台主键使用 Snowflake 数字 ID接口按字符串返回避免 JavaScript 长整型精度丢失。
  • 后端格式化时间字段统一使用 KtDateTime extends DateEntity 通过 @KtDateTimeColumn(format)@KtCreateDateColumn(format)@KtUpdateDateColumn(format) 在 TypeORM hydrate 边界转换DTO/外部数据源通过 @KtDateTimeField(format) + transformKtDateTimeFields() 转换。默认输出 YYYY-MM-DD HH:mm:ss,可在装饰器中传入格式字符串;响应包装不做递归遍历。
  • POST */save 默认会删除请求体里的 id,防止新增接口误用前端主键。

Runtime Health

方法 路径 认证 说明
GET /health/runtime API 运行时健康和配置检查状态

该接口返回 plain JSON不使用 Vben 响应包装,供本地 smoke、Jenkins/K8s 和 ktWorkflow 观测脚本直接读取。接口位于 Swagger 基础能力分组 /api/basic

顶层字段:

字段 说明
service 固定为 kt-template-online-api
checkedAt ISO 时间字符串
status livereadydegradedblocked
checks 进程和配置检查列表

公开响应不返回数据库、WordPress、Loki、NapCat SSH 等运行拓扑配置快照;配置检查只暴露 key 级别、是否存在和缺失说明。

状态含义:

  • liveNestJS 进程能响应健康请求。
  • ready:关键配置存在,当前检查未发现缺失项。
  • degraded:可选运行时配置缺失,核心 API 可继续工作。
  • blocked:关键运行时配置缺失,不能声明部署或运行态成功。

Admin Environment Dashboard

方法 路径 认证 说明
GET /system/environment/dashboard 返回 local-dev、NAS 线上、腾讯云、r4se 环境快照
POST /system/environment/self-check 触发只读自检并返回最新环境快照
GET /system/environment/events/stream SSE 推送后端环境事件,支持 lastEventId 查询参数

环境总览接口使用 Site -> Node -> Service -> Signal 模型聚合状态,unwired 表示只读观测尚未配置,unknown 表示已知入口但缺少新鲜证据。Admin 首次加载通过 HTTP 获取快照,后续通过 API SSE 接收 local/MQTT 事件;前端不直接连接 MQTT也不使用定时轮询。

当前版本只提供观测和只读自检。重启 Pod、触发 Jenkins 部署、执行迁移、重建 NapCat 容器、启停插件、立即执行插件任务、修改 Caddy/OpenClash/WireGuard/Tencent Cloud 等高风险能力只会以禁用动作展示,后端不提供通用写动作入口。

System 网络管理

方法 路径 认证 说明
GET /system/network/port-forward/list super 分页查询期望、同步、Keeper 与端点租约状态
POST /system/network/port-forward super 新增 TCP/UDP 期望记录
PUT /system/network/port-forward/:id super 修改名称、协议和端口期望
DELETE /system/network/port-forward/:id super 写入 absent tombstone等待 Agent 确认
POST /system/network/port-forward/:id/retry super 提升 revision 并重试协调
POST /system/network/port-forward/:id/keeper/enable super 启用同源端口 UDP Keeper 并立即探测
POST /system/network/port-forward/:id/keeper/disable super 停用 UDP Keeper 并撤下当前端点
POST /system/network/port-forward/:id/probe super 为已启用 Keeper 生成新 probeRequestId
GET /system/network/port-forward/:id/endpoint-history super 查询端点状态变化历史
GET /system/network/agent/status super 查询 Agent 在线与 revision 收敛状态
GET /system/network/events/stream super SSE 推送已提交的 MQTT 状态变化
GET /system/network/ddns/list super 分页查询双栈自动 DDNS 绑定
GET /system/network/ddns/source-options super 查询 A/AAAA 的安全地址来源选项
GET /system/network/ddns/provider-status super 查询腾讯云云解析 DNS 配置状态,不返回凭据
POST /system/network/ddns super 新增本地 DDNS 自动更新绑定
PUT /system/network/ddns/:id super 修改并按需立即协调 DDNS 绑定
DELETE /system/network/ddns/:id super 删除本地绑定,不删除云端 DNS 记录
POST /system/network/ddns/:id/retry super 手动重试一条已启用 DDNS 绑定

新增和修改请求只接受名称、备注、tcp|udp、外部端口和内部端口;目标 NAS IPv4 固定来自 NETWORK_AGENT_TARGET_IPV4,请求体中的未知字段会返回 400。Snowflake ID 与 revision 在 HTTP JSON 中保留为字符串。所有动态响应设置 Cache-Control: no-store

端点历史行使用 portForwardId 关联端口转发,撤下原因返回为 withdrawalReason。Agent 状态同时返回统一的 lastErrorCode/lastErrorMessagereconciliation 优先于 MQTT和细分错误字段便于 Admin 展示与诊断。

API 数据库是唯一事实源。每次合法期望变更在同一事务中锁定 network_agent_state、全局 revision 只增加一次并保存稳定 desiredIssuedAt;事务提交后再发布 kt/network/v1/agents/{agentId}/desired 的 QoS 1 retained 完整快照。PUBACK 只推进 publishedRevisionAgent 的完整 reported 才推进 appliedRevision 和逐条实际状态。MQTT 或 Agent 离线不回滚已接受的期望状态。

Wire contract 采用 kt-network-agent/internal/contract schema-v1desired mapping 使用 state=present|absentreported 使用 appliedRevisiondesiredDigest、helper 状态和逐条 router/route/Keeper 证据endpoint event 使用唯一 eventId。API 不发布数据库备注,也不在 MQTT、HTTP 或数据库中接收/保存路由器密码和 token。事件按 eventId 幂等追加;删除只有在 Agent 明确回报 absent、synced、router/route 均不存在、Keeper 期望关闭且实际 disabled、current endpoint 为空,并且 helper 已确认且 helperAppliedRevision === appliedRevision 后才完成,随后生成新 revision 移除 tombstone。

Admin 首次进入网络管理页通过 HTTP 读取快照,随后使用 /system/network/events/stream 接收 network-state-changed。API 只在 reportedstatusevents 对应事务提交且语义状态实际变化后发出事件MQTT QoS 1 重投、仅推进 lastHeartbeatAt 的状态心跳以及仅推进 currentObservedAt/currentValidUntil/lastObservedAt 的租约续期继续持久化,但不触发刷新。公网 IP/端口、Keeper/同步/错误/删除状态或 Agent 在线会话变化仍发布事件。SSE 心跳只维持连接并复用最近一次真实状态事件 ID尚无状态事件时显式发送空 ID避免 Nest 自动生成游标;浏览器重连通过 Last-Event-IDlastEventId 重放有限窗口,游标失效时收到一次 snapshot-required 并重新读取 HTTP 快照。前端不直接订阅 MQTT也不使用定时轮询。

TCP 记录支持 API CRUD但不提供 STUN/Keeper当前已验证的 Agent 切片尚未启用 TCP 路由器写入,会明确回报 tcp_router_write_gated,不能把 pending/failed TCP 记录描述为已生效转发。UDP 只有 externalPort === internalPort 时可启用 Keeper。当前端点只有在 currentValidUntil 未过期时才返回为可用值;租约过期不会删除最近观测或 network_endpoint_history。API 不直接访问小米路由器、不修改 NAS 路由真实路由器、raw UDP 与回程规则只由固定 NAS Agent/helper 处理。

自动 DDNS 支持 AAAAA。A 记录绑定 sourceType=port_forward_ipv4 与一条合格的同源端口 UDP KeeperAAAA 记录固定使用 sourceType=agent_ipv6,不得携带 portForwardId。来源暂不可用时记录进入 waiting_source,不会向腾讯云写入空地址。协调器只修改腾讯云云解析 DNS 中已存在、已启用、默认线路且唯一的同类型记录,写入时保留 RecordId、线路和 TTL并回读相同 RecordId 验证结果DNS 值不包含端口。删除接口只删除本地自动更新绑定不删除云端记录。Provider 状态接口只返回开关、配置完整性和官方 provider 标识,不返回 SecretId、SecretKey 或 SDK 原始错误。

Agent 状态响应额外包含可选的 currentPublicIpv6/currentIpv6ObservedAt。只有在线且未超过 NETWORK_DDNS_AGENT_IPV6_MAX_AGE_MS 的规范化全局 IPv6 才能作为 AAAA 来源;缺少 IPv6 不影响现有端口转发、UDP Keeper 或 Agent 在线状态。

环境变量分组

分组 关键变量
MySQL DB_HOSTDB_PORTDB_USERNAMEDB_PASSWORDDB_DATABASEDB_SYNC
MinIO MINIO_ENDPOINTMINIO_PORTMINIO_ACCESS_KEYMINIO_SECRET_KEYMINIO_BUCKETBLOG_LIVE2D_ALLOWED_ORIGINSBLOG_LIVE2D_BUCKETBLOG_LIVE2D_ROOT_PREFIXBLOG_LIVE2D_PREFIX
Admin ADMIN_TOKEN_SECRETADMIN_COOKIE_SECURESNOWFLAKE_WORKER_IDSNOWFLAKE_DATACENTER_ID
WordPress WORDPRESS_BASE_URLWORDPRESS_HOST_HEADERWORDPRESS_ADMIN_USERNAMEWORDPRESS_ADMIN_PASSWORD
Loki LOG_LEVELLOG_APP_NAMELOKI_URLLOKI_QUERY_HOSTLOKI_QUERY_SELECTOR
QQBot QQBOT_ENABLEDQQBOT_ACCOUNT_SECRET_KEYQQBOT_REVERSE_WS_PATHQQBOT_REVERSE_WS_TOKENQQBOT_EVENT_BUSQQBOT_SEND_*QQBOT_PLUGIN_QUEUE_REDIS_*QQBOT_PLUGIN_TASK_QUEUE_REDIS_*QQBOT_PLUGIN_QUEUE_WAIT_TIMEOUT_MSQQBOT_COMMAND_MIN_COOLDOWN_MSQQBOT_RULE_MIN_COOLDOWN_MSQQBOT_REPEATER_*
NapCat NAPCAT_WEBUI_BASE_URLNAPCAT_WEBUI_TOKENQQBOT_NAPCAT_*
MQTT MQTT_URLMQTT_USERNAMEMQTT_PASSWORDMQTT_CLIENT_ID
Env Dashboard ENV_DASHBOARD_CACHE_TTL_MSENV_DASHBOARD_SIGNAL_TIMEOUT_MSENV_DASHBOARD_EVENT_BUSENV_DASHBOARD_MQTT_*ENV_DASHBOARD_SSE_*ENV_DASHBOARD_JENKINS_*ENV_DASHBOARD_K8S_*ENV_DASHBOARD_TENCENT_*ENV_DASHBOARD_CADDY_*ENV_DASHBOARD_R4SE_*
Network NETWORK_AGENT_IDNETWORK_AGENT_TARGET_IPV4NETWORK_AGENT_MQTT_URLNETWORK_AGENT_MQTT_CLIENT_IDNETWORK_AGENT_MQTT_USERNAMENETWORK_AGENT_MQTT_PASSWORDNETWORK_AGENT_MQTT_RETRY_MSNETWORK_MANAGEMENT_SSE_HEARTBEAT_MSNETWORK_MANAGEMENT_SSE_REPLAY_LIMITNETWORK_DDNS_DNSPOD_ENABLEDNETWORK_DDNS_DNSPOD_SECRET_IDNETWORK_DDNS_DNSPOD_SECRET_KEYNETWORK_DDNS_RECONCILE_INTERVAL_MSNETWORK_DDNS_AGENT_IPV6_MAX_AGE_MS
BangDream BANGDREAM_TSUGU_MAIN_SERVERBANGDREAM_TSUGU_DISPLAYED_SERVERSBANGDREAM_TSUGU_CACHE_ROOT
FF14 Market FF14_XIVAPI_BASE_URLFF14_UNIVERSALIS_BASE_URLFF14_DEFAULT_WORLD
FFLogs FFLOGS_GRAPHQL_URLFFLOGS_TOKEN_URLFFLOGS_CLIENT_IDFFLOGS_CLIENT_SECRET

真实密码、Token、OAuth secret 和生产 env 不提交到 Git。

Env Dashboard 的 ENV_DASHBOARD_ADMIN_LOCAL_URL / ENV_DASHBOARD_ADMIN_PUBLIC_URL 只作为 Admin 入口展示证据Jenkins、K8s、Tencent Cloud、Caddy、WireGuard、Mihomo/OpenClash 仍通过对应 ENV_DASHBOARD_* 只读配置接入,缺失配置必须返回 unwired 证据。

QQBot 插件 worker 队列依赖 Redis。K8s 生产清单提供内部 Redis Service kt-qqbot-plugin-redis:6379,用于 QQBOT_PLUGIN_QUEUE_REDIS_HOST / QQBOT_PLUGIN_QUEUE_REDIS_PORTQQBOT_PLUGIN_QUEUE_WAIT_TIMEOUT_MS 控制串行队列的排队等待窗口,避免排队时间挤占插件操作本身的 timeoutMs 执行预算。插件定时任务可通过 QQBOT_PLUGIN_TASK_QUEUE_REDIS_* 使用独立 BullMQ prefix未配置 host 时复用插件 worker Redis 连接。

Admin 与基础后台

Auth / User

方法 路径 说明
POST /auth/login 后台登录,返回 accessToken、用户信息和 WordPress 自动登录状态,并写入 httpOnly cookie
POST /auth/refresh 通过 refresh token cookie 刷新 accessToken
POST /auth/logout 清理 Admin 与 WordPress 登录 cookie
GET /auth/codes 获取当前用户按钮权限码
GET /user/info 获取当前用户信息

/auth/login 会尝试用 env 中的 WordPress 管理员账号建立 WordPress 登录态。WordPress 不可用时Admin 主登录仍成功,返回 wordpressAuth=nullwordpressAvailable=false,菜单和权限码会过滤 Blog 管理入口。

Menu / Role / Dept / User Manage

方法 路径 说明
GET /menu/all 当前用户菜单
GET /system/menu/list 系统菜单树
GET /system/menu/name-exists 菜单 name 重名校验
GET /system/menu/path-exists 菜单 path 重名校验
POST /system/menu 新增菜单
PUT /system/menu/:id 更新菜单
DELETE /system/menu/:id 删除菜单及子菜单
GET /system/role/list 角色分页
POST /system/role 新增角色
PUT /system/role/:id 更新角色
DELETE /system/role/:id 删除角色
GET /system/dept/list 部门树
POST /system/dept 新增部门
PUT /system/dept/:id 更新部门
DELETE /system/dept/:id 删除部门
GET /system/user/list 用户分页
POST /system/user 新增用户
PUT /system/user/:id 更新用户
DELETE /system/user/:id 删除用户

系统菜单实体包含 sort 字段;菜单树输出按 meta.order 优先,其次按 sort 升序排列。Admin 菜单管理页面维护 sort,不要把普通菜单排序写进隐藏的 route meta。

Dict

方法 路径 说明
GET /dict/list 字典项分页,支持 dictCodekeywordlabelvaluechildrenCodestatus
GET /dict/tree 兼容树形字典视图
GET /dict/groups 字典编码分组列表,适合左右表左侧分组
GET /dict/codes 字典编码选项
GET /dict/getDictByKey dictKey 获取启用字典项
GET /dict/getComponentDictByType 按组件一级类型查二级类型
POST /dict/save 新增字典项
POST /dict/update 更新字典项
DELETE /dict/:id 物理删除字典项
POST /dict/toggle 启停字典项

字典核心字段:

字段 说明
dictCode 字典分组,例如 COMPONENT_TYPEBANGDREAM_SERVER_ALIAS
label 展示文本
value 字典值
childrenCode 关联子分组编码
sort 排序
status 1 启用

Component

组件接口保持 /component/* 路径兼容,但数据表为 admin_component

方法 路径 说明
GET /component/allList 全量组件
GET /component/list 组件分页,支持 pageNopageSizenametypecomponentType
GET /component/detail?id= 组件详情
POST /component/save 新增组件
POST /component/update 更新组件
POST /component/remove?id= 逻辑删除组件

Timezone / Upload / Demo

方法 路径 说明
GET /timezone/getTimezoneOptions 时区选项
GET /timezone/getTimezone 当前用户时区
POST /timezone/setTimezone 设置当前用户时区
POST /upload Vben 上传适配,实际写入 MinIO
GET /table/list Vben 示例表格
GET /status 状态码测试
GET /demo/bigint BigInt JSON 测试
GET /test GET 测试
POST /test POST 测试

系统日志

后端通过 nestjs-pino 输出结构化日志。配置 Loki 后Admin 日志页面通过后端代理查询,不直连 Loki。

方法 路径 说明
GET /system/logs 日志分页,支持 levelkeywordcontextpathrequestIdstartTimeendTimerangeMinutes
GET /system/logs/summary 按级别统计
GET /system/logs/levels 日志级别选项
GET /system/logs/status Loki 查询配置状态

日志行包含 timestamplevelmessagemethodpathstatusCodedurationMsrequestIdraw 等字段。

系统站内信

站内信用于承接运行期事件,不再作为人工公告入口。后端在接口 5xx、QQBot OneBot 下线 notice、NapCat 容器日志检测到账户离线时自动生成或聚合一条通知,默认通知 super 角色;站内信接口在服务端也强制 super 角色访问。相同 dedupeKey 的事件通过 active_dedupe_key 唯一索引聚合,会累加 occurrenceCount,刷新 lastSeenAt,并把状态重新置为未处理。运行期通知会按表字段长度归一化 titlededupeKeysourceeventTypenotifyRoleCode,长 dedupeKey 会保留稳定 hash 后缀,避免长路径接口错误丢通知。

方法 路径 说明
GET /system/notice/list 日志级站内信分页列表,支持 keywordseveritysourceeventTypestatusisTopnotifyRoleCodenotifyUserspageNopageSize
GET /system/notice/detail/:id 查询站内信详情
DELETE /system/notice/:id 删除站内信(逻辑删除)
POST /system/notice/toggle 标记处理或重新打开(idstatus1 未处理,0 已处理)
POST /system/notice/top 切换置顶(idisTop

返回字段包含 severitysourceeventTypededupeKeyoccurrenceCountnotifyRoleCodemetadatafirstSeenAtlastSeenAt。后端不暴露人工 save/update 入口。

Blog 本地内容

/blog/* 是本地博客内容能力,供 Vue/kt-blog-web 和 Admin 博客管理使用。

Blog Article

方法 路径 说明
GET /blog/article/public/list 公开文章分页
GET /blog/article/public/detail 公开文章详情,支持 id/slug
GET /blog/article/list 后台文章分页
GET /blog/article/detail 后台文章详情
POST /blog/article/save 新增文章
POST /blog/article/update 更新文章
POST /blog/article/remove 删除文章
GET /blog/article/category-options 文章分类选项
GET /blog/article/tag-options 文章标签选项
POST /blog/article/import-wordpress 从 WordPress 导入文章

文章 body 常用字段:

{
  "title": "文章标题",
  "slug": "post-slug",
  "status": "publish",
  "content": "Markdown 或 HTML",
  "contentFormat": "markdown",
  "cover": "",
  "categories": ["tech"],
  "tags": ["kt"]
}

Blog Category / Tag / Theme

方法 路径 说明
GET /blog/category/list 本地分类分页
GET /blog/category/detail 本地分类详情
POST /blog/category/save 新增分类
POST /blog/category/update 更新分类
POST /blog/category/remove 删除分类
GET /blog/tag/list 本地标签分页
GET /blog/tag/detail 本地标签详情
POST /blog/tag/save 新增标签
POST /blog/tag/update 更新标签
POST /blog/tag/remove 删除标签
GET /blog/term/options 分类/标签选项
GET /blog/theme/config 获取 Argon 主题配置
POST /blog/theme/save 保存本地主题配置
POST /blog/theme/import-wordpress 从 WordPress 导入主题配置

WordPress 代理

/wordpress/* 需要 Admin 登录态和 WordPress 登录态。后端优先使用 kt_wordpress_auth httpOnly cookie也支持显式透传 WordPress 认证 header。

方法 路径 说明
POST /wordpress/auth/login 使用 env 管理员账号登录 WordPress 并写入 cookie
POST /wordpress/auth/logout 清理 WordPress cookie
GET /wordpress/auth/check 校验 WordPress 登录态
GET /wordpress/theme/config 读取 WordPress Argon 主题配置

WordPress Article / Tag / Category

方法 路径 说明
GET /wordpress/article/public/list 公开文章列表代理
GET /wordpress/article/public/detail 公开文章详情代理
GET /wordpress/article/list WordPress 文章分页
GET /wordpress/article/detail WordPress 文章详情
POST /wordpress/article/save 新增 WordPress 文章
POST /wordpress/article/update 更新 WordPress 文章
POST /wordpress/article/remove 删除 WordPress 文章
GET /wordpress/tag/list 标签分页
GET /wordpress/tag/detail 标签详情
POST /wordpress/tag/save 新增标签
POST /wordpress/tag/update 更新标签
POST /wordpress/tag/remove 删除标签
GET /wordpress/category/list 分类分页
GET /wordpress/category/detail 分类详情
POST /wordpress/category/save 新增分类
POST /wordpress/category/update 更新分类
POST /wordpress/category/remove 删除分类

WordPress rewrite 未开启导致 /wp-json/* 返回 404 时,后端会回退到 ?rest_route=/...

MinIO

方法 路径 说明
GET /minio/check 检查连接和 bucket
POST /minio/bucket 创建 bucket
POST /minio/upload 上传文件,multipart/form-data
GET /minio/list 文件列表
GET /minio/url 临时访问 URL
GET /minio/resource-proxy 代理读取资源
GET /minio/download 下载文件流
DELETE /minio/remove 删除文件
GET /blog/live2d/:character/catalog.json 公开读取 Pio/Tia Live2D 公共目录索引,按 Referer/Origin 白名单防盗链
GET /blog/live2d/:character/:family/*assetPath 公开读取 Pio/Tia Live2D 运行包资源,character 只允许 pio/tiafamily 只允许 moc/moc3,按 Referer/Origin 白名单防盗链

bucketName 不传时使用 MINIO_BUCKET

Blog Live2D 运行包读取入口不使用 Vben 响应包装,直接返回 MinIO 文件流。根 catalog.json 暴露当前角色 family、目录规范和动作/贴图计数asset 路由只读取 moc/moc3/ 下的 index.jsonmanifest.json、runtime、model、motion、shader 和 source texture 文件。BLOG_LIVE2D_ALLOWED_ORIGINS 配置允许的 Blog 源,例如 https://blog.kwitsukasa.top,http://localhost:5999BLOG_LIVE2D_BUCKET 决定 bucketBLOG_LIVE2D_ROOT_PREFIX 决定角色根目录(默认 blog/live2d),旧 BLOG_LIVE2D_PREFIX=blog/live2d/pio 会自动派生到同一根前缀以兼容现有环境。路由支持嵌套资源路径,如 textures/default-costume.pngassets/model/motions/breath1.motion3.json,并拒绝绝对 URL、反斜杠、./..、多重编码后的路径逃逸、未知角色和 v1/v2 这类自定义版本 family。

QQBot 管理

QQBot 运行态包括 NapCat 容器登录、OneBot v11 反向 WebSocket、MQTT 事件总线、账号能力绑定、在线命令、自动回复规则、权限名单、发送/接收日志和插件生态。

Account / Scan Login

方法 路径 说明
GET /qqbot/account/list QQBot 账号分页
GET /qqbot/account/enabled 启用账号列表
POST /qqbot/account/save 手动新增账号
POST /qqbot/account/update 更新账号
POST /qqbot/account/scan/create 扫码新增账号,创建登录会话
POST /qqbot/account/scan/refresh?id= 对已有账号刷新登录态
GET /qqbot/account/scan/status?sessionId= 查询扫码会话状态
GET /qqbot/account/scan/events?sessionId= SSE 订阅扫码进度
POST /qqbot/account/scan/qrcode/refresh?sessionId= 刷新当前会话二维码
POST /qqbot/account/scan/captcha/submit 提交密码登录安全验证码结果
POST /qqbot/account/scan/cancel?sessionId= 取消扫码会话
POST /qqbot/account/delete?id= 删除账号并断开 WS
POST /qqbot/account/kick?selfId= 断开反向 WS 会话
GET /qqbot/napcat/runtime/detail?accountId= 读取账号 NapCat 运行态证据
POST /qqbot/account/bind/command 绑定账号和在线命令
POST /qqbot/account/unbind/command 解绑账号和在线命令
POST /qqbot/account/bind/rule 绑定账号和自动回复规则
POST /qqbot/account/unbind/rule 解绑账号和自动回复规则

账号保存支持可选 encryptedLoginPassword,用于 NapCat 密码登录。前端必须先通过 /auth/password-public-key 获取公钥并使用 RSA-OAEP 加密,不传明文 loginPassword;后端必须使用显式配置的 QQBOT_ACCOUNT_SECRET_KEY(或非默认 ADMIN_TOKEN_SECRET)二次加密落库,空值和公开默认值会被拒绝,不在列表/详情中返回。账号列表里的 connectStatus 只表示 OneBot 反向 WSnapcat.oneBotOnlinenapcat.containerOnlinenapcat.webuiOnlinenapcat.qqLoginStatusnapcat.qqLoginMessage 分别表示 OneBot、容器、WebUI 和 QQ 登录态,webuiOnline=null 表示本次使用缓存且未重新探测 WebUIqqLoginMessage 只承载真实 QQ 登录态消息WebUI 配置缺失或请求异常只放在 lastError

扫码链路返回 sessionId,前端应使用 SSE 查看步骤进度,而不是等待长 HTTP 请求完成;新增账号扫码会先预留容器和临时设备身份后立即返回 pending会话后台再启动远端 Docker 和生成二维码。CheckLoginStatus.isLogin=true 只表示 NapCat 登录阳性,新增账号必须继续等 GetQQLoginInfo 返回 uin/selfId 后才允许创建和绑定真实 QQ 号;短暂缺号时 /qqbot/account/scan/status 保持同一会话 pending 并显示正在读取 QQ 号,等待 NAPCAT_LOGIN_SELF_ID_WAIT_MS,不得重建容器、补 env 或从容器元数据猜号。已有账号的更新登录不会通过 Docker 重建、重启或补 env 来刷新 QQ 登录态;如果目标容器仍在线,即使 QQ 账号已离线,也会保持同一容器并通过 NapCat WebUI 推进原有弹窗流程。若 WebUI 明确返回 QQ 离线API 会先调用同容器 /api/QQLogin/RestartNapCat 重启 NapCat worker 以重建 QQCore login service再继续 SetQuickLoginPasswordLoginRefreshQRcode / GetQQLoginQrcode;这不是 Docker 容器重建/重启设备身份、env 和 dataDir 不变,同一个更新登录 session 只消费一次 worker restart 预算,后续轮询继续刷新二维码但不得反复重启 worker。只有 Docker 容器离线或缺失时,容器准备阶段才会创建/重建容器,并在创建时一次性注入 ACCOUNT 和必要登录 env已在线的源容器不补 env。快速登录失败后如果账号保存了登录密码后端使用解密后的密码计算 MD5 调用 /api/QQLogin/PasswordLogin,不会把密码写回运行态 env也没有成功后的 env 清理步骤;密码登录结果按 QQBOT_NAPCAT_PASSWORD_LOGIN_WAIT_MS / QQBOT_NAPCAT_LOGIN_POLL_INTERVAL_MS 轮询。准备阶段的扫码会话会持续续期,避免后台登录未完成时前端先判过期。同一账号已有 pending 更新登录会话时,重复调用 /qqbot/account/scan/refresh 通常会返回原 sessionId,不会再次启动 quick/password/二维码准备;但当这条 pending 会话创建时账号还没有保存登录密码、且会话尚未进入密码验证码或新设备验证上下文而账号后来通过编辑维护了登录密码时API 必须退役旧无密码会话并新建 refresh session重新读取最新密码后进入 PasswordLogin。取消扫码会话必须在接口返回前把持久化 napcat_login_session 落到非 pending 终态并写入完成时间,避免已取消的测试二维码从 DB 恢复成可轮询会话。若 API Pod 在准备阶段重启,持久化的 preparingRelogin 超过 QQBOT_NAPCAT_RELOGIN_PREPARING_STALE_MS(留空使用密码等待窗口加缓冲)后,/qqbot/account/scan/status 会自动恢复普通登录态检测,不再永久停留在“正在尝试密码登录”;/qqbot/account/scan/events 在进程内事件缓存丢失时会先推送当前会话快照。pending refresh 会话如果没有二维码、验证码或新设备挑战,/qqbot/account/scan/status 会按 NAPCAT_LOGIN_QR_AUTO_REFRESH_COOLDOWN_MS 冷却在同一容器自动重试 RefreshQRcode/GetQQLoginQrcode,避免 SSE 长时间卡在“二维码生成中”。密码登录触发 QQ 安全验证时,接口返回的 captchaUrl 只用于前端拉起腾讯验证码;前端必须把腾讯验证码返回的 ticketrandstrsid 连同 sessionId 提交到 /qqbot/account/scan/captcha/submit,后端再代理到同一 NapCat 容器的 /api/QQLogin/CaptchaLogin 继续密码登录第二步。验证码和新设备验证这类真人交互态使用 NAPCAT_LOGIN_HUMAN_VERIFY_EXPIRE_MS(默认 15 分钟,且至少不短于普通二维码 TTL续期普通登录二维码仍使用 NAPCAT_LOGIN_QR_EXPIRE_MS/qqbot/account/scan/status 遇到 NapCat 只返回“需要验证码/继续完成验证/安全验证”但不带 URL 时,会先从当前容器日志提取 proofWaterUrl,提取不到则保持验证码处理中而不切到二维码兜底;会话已有 captchaUrl 后,同类状态仍保持 pending 和原 captchaUrl。密码登录仍失败、验证码未完成、离线、账号不匹配或缺少 QQ 号时,直接通过 WebUI 二维码接口进入扫码兜底,不 reset 登录态。看门狗只做离线巡检、账号错误写入和 super 站内信告警,不会触发 quick/password 登录或扫码登录。

密码验证码通过后如果 NapCat 返回 needNewDevice,后端不会只把 jumpUrl 透给 Admin而是在同一会话中继续调用 /api/QQLogin/GetNewDeviceQRCode 生成新设备验证二维码;/qqbot/account/scan/status 后续轮询会代理 /api/QQLogin/PollNewDeviceQR,状态映射为 newDeviceStatus=qr-pending|scanned|confirming|verified|expired|failed,进入确认态后再调用 /api/QQLogin/NewDeviceLogin 并回到密码登录完成检查。扫码会话结果新增 newDeviceQrcodenewDeviceStatusdeviceVerifyUrl 字段;captchaUrlnewDeviceQrcode 分别表示腾讯安全验证码和 QQ 新设备验证二维码前端必须分开展示。SSE 进度文案包含快速登录、密码登录、验证码、新设备二维码、已扫码、确认中、二维码兜底、登录成功/失败。

同一 QQ 账号只保留一个有效 NapCat 主容器。扫码后如果已有账号绑定到新容器后端会释放旧绑定和未共享的旧容器避免同账号多实例互相挤下线。OneBot notice 只有机器人下线、登录失效、KickedOffLine 等账号级信号才会记录 QQ 登录态异常并生成 qqbot.account.offline 站内信,普通群成员 kick 不属于账号离线信号。下线原因写入 lastError 前按 last_error 500 字符列宽截断;后续无错误的普通断连只更新 OneBot 连接状态,不清空该原因。账号列表会按近期缓存检查绑定 NapCat 容器的最新登录状态日志,日志检测默认 5 秒超时;isOnline:false 属于 QQ 登录态离线信号;心跳只代表 OneBot/容器通信,不能推导 QQ 登录态;近期连接只用于避免重连瞬间被旧缓存误伤,后续仍必须以 NapCat WebUI/日志检查判断 QQ 登录态。托管容器必须显式配置 QQBOT_NAPCAT_IMAGE,不要依赖 latest 默认镜像。

托管 NapCat 容器按账号持久化设备身份,napcat_device_identity 保存账号对应的数据目录、hostname、machine-id 路径、MAC 地址、验证状态和最近登录证据。重建同一账号容器时会复用 pc-<8hex> hostname、实体 OUI 风格 MAC 和 machine-id并明确排除 Docker 02:42、QEMU/KVM 52:54:00、VMware、Hyper-V 等虚拟化前缀;新增账号创建期在真实 QQ selfId 未知时使用预留容器 id 创建临时设备身份,第一次 Docker run 就注入完整拟真参数,扫码成功后再把该身份和 runtime/protocol profile 归属到真实账号。Docker run 会注入 --hostname--mac-address、只读 /etc/machine-id 挂载、SYS_ADMINapparmor=unconfinedseccomp=unconfinedNAPCAT_REQUIRE_DEVICE_PROFILE=1;后端还会同步写入 QQNT Linux machine-info,让 QQNT 计算 GUID 时使用的 MAC 与 Docker 网卡一致。派生镜像 entrypoint 会用同一设备 profile 覆盖 QQCore 实际打开的 DMI、boot_id、kernel release/version/proc version、CPU model、uptime、TTY active、mountinfo、/etc/hosts/proc/devices 等探针NapCat fork native login 和 core session config 的 machineIdsystemVersion 也从该 profile 读取,避免 QQ native 入参和 Docker 可见探针不一致。当前策略名为 qqnt-visible-hostname-v1 / physical-oui-mac-v1,绑定关系会回填 napcat_account_binding.device_identity_id

System Message Push

所有接口先通过 Admin JWT再按路由声明的权限码执行 OR 校验;只有启用且未删除的角色/菜单生效,启用且未删除的 super 可放行。下表中 / 分隔的权限表示任一项即可,写接口始终只接受该动作自己的权限。

方法 路径 权限
GET /qqbot/message-push/sources Subscription List/Create/UpdateTemplate List/Create/Update/PreviewAccount MessagePush List/Create/Update
GET /qqbot/message-push/sources/:sourceKey 同 source list
GET /qqbot/message-push/sources/network.stun.mapping-port-changed/options Subscription Create/UpdateAccount MessagePush Create/Update
GET /qqbot/message-push/subscriptions Subscription ListAccount MessagePush List/Create/Update
POST /qqbot/message-push/subscriptions Subscription Create
PUT /qqbot/message-push/subscriptions/:id Subscription Update
PUT /qqbot/message-push/subscriptions/:id/enabled Subscription Toggle
DELETE /qqbot/message-push/subscriptions/:id Subscription Delete
GET /qqbot/message-push/templates Template ListAccount MessagePush List/Create/Update
POST /qqbot/message-push/templates Template Create
PUT /qqbot/message-push/templates/:id Template Update
PUT /qqbot/message-push/templates/:id/enabled Template Toggle
DELETE /qqbot/message-push/templates/:id Template Delete
POST /qqbot/message-push/templates/preview Template Preview
GET /qqbot/accounts/:selfId/message-push/bindings Account MessagePush List
POST /qqbot/accounts/:selfId/message-push/bindings Account MessagePush Create
PUT /qqbot/accounts/:selfId/message-push/bindings/:id Account MessagePush Update
PUT /qqbot/accounts/:selfId/message-push/bindings/:id/enabled Account MessagePush Toggle
DELETE /qqbot/accounts/:selfId/message-push/bindings/:id Account MessagePush Delete
GET /qqbot/accounts/:selfId/message-push/targets Account MessagePush Create/Update

完整权限码前缀分别为 QqBot:MessageSubscription:*QqBot:MessageTemplate:*QqBot:Account:MessagePush:*。订阅与模板列表返回 data.items/data.totalsource 与 binding 列表直接返回数组,其余接口返回单个对象或布尔值;全部 POST 使用 HTTP 200。账号离线或 OneBot 不可用时 targets 仍返回 HTTP 200 和 { available: false, options: [], reasonCode }

请求采用严格白名单Snowflake/外键 ID 是 124 位正十进制字符串,selfId 和 QQ 目标 ID 必须匹配 ^[1-9]\d{4,19}$,禁止 number 转换。订阅 name 为 1100 字符且不能全空白,sourceConfig 必须且仅含字符串 portForwardId/ddnsRecordId;模板 name 同限,content 最多 2,000 Unicode 字符;remark 最多 500 字符。Binding 必须含 1100 个严格嵌套 target类型仅 group/privatetargetName 最多 120 字符。Body、query、path 及嵌套对象的未知字段都会拒绝query boolean 只接受字面量 true/false

管理边界将 SystemMessageContractError 仅转换为 Vben 安全错误,响应只包含其稳定 code,不会暴露原始消息、实体或 provider 对象:unknown_message_sourcemapping_not_foundddns_not_found 返回 HTTP 404重复、禁用、不可用、已取代、映射不匹配、DDNS 未同步、错误协议/管理状态及 OneBot 可用性或拒绝状态返回 HTTP 409其余来源、目标、模板、长度和契约校验错误返回 HTTP 400。非该领域错误维持 HTTP 500且不返回其内部细节。

响应仅返回管理契约字段source definition/field/variable 白名单STUN 的 port-forward/DDNS 候选白名单subscription、template、preview、binding/target 和 target option 视图。不会返回 adapter、entity/repository、activeKey、digest、软删除字段、账号内部 ID、事件 payload/delivery/lease/retry 状态、凭据、access token、Provider/OneBot/MQTT 原始对象。系统事件只能通过 Nest 内部 Outbox stager 暂存,不存在 publish、event、delivery、fan-out、retry 或 worker HTTP 发布接口。

NapCat Runtime Profile

方法 路径 说明
GET /qqbot/napcat/runtime/detail?accountId= 读取账号 NapCat runtime/protocol/session behavior profile、风险降载和历史登录事件兼容表状态

该接口只返回脱敏后的运行态证据,供 Admin 排查镜像、locale、shm、配置 hash、漂移状态、风险模式和 watchdog 巡检告警状态;不会返回 WebUI token、reverse WS token、QQ 登录密码、SSH 私钥或运行态密码环境。账号列表只挂载 napcat.profileStatusnapcat.runtimeProfile 等摘要字段不触发登录、重建或修复动作。watchdog 不执行登录恢复:遇到 QQ 登录态离线只记录离线原因并通知 super,登录恢复统一由 Admin 手动「更新登录」触发session behavior profile 只做冷启动、housekeeping、presence 和自动能力分阶段降载,不实现账号级每小时/每日累计发送预算。

NapCat Chinese Desktop Runtime 使用 KT NapCatQQ fork 源码构建出的 NapCat.Shell artifact并在 QQ KickedOffLine 后重置 native login service 再请求二维码;同一次踢下线事件只消费一次 reset明确二维码过期或扫码确认窗口失效的 QR session failure 会自动换码,其他非自动重试 QR failure 会标记下次 WebUI 登录动作先重置 native login service。v14 起运行时会为 QQ/NapCat/Xvfb 长期进程做 PID 级 /proc/<pid>/mountinfo 遮蔽,避免 QQCore 通过 /proc/self/mountinfo 看到 overlay/vol1/dockerdocker-init/docker/containersnapcat-instancesbtrfs/dev/mapper/trim 等宿主路径v15 在扫码登录成功回调中先写入 QQLoginInfo 再写登录态,避免 API 读到 isLogin=true 但 QQ 号为空的短暂不一致v16 在 native reset 缺少 offline() 时改用 destroy() 硬重置半登录服务,并让镜像 verify 等待 mountinfo guard 收敛v17/v18 增加 WebUI 鉴权的 /api/Debug/RuntimeViewProbe 同进程诊断并修正 native maps 截断导致的 hook 证据假阴性v19 保留 WebUI RestartNapCat 重启 worker 时的 -q <uin> 快速登录参数避免重启后退回无账号扫码v20 保护 API 预写的 /app/napcat/config,避免上游首次解包 NapCat.Shell/* 覆盖 bypass.*=trueo3HookMode=0。构建前必须运行 scripts/napcat-desktop-cn-stage-build.mjs 生成 Docker build context生产 QQBOT_NAPCAT_IMAGE 应指向验证过的 kt-napcat-desktop-cn:* digest。生产 K8s manifest 保留 kt-napcat-desktop-cn:desktop-cn-v20 / desktop-cn-v20 稳定默认值Jenkins QQBOT_NAPCAT_IMAGE_OVERRIDEQQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE 只有非空时才覆盖 API Deployment env空值会保持 manifest/default env。运行时回滚应重新运行 Jenkins 并填入上一版镜像 digest/profile或清空两个 override 后重新部署回 manifest 默认值。

API 仓库不提交 NapCat.Shell.zip;生产镜像必须从 staged context 构建,且 fork-artifact.json 必须包含完整 marker metadataupstream release tag/commit、fork commit、base image digest、Jenkins URL 和 artifact hashes。NapCat base image 在 release evidence 中必须 pin 到 digest。API Jenkins 只做显式参数推广,不负责自动合并上游、自动构建运行时镜像或在 override 为空时隐式改写 NapCat env。

node scripts/napcat-desktop-cn-stage-build.mjs \
  --napcat-root /home/yemu2/KT/GitHub/NapCatQQ \
  --upstream-release-tag v4.8.0 \
  --upstream-release-commit 0000000000000000000000000000000000000000 \
  --napcat-base-image-digest mlikiowa/napcat-docker@sha256:0000000000000000000000000000000000000000000000000000000000000000 \
  --jenkins-build-url https://jenkins.kwitsukasa.top/job/KT-NapCatQQ-Runtime-Release/1/

NapCat WebUI Gateway

NapCat WebUI Gateway 是独立部署的内部代理服务,生产镜像由 dockerfile.gateway 打包 dist/apps/napcat-webui-gateway/main.jsK8s 服务名为 kt-napcat-webui-gateway,端口 48086。API 侧只通过内部路由 NAPCAT_WEBUI_GATEWAY_INTERNAL_BASE_URL 创建、续期、撤销会话和交换一次性 ticket浏览器只访问公开前缀 NAPCAT_WEBUI_GATEWAY_PUBLIC_BASE_URL 下的代理页面、静态资源和 WebSocket 转发,不能直连 NapCat 容器 WebUI。

Gateway 只改写 NapCat HTML/JS/CSS 中需要浏览器直连的绝对根路径:/webui/*/api/*/files/*/plugin/*。NapCat 文件管理的 File 路由属于 axios baseURL="/api" 下的 API 子路径,页面源码里的 "/File/list" 必须保持原样,由浏览器最终请求 /api/File/list;不能把 /File/* 当作独立静态根路径改写到 Gateway session 前缀,否则会形成 /webui/api/napcat-webui/session/.../File/list 并让文件管理拿到 HTML。

必需环境变量:NAPCAT_WEBUI_GATEWAY_INTERNAL_BASE_URLNAPCAT_WEBUI_GATEWAY_PUBLIC_BASE_URLNAPCAT_WEBUI_GATEWAY_INTERNAL_SECRETNAPCAT_WEBUI_GATEWAY_REDIS_HOSTNAPCAT_WEBUI_GATEWAY_REDIS_PORTNAPCAT_WEBUI_GATEWAY_SESSION_TTL_MSNAPCAT_WEBUI_GATEWAY_TICKET_TTL_MSNAPCAT_WEBUI_GATEWAY_UPSTREAM_TIMEOUT_MS。生产 NAPCAT_WEBUI_GATEWAY_INTERNAL_SECRET 只来自 Jenkins 私有 .env.production 生成的 kt-template-online-api-env Secret不写入 Git 或 manifest 字面量。

部署验收使用:pnpm exec jest --runTestsByPath test/modules/qqbot/napcat-webui-gateway/gateway-deployment.spec.ts --runInBandpnpm run typecheckpnpm run buildtest -f dist/apps/napcat-webui-gateway/main.jsgit diff --check。安全验收要求浏览器永远不接收 WebUI token、Credential、上游 URL/端口、Docker 拓扑、Redis 地址或内部 secret。

napcat_login_event 实体和表仅作为历史 schema 兼容保留watchdog 不再写入 quick/password 恢复事件,也不再依赖该表判断是否恢复登录。

外发消息不直接抢发:后端会按 QQBOT_SEND_GLOBAL_INTERVAL_MSQQBOT_SEND_TARGET_INTERVAL_MSQQBOT_SEND_JITTER_MS 预约发送窗口,默认全局 2500ms、同会话 8000ms、抖动 0-800ms如果等待超过 QQBOT_SEND_MAX_QUEUE_WAIT_MS,本次发送会在下发前被拒绝。在线命令和自动回复规则会叠加运行时保底冷却,默认命令 5000ms、规则 30000ms复读机默认连续 4 次相同普通文本才触发,同一会话默认 10 分钟内只复读一次,并限制普通文本长度,减少自动行为被风控识别的概率。

Command / Rule / Permission

方法 路径 说明
GET /qqbot/command/list 在线命令分页,支持 pluginKeyoperationKeyselfIdenabled
POST /qqbot/command/save 新增在线命令
POST /qqbot/command/update 更新在线命令
POST /qqbot/command/delete?id= 删除在线命令
POST /qqbot/command/toggle?id=&enabled= 启停在线命令
POST /qqbot/command/test 预览测试在线命令
GET /qqbot/rule/list 自动回复规则分页
POST /qqbot/rule/save 新增自动回复规则
POST /qqbot/rule/update 更新自动回复规则
POST /qqbot/rule/delete?id= 删除自动回复规则
POST /qqbot/rule/toggle?id=&enabled= 启停自动回复规则
GET /qqbot/permission/config 权限名单配置
POST /qqbot/permission/config 保存权限名单配置
GET /qqbot/permission/allowlist 白名单分页
POST /qqbot/permission/allowlist/save 新增白名单
POST /qqbot/permission/allowlist/update 更新白名单
POST /qqbot/permission/allowlist/delete?id= 删除白名单
GET /qqbot/permission/blocklist 黑名单分页
POST /qqbot/permission/blocklist/save 新增黑名单
POST /qqbot/permission/blocklist/update 更新黑名单
POST /qqbot/permission/blocklist/delete?id= 删除黑名单

/qqbot/command/test 示例:

{
  "commandId": "2041700000000000001",
  "text": "/查曲 夏祭り",
  "selfId": "10000",
  "targetType": "group",
  "targetId": "123456",
  "userId": "2354598417"
}

线上 smoke 必须按 operationKey 查询启用命令 ID 后传入 commandId,避免默认 preview selfId 误报未匹配命令。

Plugin / Dashboard / Send / Message

方法 路径 说明
GET /qqbot/plugin/list 插件列表,支持 triggerMode=command/event
GET /qqbot/plugin/operation/list 插件能力列表
GET /qqbot/plugin/health 插件健康检查
GET /qqbot/plugin/event/list 事件触发插件绑定状态
POST /qqbot/plugin/event/bind 绑定事件触发插件
POST /qqbot/plugin/event/unbind 解绑事件触发插件
GET /qqbot/dashboard/summary QQBot 工作台汇总
GET /qqbot/send/log/list 发送日志分页
POST /qqbot/send/private 发送私聊消息
POST /qqbot/send/group 发送群聊消息
GET /qqbot/conversation/list 会话列表
GET /qqbot/message/list 消息列表

Plugin Platform

插件平台使用统一 plugin.json manifest 描述插件 key、版本、入口、操作、事件、定时任务、权限和运行预算后端会校验路径必须留在插件包内权限必须命中白名单安装包 content hash 必须与 manifest 匹配。tasks 字段声明平台托管的定时任务:

字段 说明
key 全局唯一任务 key例如 bangdream.bestdori.sync-main-data
name Admin 展示名称
handlerName 插件入口暴露的任务处理器名称
defaultCron 5 段 cron 表达式,不允许每分钟执行,并按 BullMQ/cron-parser 语义校验
timeoutMs 单次任务执行预算
enabled 安装/启用时是否默认调度
permissions 任务需要的插件权限,例如 runtime.httpplugin.storage.write
description 可选说明

CLI 入口:

pnpm qqbot-plugin create <pluginKey>
pnpm qqbot-plugin validate <pluginDir>
pnpm qqbot-plugin pack <pluginDir>
pnpm qqbot-plugin install-local <packageFile>

平台管理接口:

方法 路径 说明
GET /qqbot/plugin-platform/installations 插件安装记录,支持 key/status 过滤
POST /qqbot/plugin-platform/upload 上传插件包并返回校验摘要
POST /qqbot/plugin-platform/validate 校验 manifest JSON
POST /qqbot/plugin-platform/install 按上传包安装插件版本
POST /qqbot/plugin-platform/install-local 按本地包路径安装插件版本
POST /qqbot/plugin-platform/enable 启用插件安装
POST /qqbot/plugin-platform/disable 禁用插件安装
POST /qqbot/plugin-platform/upgrade 升级插件安装版本
POST /qqbot/plugin-platform/uninstall 卸载插件安装
POST /qqbot/plugin-platform/config 保存插件配置
GET /qqbot/plugin-platform/runtime-events 查询插件运行事件
GET /qqbot/plugin-platform/account-bindings 查询插件账号绑定

定时任务管理接口:

方法 路径 说明
GET /qqbot/plugin-platform/tasks/page 插件定时任务分页,支持插件、状态过滤
GET /qqbot/plugin-platform/tasks/:id 任务详情
POST /qqbot/plugin-platform/tasks/:id/enable 启用任务并注册 BullMQ Job Scheduler
POST /qqbot/plugin-platform/tasks/:id/disable 停用任务并移除调度
POST /qqbot/plugin-platform/tasks/:id/cron 修改 5 段 cron校验通过后重建调度
POST /qqbot/plugin-platform/tasks/:id/run 手动提交一次任务
GET /qqbot/plugin-platform/tasks/:id/runs 任务运行记录分页

src/modules/qqbot/plugin-platform/runtime 当前提供 host-side driver 边界和超时/崩溃事件归档;实际 worker/child-process driver 可以在后续批次接入,但插件侧只能通过受控 SDK 访问发送队列、配置、存储、HTTP、资产和事件上下文。

Admin 入口为 /qqbot/plugin-task,用于分页查看任务、启停、修改 cron、手动运行和查看运行记录。BangDream 内置任务 bangdream.bestdori.sync-main-data 会定期同步 Bestdori 主数据到 BANGDREAM_TSUGU_CACHE_ROOT;生产容器内路径为 /data/qqbot/plugins/bangdream/cacheK8s hostPath 使用 k3d 节点可写目录 /var/lib/rancher/k3s/kt-template-online-api/qqbot-plugins

OneBot Reverse WebSocket

QQBOT_REVERSE_WS_PATH 默认是 /qqbot/onebot/reverse。NapCat 通过反向 WS 连接 APItoken 使用 QQBOT_REVERSE_WS_TOKEN

QQBot 插件能力

Bilibili Card

插件 keybilibili-card。这是事件型内置插件,不新增在线命令;启用后仍需通过账号事件绑定让指定 QQBot 账号接收 bilibili-card.message

event key 触发来源 说明
bilibili-card.message message 从 QQ/NapCat share/json/xml/lightapp 卡片和文本中提取 Bilibili 链接

插件会解析 www.bilibili.comm.bilibili.comb23.tv。短链通过插件平台受控 resolveRedirect host 能力限制跳转次数和超时;视频信息来自 Bilibili x/web-interface/view,回复首行使用视频封面 CQ image随后输出标题、UP 主、时长、播放/弹幕/点赞等文本摘要和标准视频链接。同一账号、同一会话、同一视频在 QQBOT_BILIBILI_CARD_DEDUPE_TTL_MS 内去重。

可配置键:

配置键 默认值 说明
QQBOT_BILIBILI_CARD_HTTP_TIMEOUT_MS 6000 HTTP 请求超时毫秒
QQBOT_BILIBILI_CARD_MAX_REDIRECTS 5 b23.tv 最大跳转数
QQBOT_BILIBILI_CARD_DEDUPE_TTL_MS 600000 同视频去重毫秒
QQBOT_BILIBILI_CARD_DESC_MAX_LENGTH 80 回复中简介最大字符数

BangDream

插件 keybangdream。旧 bangDream 作为兼容别名仍可解析;当前源码根目录为 src/modules/qqbot/plugins/bangdream/src,按第三期插件结构拆分为 operationsdomain/*applicationinfrastructure/integrationinfrastructure/storageconfigassetstheme,不再使用旧 tsugu 子目录、宿主 builtins 包装层或纯转接目录。

operation key 命令 说明
bangdream.song.search /查曲 查歌曲信息图片
bangdream.song.chart /查谱面 查谱面图片
bangdream.song.random /随机曲 随机歌曲
bangdream.song.meta /查询分数表 查歌曲分数榜
bangdream.card.search /查卡 查卡牌信息图片
bangdream.card.illustration /查卡面 查卡面插画
bangdream.character.search /查角色 查角色信息
bangdream.event.search /查活动 查活动信息
bangdream.event.stage /查试炼 查活动试炼,保持拆图输出
bangdream.player.search /查玩家 查玩家信息
bangdream.gacha.search /查卡池 查卡池
bangdream.gacha.simulate /抽卡模拟 模拟抽卡
bangdream.cutoff.detail /ycx 单档位预测线
bangdream.cutoff.all /ycxall 全档位预测线
bangdream.cutoff.recent /lsycx 历史/近期档线

plugins/bangdream/plugin.json 是 BangDream operation、handlerName、别名、权限、超时和说明的单一来源。新增或调整命令必须同步在线命令 SQL并跑 manifest/command-SQL 测试。

FF14 Market

插件 keyff14-market。旧 ff14Market 作为兼容别名仍可解析;源码按第三期插件结构拆分为 operationsapplicationdomaininfrastructure/integrationconfig

operation key 说明
ff14.item.resolve 按物品名称或 ID 解析 XIVAPI 物品
ff14.market.price 查询指定服务器/大区的 Universalis 市场价格

市场查价支持 itemitemIdworlddataCenterregionhqlanguage

FFLogs

插件 keyfflogs

源码按第三期插件结构拆分为 operationsapplicationdomaininfrastructure/integrationinfrastructure/storageconfig

operation key 说明
fflogs.character.summary 查询 FFLogs 角色公开排名;传 encounter 时查询指定高难最近记录

常用输入:characterNameserverSlugserverRegionencounterlimitmetrictimeframezoneId

初始化 SQL

文件 用途
sql/vben-admin-init.sql 创建 Admin 基础表、用户、角色、菜单、部门、字典和空组件表
sql/blog-init.sql 初始化本地 Blog 表
sql/blog-menu.sql 初始化 Blog 管理菜单
sql/qqbot-init.sql 初始化 QQBot 表、插件命令和字典
sql/system-log-menu.sql 初始化系统日志菜单和权限
sql/system-notice-menu.sql 初始化系统站内信表与菜单权限
sql/migrate-dict-to-admin-dict.sql dict 迁移到 admin_dict
sql/migrate-component-to-admin-component.sql component 迁移到 admin_component
sql/fix-admin-menu-meta.sql 修复菜单 meta 被覆盖为空
sql/fix-admin-user-zero-id.sql 修复旧版本 admin_user.id=0 脏数据

验证入口

常规文档/配置检查:

git diff --check

后端代码检查:

pnpm run typecheck
pnpm run lint
pnpm test

BangDream 图片 smoke

bash scripts/bangdream-render-smoke.sh --operation-key bangdream.song.search --text "夏祭り" --out-file ".kt-workspace/bangdream-smoke/song.jpg"
bash scripts/bangdream-render-smoke.sh --operation-key bangdream.event.stage --text "310" --out-file ".kt-workspace/bangdream-smoke/stage.jpg" --expected-image-count 5

Jenkins/K8s 发布后还需要观察 rollout、新 Pod 日志,并跑真实运行态 smoke推送成功不等于发布完成。