1
0
Fork 0
mirror of https://github.com/Radarr/Radarr synced 2024-12-21 23:42:23 +00:00

New: Add metadata links to telegram messages

Co-authored-by: Ivar Stangeby <istangeby@gmail.com>

Fixed errors sending Telegram notifications when links aren't available

(cherry picked from commit 4eab168267db716a9e897a992e3a7f6889571f9f)
(cherry picked from commit 4d7a3d0909437268b4ad0a0dbeb59d45b4435118)

Closes #10242
Closes #10489
This commit is contained in:
Mark McDowall 2024-07-30 21:25:48 -07:00 committed by Bogdan
parent b2b5aa1f79
commit b801aa0935
5 changed files with 101 additions and 14 deletions

View file

@ -1236,6 +1236,8 @@
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Optionally prefix message title with {appName} to differentiate notifications from different applications",
"NotificationsTelegramSettingsIncludeInstanceName": "Include Instance Name in Title",
"NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Optionally include Instance name in notification",
"NotificationsTelegramSettingsMetadataLinks": "Metadata Links",
"NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Add links to movie metadata when sending notifications",
"NotificationsTelegramSettingsSendSilently": "Send Silently",
"NotificationsTelegramSettingsSendSilentlyHelpText": "Sends the message silently. Users will receive a notification with no sound",
"NotificationsTelegramSettingsTopicId": "Topic ID",

View file

@ -27,8 +27,9 @@ public override void OnGrab(GrabMessage grabMessage)
{
var title = Settings.IncludeAppNameInTitle ? MOVIE_GRABBED_TITLE_BRANDED : MOVIE_GRABBED_TITLE;
title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title;
var links = GetLinks(grabMessage.Movie);
_proxy.SendNotification(title, grabMessage.Message, Settings);
_proxy.SendNotification(title, grabMessage.Message, links, Settings);
}
public override void OnDownload(DownloadMessage message)
@ -44,32 +45,36 @@ public override void OnDownload(DownloadMessage message)
}
title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title;
var links = GetLinks(message.Movie);
_proxy.SendNotification(title, message.Message, Settings);
_proxy.SendNotification(title, message.Message, links, Settings);
}
public override void OnMovieAdded(Movie movie)
{
var title = Settings.IncludeAppNameInTitle ? MOVIE_ADDED_TITLE_BRANDED : MOVIE_ADDED_TITLE;
title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title;
var links = GetLinks(movie);
_proxy.SendNotification(title, $"{movie.Title} added to library", Settings);
_proxy.SendNotification(title, $"{movie.Title} added to library", links, Settings);
}
public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage)
{
var title = Settings.IncludeAppNameInTitle ? MOVIE_FILE_DELETED_TITLE_BRANDED : MOVIE_FILE_DELETED_TITLE;
title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title;
var links = GetLinks(deleteMessage.Movie);
_proxy.SendNotification(title, deleteMessage.Message, Settings);
_proxy.SendNotification(title, deleteMessage.Message, links, Settings);
}
public override void OnMovieDelete(MovieDeleteMessage deleteMessage)
{
var title = Settings.IncludeAppNameInTitle ? MOVIE_DELETED_TITLE_BRANDED : MOVIE_DELETED_TITLE;
title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title;
var links = GetLinks(deleteMessage.Movie);
_proxy.SendNotification(title, deleteMessage.Message, Settings);
_proxy.SendNotification(title, deleteMessage.Message, links, Settings);
}
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
@ -77,7 +82,7 @@ public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
var title = Settings.IncludeAppNameInTitle ? HEALTH_ISSUE_TITLE_BRANDED : HEALTH_ISSUE_TITLE;
title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title;
_proxy.SendNotification(title, healthCheck.Message, Settings);
_proxy.SendNotification(title, healthCheck.Message, new List<TelegramLink>(), Settings);
}
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
@ -85,7 +90,7 @@ public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
var title = Settings.IncludeAppNameInTitle ? HEALTH_RESTORED_TITLE_BRANDED : HEALTH_RESTORED_TITLE;
title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title;
_proxy.SendNotification(title, $"The following issue is now resolved: {previousCheck.Message}", Settings);
_proxy.SendNotification(title, $"The following issue is now resolved: {previousCheck.Message}", new List<TelegramLink>(), Settings);
}
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
@ -93,7 +98,7 @@ public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
var title = Settings.IncludeAppNameInTitle ? APPLICATION_UPDATE_TITLE_BRANDED : APPLICATION_UPDATE_TITLE;
title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title;
_proxy.SendNotification(title, updateMessage.Message, Settings);
_proxy.SendNotification(title, updateMessage.Message, new List<TelegramLink>(), Settings);
}
public override void OnManualInteractionRequired(ManualInteractionRequiredMessage message)
@ -101,7 +106,7 @@ public override void OnManualInteractionRequired(ManualInteractionRequiredMessag
var title = Settings.IncludeAppNameInTitle ? MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED : MANUAL_INTERACTION_REQUIRED_TITLE;
title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title;
_proxy.SendNotification(title, message.Message, Settings);
_proxy.SendNotification(title, message.Message, new List<TelegramLink>(), Settings);
}
public override ValidationResult Test()
@ -112,5 +117,37 @@ public override ValidationResult Test()
return new ValidationResult(failures);
}
private List<TelegramLink> GetLinks(Movie movie)
{
var links = new List<TelegramLink>();
if (movie == null)
{
return links;
}
foreach (var link in Settings.MetadataLinks)
{
var linkType = (MetadataLinkType)link;
if (linkType == MetadataLinkType.Tmdb && movie.TmdbId > 0)
{
links.Add(new TelegramLink("TMDb", $"https://www.themoviedb.org/movie/{movie.TmdbId}"));
}
if (linkType == MetadataLinkType.Imdb && movie.ImdbId.IsNotNullOrWhiteSpace())
{
links.Add(new TelegramLink("IMDb", $"https://www.imdb.com/title/{movie.ImdbId}"));
}
if (linkType == MetadataLinkType.Trakt && movie.TmdbId > 0)
{
links.Add(new TelegramLink("Trakt", $"https://trakt.tv/search/tmdb/{movie.TmdbId}?id_type=movie"));
}
}
return links;
}
}
}

