RSS Forwarder 最近的改动重点不在新增订阅源,而在让每日阅读摘要和普通 RSS 媒体推送更可预测。一个订阅插件在实际使用中经常遇到的问题并不是“能不能抓到条目”,而是图文能否稳定发送、不同目标能否使用不同展示方式,以及失败后的下一轮调度是否会重复打扰。
项目概览
这个插件公开维护在 RhoninSeiei/astrbot_plugin_rss_forwarder。它把配置拆成 feeds、targets、jobs 和 daily_digests:源负责提供 RSS、Atom 或 Twitter/Nitter 条目,目标负责描述平台会话,任务负责把多个源和多个目标组合起来,日报则负责按时间窗口汇总内容。
代码结构也围绕这个分工展开。fetcher.py 处理源读取与代理,parser.py 规范化条目,scheduler.py 管理周期任务,dispatcher.py 负责去重、翻译和发送,daily_digest_image.py 负责本地图卡渲染。assets/daily_digest/ 保存图卡用的轻量素材和字体资源,测试覆盖配置迁移、解析、调度、发送和图卡生成。
本地渲染日报图卡
之前日报图片依赖外部图像渲染能力时,失败点比较多:接口可用性、远程渲染耗时、字体差异和消息链包装都可能影响结果。新的实现把日报 render_mode=image 移到本地 Pillow 渲染,使用预制 RSS 标识、角标、签名区和本地字体。
这样做的好处是生成结果可重复,部署时不需要等待远程图像服务。对于静态摘要图来说,最重要的是标题层级、来源、摘要和时间窗口清晰,而不是复杂视觉效果。本地渲染也让回退策略更明确:图卡生成失败时可以使用文本摘要继续发送。
远程媒体缓存与发送确认
普通 RSS 条目中的远程图片也做了整理。文本模式下,插件会优先把远程 RSS 图片缓存为本地 JPEG,再交给平台适配器发送。对于需要代理访问的源,feeds[].proxy_url 会传入原文图片缓存请求,减少源站反盗链、图片格式兼容和远程转存失败带来的错误。
发送确认也按实际场景拆分过。一次改动曾把正文和媒体拆成两段,先确认正文去重,再发送原文图片和视频,避免富媒体失败导致正文反复重试。后续文本模式又恢复到“正文 + 图片”同一条消息链,前提是图片已经经过本地缓存和格式整理。这条线索体现了插件的主要取舍:先保证内容身份和去重判断正确,再尽量保留图文完整性。
维护心得
RSS 工具看起来只是定时抓取和转发,实际更像一个轻量发布系统。源、目标、任务、去重、语义合并、翻译、日报、媒体缓存和发送确认都需要各自保持边界清晰。
本次整理后的项目结构更适合长期维护:日报图卡可以离线生成,远程媒体先进入本地缓存,任务级确认避免多目标重复发送,配置项也能针对源、任务和目标分别调节展示方式。对于个人阅读和兴趣频道来说,这比单纯堆叠更多订阅源更有价值。