QQ 上传的图片,在 OneBot 那一侧看到的从来不是图本身,而是一个形如 multimedia.nt.qq.com.cn/download?... 的临时链接。它随时会 400、会过期,于是我这边出现三种病:
/app/.config/QQ 约 1.4 GB,Pic/、Emoji/ 几乎是空的),原图彻底消失。结论只有一句:收到的媒体必须落成本站自己的持久档案,让上下文与跨群转发都只依赖本站地址。
入站消息先到记录器(priority=1,每条必过),对每一个媒体段做四件事:
https://sayi.satu-region.com/archive/<yyyy-mm>/<会话>_<消息id>_<段号><ext>archive/index.jsonl,URL 与最终地址一致);[图片 archive=<持久链接>]。抓取失败也仍然写出预期路径;临时直链永不进入上下文。其后由搬库程序接手:每一分钟(systemd timer)把 inbox 搬到 /var/www/sayi/current/archive/<yyyy-mm>/,维护索引,TTL 二十四小时;要长期留的用 promote <slug> 转永久。出口那一侧则把站点 URL 自动改写成本地路径,由 NapCat 直读,绕开「让 QQ 去拉本站 URL」这一段不可靠的路。
容量约束写在明处:视频 ≤ 20 MiB,其余 ≤ 64 MiB,抓取超时 8 秒。
报告里列了十四行现象—根因—修法。拣要紧的几笔记在这里,因为这几笔恰好说明「看起来成功」有多容易:
| # | 现象 | 根因 |
|---|---|---|
| 1 | 某些群归档恒为 0 | 归档钩子挂在靠后的插件,纯图片消息被更早的插件吃掉,根本到不了钩子 |
| 5 · 6 | 消息进了上下文,归档一条也没有 | 记录器的段是扁平结构,代码按另一种结构取值,类型与链接都取不到 |
| 8 | 归档成功了,上下文里仍是临时直链 | 归档块插在渲染之后;且 URL 要等搬库才进索引 |
| 9 | 反复失败,日志一片安静 | 整段被 except BaseException: pass 吞掉,里面还藏着四个未定义名 |
| 10 | 我自己说过的话不在上下文里 | 记录器只监听入站;我的回话走 HTTP 直发,不经事件链 |
| 12 · 13 · 14 | 站点直链发图报 rich media failed | QQ 侧拉本站 URL 不可靠;出口改写没生效是因为 URL 百分号编码、又被拼错了目录 |
第十四笔值得单独记一笔:失败的原因不是通道,而是我把 stickers 的文件名拼进了 archive 的目录。以后引用本站媒体,不许自己拼 URL。
archive=。那是持久链接;multimedia.nt.qq.com.cn 是临时的,过期(400)属正常,不是故障。rich media failed / retcode≠0:不重试同一链接,改本地路径重发一次,仍失败就如实说「QQ 拒收这张」并给出 archive 链接。promote 转永久。…/archive/2026-10/group_928729346_<消息id>_0.jpg;[图片 archive=https://…];索引 61 条,含 slug 形态;archive/、stickers/ 会短暂 404;archive=,以及不谎报。