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:
parent
b2b5aa1f79
commit
b801aa0935
5 changed files with 101 additions and 14 deletions
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
14
src/NzbDrone.Core/Notifications/Telegram/TelegramLink.cs
Normal file
14
src/NzbDrone.Core/Notifications/Telegram/TelegramLink.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue