diff --git a/internal/service/download_notification.go b/internal/service/download_notification.go
index 2288bdd..dac1120 100644
--- a/internal/service/download_notification.go
+++ b/internal/service/download_notification.go
@@ -2,7 +2,6 @@ package service
import (
"context"
- "fmt"
"path/filepath"
"strings"
"time"
@@ -33,7 +32,7 @@ func (d *DownloadService) notifyDownloadComplete(ctx context.Context, torrent QB
func downloadCompleteNotificationPayload(torrent QBitTorrent, task *model.DownloadTask) (string, map[string]interface{}) {
name := downloadCompleteNotificationName(torrent, task)
- body := fmt.Sprintf("任务:%s\n保存路径:%s\nHash:%s", name, firstNonEmpty(torrent.ContentPath, torrent.SavePath), torrent.Hash)
+ body := "任务:" + name
data := downloadCompleteNotificationData(torrent, task)
return body, data
}
diff --git a/internal/service/downloads_view_test.go b/internal/service/downloads_view_test.go
index 747ca79..00168ab 100644
--- a/internal/service/downloads_view_test.go
+++ b/internal/service/downloads_view_test.go
@@ -58,8 +58,10 @@ func TestDownloadCompleteNotificationPayloadUsesTaskMetadata(t *testing.T) {
if !strings.Contains(body, "任务:正式标题") {
t.Fatalf("body should prefer task title, got %q", body)
}
- if !strings.Contains(body, "保存路径:/downloads/show/Release.Name.S01E02.1080p.mkv") {
- t.Fatalf("body should include content path, got %q", body)
+ for _, private := range []string{"保存路径", "/downloads/show", "Hash", "done123"} {
+ if strings.Contains(body, private) {
+ t.Fatalf("body should not expose %q, got %q", private, body)
+ }
}
for key, want := range map[string]interface{}{
"resource_title": "Release.Name.S01E02.1080p",
diff --git a/internal/service/notify_channels_test.go b/internal/service/notify_channels_test.go
index f007085..83a75a0 100644
--- a/internal/service/notify_channels_test.go
+++ b/internal/service/notify_channels_test.go
@@ -101,27 +101,45 @@ func TestTelegramDispatchUsesPhotoAndFormattedCaption(t *testing.T) {
}
caption := gotForm["caption"]
for _, want := range []string{
- "🐈⬛🐈⬛ MediaStationGo 更新啦 🐈⬛🐈⬛",
- "--------------------------------",
- "#剧集",
- "📺 中文片名:美国甜心:达拉斯牛仔啦啦队",
- "🧿 原始片名:AMERICA'S SWEETHEARTS: Dallas Cowboys Cheerleaders",
- "🌐 原始语言:英语",
- "📅 发行年份:2024",
- "🐈⬛ 类别:纪录片剧集",
- "🫧 季集:S03E07",
- "🔎 大小:3.0GB / 5.7Mbps",
- "📁 版本:H264.NF.FHD-HHWEB",
- "⭐️ 评分:8.2",
- "💎 类型:纪录",
- "🪬 简介:",
- `🔗 外链:TMDB / IMDB / 豆瓣`,
+ "#下载完成",
+ "📺 任务:示例影片",
} {
if !strings.Contains(caption, want) {
t.Fatalf("caption missing %q: %s", want, caption)
}
}
- for _, unwanted := range []string{"✅ 下载完成", "🎯 订阅命中新资源", "保存路径", "abcdef"} {
+ for _, unwanted := range []string{
+ "✅ 下载完成",
+ "🎯 订阅命中新资源",
+ "保存路径",
+ "abcdef",
+ "美国甜心:达拉斯牛仔啦啦队",
+ "AMERICA'S SWEETHEARTS",
+ "2024",
+ "3.0GB",
+ "简介",
+ server.URL + "/tmdb",
+ } {
+ if strings.Contains(caption, unwanted) {
+ t.Fatalf("caption should not include %q: %s", unwanted, caption)
+ }
+ }
+}
+
+func TestTelegramDownloadCompleteNeverFallsBackToSensitiveFields(t *testing.T) {
+ caption := formatTelegramNotification(NotifyEvent{
+ Type: EventDownloadComplete,
+ Data: map[string]interface{}{
+ "save_path": "/downloads/private/movie.mkv",
+ "hash": "abcdef",
+ },
+ })
+ for _, want := range []string{"#下载完成", "📺 任务:下载任务"} {
+ if !strings.Contains(caption, want) {
+ t.Fatalf("caption missing %q: %s", want, caption)
+ }
+ }
+ for _, unwanted := range []string{"保存路径", "/downloads/private", "Hash", "abcdef"} {
if strings.Contains(caption, unwanted) {
t.Fatalf("caption should not include %q: %s", unwanted, caption)
}
diff --git a/internal/service/notify_telegram_media.go b/internal/service/notify_telegram_media.go
index a0be82e..fccc22b 100644
--- a/internal/service/notify_telegram_media.go
+++ b/internal/service/notify_telegram_media.go
@@ -13,6 +13,10 @@ const (
var telegramSeasonEpisodePattern = regexp.MustCompile(`(?i)S\d{1,2}E\d{1,3}(?:[\-.~_ ]?E?\d{1,3})?`)
func formatTelegramMediaNotification(event NotifyEvent) string {
+ if strings.TrimSpace(event.Type) == EventDownloadComplete {
+ return formatTelegramDownloadCompleteNotification(event)
+ }
+
tag := telegramMediaTag(event.Data)
if tag == "" {
return ""
@@ -97,6 +101,17 @@ func formatTelegramMediaNotification(event NotifyEvent) string {
return strings.TrimSpace(strings.Join(lines, "\n"))
}
+func formatTelegramDownloadCompleteNotification(event NotifyEvent) string {
+ title := telegramMessageFieldValue(event.Message, "任务", "媒体", "资源")
+ if title == "" {
+ title = telegramFirstValue(event.Data, "title", "name", "media_title", "chinese_title", "resource_title")
+ }
+ if title == "" {
+ title = "下载任务"
+ }
+ return "#下载完成\n📺 任务:" + escapeHTML(title)
+}
+
func telegramMediaTag(data map[string]interface{}) string {
for _, key := range []string{"media_category", "category", "media_type"} {
value := strings.TrimSpace(telegramDataString(data, key))