View file

@ -0,0 +1,14 @@
namespace NzbDrone.Core.Notifications.Telegram
{
public class TelegramLink
{
public string Label { get; set; }
public string Link { get; set; }
public TelegramLink(string label, string link)
{
Label = label;
Link = link;
}
}
}

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Web;
using FluentValidation.Results;
using NLog;
@ -14,7 +15,7 @@ namespace NzbDrone.Core.Notifications.Telegram
{
public interface ITelegramProxy
{
void SendNotification(string title, string message, TelegramSettings settings);
void SendNotification(string title, string message, List<TelegramLink> links, TelegramSettings settings);
ValidationFailure Test(TelegramSettings settings);
}
@ -34,10 +35,16 @@ public TelegramProxy(IHttpClient httpClient, IConfigFileProvider configFileProvi
_logger = logger;
}
public void SendNotification(string title, string message, TelegramSettings settings)
public void SendNotification(string title, string message, List<TelegramLink> links, TelegramSettings settings)
{
// Format text to add the title before and bold using markdown
var text = $"<b>{HttpUtility.HtmlEncode(title)}</b>\n{HttpUtility.HtmlEncode(message)}";
var text = new StringBuilder($"<b>{HttpUtility.HtmlEncode(title)}</b>\n");
text.AppendLine(HttpUtility.HtmlEncode(message));
foreach (var link in links)
{
text.AppendLine($"<a href=\"{link.Link}\">{HttpUtility.HtmlEncode(link.Label)}</a>");
}
var requestBuilder = new HttpRequestBuilder(URL).Resource("bot{token}/sendmessage").Post();
@ -60,9 +67,15 @@ public ValidationFailure Test(TelegramSettings settings)
const string title = "Test Notification";
const string body = "This is a test message from Radarr";
var links = new List<TelegramLink>
{
new ("Radarr.video", "https://radarr.video")
};
var testMessageTitle = settings.IncludeAppNameInTitle ? brandedTitle : title;
testMessageTitle = settings.IncludeInstanceNameInTitle ? $"{testMessageTitle} - {_configFileProvider.InstanceName}" : testMessageTitle;
SendNotification(testMessageTitle, body, settings);
SendNotification(testMessageTitle, body, links, settings);
}
catch (Exception ex)
{

View file

@ -1,3 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
@ -12,6 +15,16 @@ public TelegramSettingsValidator()
RuleFor(c => c.ChatId).NotEmpty();
RuleFor(c => c.TopicId).Must(topicId => !topicId.HasValue || topicId > 1)
.WithMessage("Topic ID must be greater than 1 or empty");
RuleFor(c => c.MetadataLinks).Custom((links, context) =>
{
foreach (var link in links)
{
if (!Enum.IsDefined(typeof(MetadataLinkType), link))
{
context.AddFailure("MetadataLinks", $"MetadataLink is not valid: {link}");
}
}
});
}
}
@ -19,6 +32,11 @@ public class TelegramSettings : NotificationSettingsBase<TelegramSettings>
{
private static readonly TelegramSettingsValidator Validator = new ();
public TelegramSettings()
{
MetadataLinks = Enumerable.Empty<int>();
}
[FieldDefinition(0, Label = "NotificationsTelegramSettingsBotToken", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://core.telegram.org/bots")]
public string BotToken { get; set; }
@ -37,6 +55,9 @@ public class TelegramSettings : NotificationSettingsBase<TelegramSettings>
[FieldDefinition(5, Label = "NotificationsTelegramSettingsIncludeInstanceName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeInstanceNameHelpText", Advanced = true)]
public bool IncludeInstanceNameInTitle { get; set; }
[FieldDefinition(6, Label = "NotificationsTelegramSettingsMetadataLinks", Type = FieldType.Select, SelectOptions = typeof(MetadataLinkType), HelpText = "NotificationsTelegramSettingsMetadataLinksMovieHelpText")]
public IEnumerable<int> MetadataLinks { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));