mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-10-29 23:12:39 +01:00
New: Add metadata links to telegram messages
Closes #5342 --------- Co-authored-by: Ivar Stangeby <istangeby@gmail.com>
This commit is contained in:
parent
c9b5a1258a
commit
4eab168267
@ -1429,6 +1429,8 @@
|
|||||||
"NotificationsTelegramSettingsChatIdHelpText": "You must start a conversation with the bot or add it to your group to receive messages",
|
"NotificationsTelegramSettingsChatIdHelpText": "You must start a conversation with the bot or add it to your group to receive messages",
|
||||||
"NotificationsTelegramSettingsIncludeAppName": "Include {appName} in Title",
|
"NotificationsTelegramSettingsIncludeAppName": "Include {appName} in Title",
|
||||||
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Optionally prefix message title with {appName} to differentiate notifications from different applications",
|
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Optionally prefix message title with {appName} to differentiate notifications from different applications",
|
||||||
|
"NotificationsTelegramSettingsMetadataLinks": "Metadata Links",
|
||||||
|
"NotificationsTelegramSettingsMetadataLinksHelpText": "Add a links to series metadata when sending notifications",
|
||||||
"NotificationsTelegramSettingsSendSilently": "Send Silently",
|
"NotificationsTelegramSettingsSendSilently": "Send Silently",
|
||||||
"NotificationsTelegramSettingsSendSilentlyHelpText": "Sends the message silently. Users will receive a notification with no sound",
|
"NotificationsTelegramSettingsSendSilentlyHelpText": "Sends the message silently. Users will receive a notification with no sound",
|
||||||
"NotificationsTelegramSettingsTopicId": "Topic ID",
|
"NotificationsTelegramSettingsTopicId": "Topic ID",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Telegram
|
namespace NzbDrone.Core.Notifications.Telegram
|
||||||
{
|
{
|
||||||
@ -19,71 +20,77 @@ namespace NzbDrone.Core.Notifications.Telegram
|
|||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? EPISODE_GRABBED_TITLE_BRANDED : EPISODE_GRABBED_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? EPISODE_GRABBED_TITLE_BRANDED : EPISODE_GRABBED_TITLE;
|
||||||
|
var links = GetLinks(grabMessage.Series);
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
_proxy.SendNotification(title, grabMessage.Message, links, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? EPISODE_DOWNLOADED_TITLE_BRANDED : EPISODE_DOWNLOADED_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? EPISODE_DOWNLOADED_TITLE_BRANDED : EPISODE_DOWNLOADED_TITLE;
|
||||||
|
var links = GetLinks(message.Series);
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, links, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnImportComplete(ImportCompleteMessage message)
|
public override void OnImportComplete(ImportCompleteMessage message)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? EPISODE_DOWNLOADED_TITLE_BRANDED : EPISODE_DOWNLOADED_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? EPISODE_DOWNLOADED_TITLE_BRANDED : EPISODE_DOWNLOADED_TITLE;
|
||||||
|
var links = GetLinks(message.Series);
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, links, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage)
|
public override void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? EPISODE_DELETED_TITLE_BRANDED : EPISODE_DELETED_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? EPISODE_DELETED_TITLE_BRANDED : EPISODE_DELETED_TITLE;
|
||||||
|
var links = GetLinks(deleteMessage.Series);
|
||||||
|
|
||||||
_proxy.SendNotification(title, deleteMessage.Message, Settings);
|
_proxy.SendNotification(title, deleteMessage.Message, links, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnSeriesAdd(SeriesAddMessage message)
|
public override void OnSeriesAdd(SeriesAddMessage message)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? SERIES_ADDED_TITLE_BRANDED : SERIES_ADDED_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? SERIES_ADDED_TITLE_BRANDED : SERIES_ADDED_TITLE;
|
||||||
|
var links = GetLinks(message.Series);
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, links, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnSeriesDelete(SeriesDeleteMessage deleteMessage)
|
public override void OnSeriesDelete(SeriesDeleteMessage deleteMessage)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? SERIES_DELETED_TITLE_BRANDED : SERIES_DELETED_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? SERIES_DELETED_TITLE_BRANDED : SERIES_DELETED_TITLE;
|
||||||
|
var links = GetLinks(deleteMessage.Series);
|
||||||
|
|
||||||
_proxy.SendNotification(title, deleteMessage.Message, Settings);
|
_proxy.SendNotification(title, deleteMessage.Message, links, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? HEALTH_ISSUE_TITLE_BRANDED : HEALTH_ISSUE_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? HEALTH_ISSUE_TITLE_BRANDED : HEALTH_ISSUE_TITLE;
|
||||||
|
|
||||||
_proxy.SendNotification(title, healthCheck.Message, Settings);
|
_proxy.SendNotification(title, healthCheck.Message, null, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
|
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? HEALTH_RESTORED_TITLE_BRANDED : HEALTH_RESTORED_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? HEALTH_RESTORED_TITLE_BRANDED : HEALTH_RESTORED_TITLE;
|
||||||
|
|
||||||
_proxy.SendNotification(title, $"The following issue is now resolved: {previousCheck.Message}", Settings);
|
_proxy.SendNotification(title, $"The following issue is now resolved: {previousCheck.Message}", null, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? APPLICATION_UPDATE_TITLE_BRANDED : APPLICATION_UPDATE_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? APPLICATION_UPDATE_TITLE_BRANDED : APPLICATION_UPDATE_TITLE;
|
||||||
|
|
||||||
_proxy.SendNotification(title, updateMessage.Message, Settings);
|
_proxy.SendNotification(title, updateMessage.Message, null, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnManualInteractionRequired(ManualInteractionRequiredMessage message)
|
public override void OnManualInteractionRequired(ManualInteractionRequiredMessage message)
|
||||||
{
|
{
|
||||||
var title = Settings.IncludeAppNameInTitle ? MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED : MANUAL_INTERACTION_REQUIRED_TITLE;
|
var title = Settings.IncludeAppNameInTitle ? MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED : MANUAL_INTERACTION_REQUIRED_TITLE;
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, null, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
@ -94,5 +101,37 @@ namespace NzbDrone.Core.Notifications.Telegram
|
|||||||
|
|
||||||
return new ValidationResult(failures);
|
return new ValidationResult(failures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<TelegramLink> GetLinks(Series series)
|
||||||
|
{
|
||||||
|
var links = new List<TelegramLink>();
|
||||||
|
|
||||||
|
foreach (var link in Settings.MetadataLinks)
|
||||||
|
{
|
||||||
|
var linkType = (MetadataLinkType)link;
|
||||||
|
|
||||||
|
if (linkType == MetadataLinkType.Imdb && series.ImdbId.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
links.Add(new TelegramLink("IMDb", $"https://www.imdb.com/title/{series.ImdbId}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linkType == MetadataLinkType.Tvdb && series.TvdbId > 0)
|
||||||
|
{
|
||||||
|
links.Add(new TelegramLink("TVDb", $"http://www.thetvdb.com/?tab=series&id={series.TvdbId}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linkType == MetadataLinkType.Trakt && series.TvdbId > 0)
|
||||||
|
{
|
||||||
|
links.Add(new TelegramLink("TVMaze", $"http://trakt.tv/search/tvdb/{series.TvdbId}?id_type=show"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linkType == MetadataLinkType.Tvmaze && series.TvMazeId > 0)
|
||||||
|
{
|
||||||
|
links.Add(new TelegramLink("Trakt", $"http://www.tvmaze.com/shows/{series.TvMazeId}/_"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
@ -13,7 +14,7 @@ namespace NzbDrone.Core.Notifications.Telegram
|
|||||||
{
|
{
|
||||||
public interface ITelegramProxy
|
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);
|
ValidationFailure Test(TelegramSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,10 +33,16 @@ namespace NzbDrone.Core.Notifications.Telegram
|
|||||||
_logger = logger;
|
_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 = new StringBuilder($"<b>{HttpUtility.HtmlEncode(title)}</b>\n");
|
||||||
var text = $"<b>{HttpUtility.HtmlEncode(title)}</b>\n{HttpUtility.HtmlEncode(message)}";
|
|
||||||
|
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();
|
var requestBuilder = new HttpRequestBuilder(URL).Resource("bot{token}/sendmessage").Post();
|
||||||
|
|
||||||
@ -58,7 +65,12 @@ namespace NzbDrone.Core.Notifications.Telegram
|
|||||||
const string title = "Test Notification";
|
const string title = "Test Notification";
|
||||||
const string body = "This is a test message from Sonarr";
|
const string body = "This is a test message from Sonarr";
|
||||||
|
|
||||||
SendNotification(settings.IncludeAppNameInTitle ? brandedTitle : title, body, settings);
|
var links = new List<TelegramLink>
|
||||||
|
{
|
||||||
|
new TelegramLink("Sonarr.tv", "https://sonarr.tv")
|
||||||
|
};
|
||||||
|
|
||||||
|
SendNotification(settings.IncludeAppNameInTitle ? brandedTitle : title, body, links, settings);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Telegram
|
namespace NzbDrone.Core.Notifications.Telegram
|
||||||
{
|
{
|
||||||
public class TelegramSettingsValidator : AbstractValidator<TelegramSettings>
|
public class TelegramSettingsValidator : AbstractValidator<TelegramSettings>
|
||||||
@ -12,6 +14,16 @@ namespace NzbDrone.Core.Notifications.Telegram
|
|||||||
RuleFor(c => c.ChatId).NotEmpty();
|
RuleFor(c => c.ChatId).NotEmpty();
|
||||||
RuleFor(c => c.TopicId).Must(topicId => !topicId.HasValue || topicId > 1)
|
RuleFor(c => c.TopicId).Must(topicId => !topicId.HasValue || topicId > 1)
|
||||||
.WithMessage("Topic ID must be greater than 1 or empty");
|
.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 +31,11 @@ namespace NzbDrone.Core.Notifications.Telegram
|
|||||||
{
|
{
|
||||||
private static readonly TelegramSettingsValidator Validator = new ();
|
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")]
|
[FieldDefinition(0, Label = "NotificationsTelegramSettingsBotToken", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://core.telegram.org/bots")]
|
||||||
public string BotToken { get; set; }
|
public string BotToken { get; set; }
|
||||||
|
|
||||||
@ -34,9 +51,27 @@ namespace NzbDrone.Core.Notifications.Telegram
|
|||||||
[FieldDefinition(4, Label = "NotificationsTelegramSettingsIncludeAppName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeAppNameHelpText")]
|
[FieldDefinition(4, Label = "NotificationsTelegramSettingsIncludeAppName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeAppNameHelpText")]
|
||||||
public bool IncludeAppNameInTitle { get; set; }
|
public bool IncludeAppNameInTitle { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(5, Label = "NotificationsTelegramSettingsMetadataLinks", Type = FieldType.Select, SelectOptions = typeof(MetadataLinkType), HelpText = "NotificationsTelegramSettingsMetadataLinksHelpText")]
|
||||||
|
public IEnumerable<int> MetadataLinks { get; set; }
|
||||||
|
|
||||||
public override NzbDroneValidationResult Validate()
|
public override NzbDroneValidationResult Validate()
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum MetadataLinkType
|
||||||
|
{
|
||||||
|
[FieldOption(Label = "IMDb")]
|
||||||
|
Imdb,
|
||||||
|
|
||||||
|
[FieldOption(Label = "TVDb")]
|
||||||
|
Tvdb,
|
||||||
|
|
||||||
|
[FieldOption(Label = "TVMaze")]
|
||||||
|
Tvmaze,
|
||||||
|
|
||||||
|
[FieldOption(Label = "Trakt")]
|
||||||
|
Trakt,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user