Files
par/docs/mediabot-api-migration.md

11 KiB
Raw Permalink Blame History

PAR Server 接口升级对比文档 (供 MediaBot 迁移)

版本: V2.0(SiteSnapshot 重构)
日期: 2026-07-07
面向对象: MediaBot 开发团队


一、升级概览

本次重构将站点配置的存储和分发方式从 "分散存储 + 运行时合并" 升级为 "统一快照 + 增量更新"。核心变化:

维度 旧方案 (V1) 新方案 (V2)
存储 脚本/页面/规则分别存七牛云 MySQL site_snapshots 表统一存储 + 七牛云 CDN 灾备
获取方式 多次请求分别获取脚本、页面、规则 一次请求获取完整 bundle
更新检测 无/各接口各自判断 统一 checksum + ETag/304 增量更新
可用性 依赖七牛云 数据库为主 + 七牛云 CDN 自动灾备

二、新增接口(推荐 MediaBot 迁移到这些)

2.1 GET /api/v1/snapshots/{siteId} ⭐ 推荐

用途: 获取站点完整配置快照(一站式获取脚本 + 页面配置 + 风险规则)

查询参数:

参数 类型 默认值 说明
preview boolean false false=仅正式版(published),true=预览版优先(draft → published fallback)

请求头:

If-None-Match: {上次返回的 ETag checksum}

响应 200 OK(内容未变化时):

{
    "siteId": "example.com",
    "generatedAt": "2026-07-07T10:30:00",
    "script": "// Groovy 脚本完整源码...",
    "scriptVersion": "3",
    "scriptSource": "custom",
    "pages": [
        {
            "pageKey": "INDEX",
            "url": "https://example.com/torrents.php",
            "method": "GET",
            "...": "..."
        }
    ],
    "pagesVersion": "2",
    "pagesSource": "custom",
    "riskRules": [
        {
            "field": "title",
            "operator": "contains",
            "value": "xxx",
            "level": "WARN"
        }
    ],
    "riskRulesVersion": 1
}

响应 304 Not Modified(内容未变化):

HTTP/1.1 304 Not Modified
ETag: "abc123def456..."

(Body 为空,节省带宽)

可用性保障(PAR Server 端三层级联):

  • 第一层:优先从 MySQL 数据库读取
  • 第二层:数据库异常时自动回退到七牛云 CDN snapshots/{siteId}.json
  • 第三层:CDN 也无数据时,实时构建(从各子表 + 七牛云存储拼装)
  • 全部失败返回 500

MediaBot 端建议(应对 PAR Server 整体不可用):

  • MediaBot 应缓存每个站点的 CDN URL(https://{七牛云CDN域名}/snapshots/{siteId}.json)
  • 当 PAR Server 连接超时/拒绝连接时,直接请求 CDN URL 作为终极 fallback
  • 这样即使 PAR Server 宕机,配置仍可通过 CDN 获取(每次 publish 都会同步上传到 CDN)

2.2 GET /api/v1/snapshots/{siteId}/check ⭐ 推荐

用途: 轻量级检查站点是否有配置更新(不传输配置内容)

响应:

{
    "code": 200,
    "data": {
        "checksum": "abc123def456...",
        "version": 5,
        "publishedAt": "2026-07-07T10:30:00"
    }
}

使用模式:

  1. MediaBot 先调 /check 获取最新 checksum
  2. 与本地缓存的 checksum 比较
  3. 不同时再调 /snapshots/{siteId} 拉取完整配置

三、旧接口兼容状态

以下接口继续可用,但推荐逐步迁移到新接口:

3.1 GET /api/v1/configs/{siteId}/bundle — ⚠️ 保持兼容

项目 说明
状态 继续可用,底层已委托给快照服务
变化 无破坏性变化,响应格式不变
建议 可继续使用,但建议迁移到 GET /api/v1/snapshots/{siteId}

数据流变化:

旧: 七牛云 bundles/{siteId}.json → 返回
新: MySQL site_snapshots → 返回  (优先)
    ↓ 失败
    七牛云 bundles/{siteId}.json / snapshots/{siteId}.json → 返回  (回退)
    ↓ 失败
    实时构建 → 返回  (兜底)

3.2 GET /api/v1/configs/{siteId}/script — ⚠️ 保持兼容

项目 说明
状态 无变化,功能一致
建议 如需单独获取脚本,可继续使用;否则建议用 snapshot 一次性获取

3.3 GET /api/v1/scripts/{siteId} — ⚠️ 保持兼容

项目 说明
状态 无变化,功能一致
说明 仅返回 Groovy 脚本纯文本,无 JSON 包装
建议 如需单独获取脚本,可继续使用

3.4 GET /api/v1/scripts/{siteId}/version — ⚠️ 保持兼容

项目 说明
状态 无变化
响应 { "version": "3", "source": "custom" }
建议 可用 /snapshots/{siteId}/check 替代,后者提供更全面的版本信息

3.5 GET /api/v1/manifest — ⚠️ 保持兼容

项目 说明
状态 无变化,仍支持 ETag
说明 返回所有活跃站点配置索引(siteId、站点类型、是否有脚本/页面/规则等元信息)
建议 继续用于获取全量站点列表和配置状态概览

3.6 GET /api/v1/sites/{siteId}/pages — ⚠️ 保持兼容

项目 说明
状态 无变化
建议 如只需页面配置,可继续使用;否则建议用 snapshot

3.7 GET /api/v1/risk-rules/{siteType} — ⚠️ 保持兼容

项目 说明
状态 无变化,仍支持版本号增量判断
建议 如只需风险规则,可继续使用;否则建议用 snapshot

四、推荐 MediaBot 迁移方案

方案 A:完全迁移到 Snapshot(推荐)

MediaBot 启动 / 定时任务:
  1. GET /api/v1/manifest              → 获取全量站点列表
  2. 对每个站点:
     a. GET /api/v1/snapshots/{siteId}/check  → 获取最新 checksum
     b. 与本地缓存的 checksum 比较
     c. 不同时: GET /api/v1/snapshots/{siteId}  → 拉取完整 bundle
     d. 缓存 checksum 和完整 bundle

优点:

  • 每次只需 1~2 次 HTTP 请求即可获取站点全部配置
  • ETag/304 支持,配置未变时不传输内容
  • 三层可用性保障(数据库 → CDN → 实时构建)

方案 B:渐进式迁移(兼容期)

1. 优先调用新接口 GET /api/v1/snapshots/{siteId}
2. PAR Server 不可用时 fallback 到 CDN:
   - 直接 GET https://{CDN域名}/snapshots/{siteId}.json
3. CDN 也无数据时 fallback 到旧接口组合:
   - GET /api/v1/configs/{siteId}/script
   - GET /api/v1/sites/{siteId}/pages
   - GET /api/v1/risk-rules/{siteType}

五、响应格式对比

旧方式(分散获取)

需要 3~4 次 HTTP 请求 才能凑齐一个站点的完整配置:

请求 1: GET /api/v1/configs/{siteId}/script       → 返回 Groovy 脚本纯文本
请求 2: GET /api/v1/sites/{siteId}/pages          → 返回页面入口配置
请求 3: GET /api/v1/risk-rules/{siteType}         → 返回风险规则
请求 4: (可选) GET /api/v1/manifest               → 返回全局站点列表

新方式(统一快照)

1~2 次 HTTP 请求 获取站点完整配置:

请求 1: GET /api/v1/snapshots/{siteId}  (带 If-None-Match) → 返回完整 bundle
  - 配置未变化: 304 Not Modified (0 流量)
  - 配置有变化: 200 OK + 完整 JSON

(可选) 请求 0: GET /api/v1/manifest → 获取全量站点列表

Bundle JSON 响应字段说明

字段 类型 说明
siteId string 站点标识
checksum string 完整内容 SHA-256(用于 ETag)
generatedAt string 快照生成时间 (ISO 8601)
script string Groovy 脚本完整源码
scriptVersion string 脚本版本号
scriptSource string "custom" 或 "default"
pages array 页面入口配置条目列表
pagesVersion string 页面配置版本号
pagesSource string "custom" 或 "default"
riskRules array 风险规则列表
riskRulesVersion integer 风险规则版本号

六、预览模式与两阶段发布

预览版 vs 正式版

PAR 快照分为两个状态:

状态 说明 谁可见
预览版 (draft) 管理员保存后生效,未上传 CDN MediaBot 带 ?preview=true 可见
正式版 (published) 管理员发布后生效,已上传 CDN 所有请求默认可见

两阶段发布工作流

开发者提交配置 → 管理员审核通过 → 自动生成预览版
                                    ↓
                    管理员保存预览版(savePreview)
                                    ↓
            MediaBot 通过 ?preview=true 验证预览版效果
                                    ↓
                    管理员发布正式版(publish)
                                    ↓
               快照写入 CDN,所有 MediaBot 自动获取最新版

MediaBot 如何使用预览版

# 正常获取正式版(默认)
curl http://par:9012/api/v1/snapshots/pthome

# 获取预览版(用于开发/测试环境验证新配置)
curl "http://par:9012/api/v1/snapshots/pthome?preview=true"

💡 建议 MediaBot 在开发/测试环境使用 ?preview=true,生产环境使用默认(正式版)。


七、鉴权说明

无变化。所有配置读取接口(snapshot、manifest、script、pages、risk-rules)均为公开接口,无需鉴权。提交类接口需 HMAC/PSK 或 JWT 认证。


八、迁移时间线建议

阶段 时间 操作
Phase 1 立即 MediaBot 开始调用 /snapshots/{siteId} 作为主路径,旧接口作为 fallback
Phase 2 稳定运行 2 周后 移除旧接口 fallback 逻辑
Phase 3 后续版本 视情况废弃分散获取接口(script/pages/rules 独立端点)

九、FAQ

Q: 旧接口会下线吗?
A: 短期内不会。但建议尽快迁移到 snapshot 接口以获得更好的性能和可用性。

Q: snapshot 接口响应时间会不会更长?
A: 不会。数据库查询是单次 SQL(按 site_id + status 索引),且应用层有 Caffeine 缓存。304 场景下完全不传输内容。

Q: 如果 PAR Server 完全挂了怎么办?
A: Snapshot 在发布时会同步上传到七牛云 CDN (snapshots/{siteId}.json),MediaBot 可以直接从 CDN 读取作为终极灾备。

Q: checksum 是用什么算法计算的?
A: SHA-256,对完整 bundle JSON 内容计算。

Q: bundle 和 snapshot 的区别?
A: 同一份数据。/configs/{siteId}/bundle 是兼容旧路径,/snapshots/{siteId} 是新路径,底层数据源相同。