[Feature Request]: 入库失败通知支持可配置模板
Author: wy19xxCreated Aug 18, 2026Updated Sep 17, 2026
Labelsfeature requeststale
[Feature Request]: 入库失败通知支持可配置模板
当前程序版本
v2.15.6(Docker;同时核对了当前 v3.0.0 源码,仍存在同一缺口)
运行环境
Docker
功能改进类型
主程序
功能改进
背景
当前可以通过 NotificationTemplates 自定义“开始下载”“已入库”“添加订阅”“订阅完成”四类通知,但“入库失败”仍由后端直接拼接标题和正文后发送。
当一个下载任务中有多个文件、特典、字幕或音轨时,失败通知只有识别后的媒体标题和错误原因,无法通过通知模板展示实际失败的源文件名,也无法按自己的通知格式组织内容。
本请求不涉及失败通知聚合;聚合需求已有 #6343。本请求关注单条入库失败通知的模板化能力,两者可以独立实现,也应能兼容。
已确认的现状
ContentType目前只有subscribeAdded、subscribeComplete、organizeSuccess、downloadAdded,没有入库失败类型。TransferChain的入库成功路径创建ctype=ContentType.OrganizeSuccess,并向post_message()传入meta、mediainfo、transferinfo等模板上下文。- 入库失败路径则直接创建
mtype=Manual的固定Notification/Message,未设置ctype,也未将meta、mediainfo、transferinfo和转移历史 ID 传给模板渲染器。 - 通知模板上下文已有
original_name,其值来自meta.title。常规整理任务的meta由MetaInfoPath按实际FileItem.path构造,因此该变量可用于输出实际源文件名(含扩展名、无完整路径),不必再增加重复的source_file_name变量。 downloadAdded的官方默认模板已经使用torrent_title;这部分不属于本 Issue 的范围。
v2.15.6 对应位置:
app/helper/message.py:TemplateContextBuilder和MessageTemplateHelperapp/chain/transfer.py:入库成功及失败通知分支app/schemas/types.py:ContentType
当前 v3 对应位置:
app/application/messaging/message.pyapp/chain/transfer.pyapp/schemas/types.py
期望能力
- 新增
ContentType.OrganizeFailed = "organizeFailed",作为入库失败通知的模板键。 - 在默认
NotificationTemplates中增加organizeFailed模板,并通过迁移为已有配置补齐该键;不能覆盖用户已有的四类自定义模板。 - 将整理链中的入库失败通知接入该内容类型。至少覆盖:
- 已识别媒体后,实际整理失败的分支;
- 未识别到媒体信息而无法入库的分支。
- 模板渲染上下文应提供:
original_name:实际源文件名,包含扩展名但不包含完整路径;err_msg:失败原因;transfer_history_id:失败历史记录 ID;- 已有的
title_year、season_episode、type、category等字段在可用时继续提供。
- 模板只负责标题和正文。现有
mtype=Manual、通知渠道开关、图片、历史记录链接、重试按钮以及/redo <id>的可用性必须保持不变。 - 对旧配置或用户主动删除
organizeFailed模板的情况,必须回退到当前固定标题和正文,不能发送空通知。
建议的默认模板结构示例:
{
'title': '{{ title_year }}{% if season_episode %} {{ season_episode }}{% endif %} 入库失败!',
'text': '{% if original_name %}源文件:{{ original_name }}\\n{% endif %}'
'原因:{{ err_msg or "未知" }}'
'{% if transfer_history_id %}\\n如果按钮不可用,可回复:\\n/redo {{ transfer_history_id }}{% endif %}'
}这里仅展示模板字段;现有的重试按钮仍应由后端保留并照常发送。
建议实现方式
失败分支可在创建消息时设置 ctype=ContentType.OrganizeFailed,并通过 post_message() 传入 meta、mediainfo、transferinfo。同时显式传入以下覆盖值:
original_name=task.fileitem.name or Path(task.fileitem.path).name,
err_msg=transferinfo.message or "未识别到媒体信息",
transfer_history_id=history.id if history else None,TemplateContextBuilder.build() 会在构造默认上下文后合并额外参数,因此可确保 original_name 始终是实际源文件名,而不依赖元数据识别结果。未识别媒体信息的失败分支也应使用同一模板化路径,并传入对应的固定错误原因。
验收建议
- 配置
organizeFailed自定义模板后,已识别媒体的整理失败通知能渲染original_name、err_msg和transfer_history_id。 - 源文件名应与
FileItem.name一致,包含扩展名,不泄露完整下载路径。 - 未识别媒体信息的失败路径也能发送有效通知;缺失的媒体字段应通过 Jinja 条件安全处理。
- 模板化后,通知仍保留
Manual类型、历史链接、重试按钮和现有接收对象行为。 - 旧配置中没有
organizeFailed时,通知回退为当前固定内容而不是空消息。 - 新迁移只补充缺失的
organizeFailed键,不改写用户已有模板。
站点适配采集文件
不适用
参考资料
- #6008:通知模板上下文新增变量并补充测试的先例。
- #6343:入库失败通知聚合需求;本请求与其相关,但不重复。
Source: jxxghp/MoviePilot