-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] Add clickable metadata links when using the Telegram connector. (IMDb / Trakt / TVDb, TVMaze) #6613
base: develop
Are you sure you want to change the base?
Conversation
Add metadata links to series when using Telegram connector.
@@ -1,6 +1,7 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFrameworks>net6.0</TargetFrameworks> | |||
<Platforms>AnyCPU;x86</Platforms> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll drop the changes in the .csproj
-files. Not sure how I managed to commit them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do, the Sonarr.sln
one as well.
private readonly ITelegramProxy _proxy; | ||
private readonly Dictionary<MetadataLinkType, Func<string, string, string>> _formatLinkFromIdMethods; | ||
|
||
private string FormatImdbLinkFromId(string message, string id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be encapsulated in a utility class somehow? Might be useful for other notication providers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially, but it depends a lot on the format something else might need, so for now I wouldn't worry about it.
This whole group of methods can be cleaned up and combined with FormatMessageWithLink
Something like to cut down on the functions and only add links when they will be correctly formatted:
private string FormatMessageWithLink(string message, Series series)
{
var linkType = (MetadataLinkType)Settings.MetadataLinkType;
if (MetadataLinkType.None)
{
return message;
}
if (MetadataLinkType.Imdbb && series.ImdbId.IsNotNullOrWhiteSpace())
{
return $"[{message}](https://www.imdb.com/title/{series.ImdbId})";
}
...
return message;
}
No need to throw if the ID is unavailable or the enum value is unexpected since we don't want the notification to be skipped, it'll just be missing that info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also move these private functions to the bottom of the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice first contribution :)
I was wondering why the choice for 4 different methods for formatting the string? Couldnt it be done in a single method with a case switch if you pass in the MedatdataLinkType?
How have you handled cases where there isn't an imdb, trakt or tvmaze Id associated with the show, but user has selected on?
Thanks for the input! I'll try to create a switch. And no, I haven't considered that fact! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for contributing! Left quite a few comments which should help clean things up a lot and reduce the number of changes to make it easier to follow.
@@ -1,6 +1,7 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFrameworks>net6.0</TargetFrameworks> | |||
<Platforms>AnyCPU;x86</Platforms> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do, the Sonarr.sln
one as well.
private readonly ITelegramProxy _proxy; | ||
private readonly Dictionary<MetadataLinkType, Func<string, string, string>> _formatLinkFromIdMethods; | ||
|
||
private string FormatImdbLinkFromId(string message, string id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially, but it depends a lot on the format something else might need, so for now I wouldn't worry about it.
This whole group of methods can be cleaned up and combined with FormatMessageWithLink
Something like to cut down on the functions and only add links when they will be correctly formatted:
private string FormatMessageWithLink(string message, Series series)
{
var linkType = (MetadataLinkType)Settings.MetadataLinkType;
if (MetadataLinkType.None)
{
return message;
}
if (MetadataLinkType.Imdbb && series.ImdbId.IsNotNullOrWhiteSpace())
{
return $"[{message}](https://www.imdb.com/title/{series.ImdbId})";
}
...
return message;
}
No need to throw if the ID is unavailable or the enum value is unexpected since we don't want the notification to be skipped, it'll just be missing that info.
private readonly ITelegramProxy _proxy; | ||
private readonly Dictionary<MetadataLinkType, Func<string, string, string>> _formatLinkFromIdMethods; | ||
|
||
private string FormatImdbLinkFromId(string message, string id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also move these private functions to the bottom of the class.
|
||
private string FormatMessageWithLink(string message, Series series) | ||
{ | ||
if (Settings.SendMetadataLink && _formatLinkFromIdMethods.TryGetValue(Settings.MetadataLinkType, out var formatMethod)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Settings should validate that the stored MetadataLinkType
is valid.
We'll have a TVDB ID 100% of the time, IMDB should be null (off chance of an empty string) and everything else will be 0 if not set. |
|
||
var requestBuilder = new HttpRequestBuilder(URL).Resource("bot{token}/sendmessage").Post(); | ||
|
||
var request = requestBuilder.SetSegment("token", settings.BotToken) | ||
.AddFormParameter("chat_id", settings.ChatId) | ||
.AddFormParameter("parse_mode", "HTML") | ||
.AddFormParameter("parse_mode", "MarkdownV2") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the parser to MarkdownV2
to have the link render properly, as I think the HTML hrefs
are being escaped in HTML
-mode when just added to the message. However, this breaks the SeriesDeleteMessage
as it contains a reserved character -
.
Not quite sure how to handle this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which part of the message? A dash could also be in the series. We could escape the -
, possibly with just \-
, but what about *
and other special characters in markdown? _
could cause issues, especially if there are two in the title.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still need to determine the impact of this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, apologies for the lack of activity here.
I'll try to mess around with reverting back to HTML.
Been unable to find a clean solution.
The problem I had initially with the HTML parser was that the markup would render as raw strings in the message, instead of formatting the message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because HttpUtility.HtmlEncode
is being called on the body text. The message body with the link can't be passed into SendNotification
, the link needs to be passed in separately and then built in the proxy, which is better because it hides that implementation detail from Telegram.cs
public enum MetadataLinkType | ||
{ | ||
None = 0, | ||
[FieldOption(Label = "IMDb")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I add FieldOption
to None
and Trakt
as well, where the Enum key aligns with the Label?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think leaving them off as fine as long as the UI is rendering them correctly.
This reverts commit 4e8dbe7.
Thanks for the thorough review @markus101 ! I've cleaned up stuff, and it's a lot more readable now, so thanks for that! 🔥 How can I have |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work on the clean up, much easier to review now, left some more comments and questions.
@@ -35,13 +35,13 @@ public TelegramProxy(IHttpClient httpClient, ILocalizationService localizationSe | |||
public void SendNotification(string title, string message, 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 = $"*{HttpUtility.HtmlEncode(title)}*\n{HttpUtility.HtmlEncode(message)}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this isn't sending HTML, do we still need to encode it for HTML?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should send HTML still, this works when the link is passed in:
var text = new StringBuilder($"<b>{HttpUtility.HtmlEncode(title)}</b>\n");
if (link.IsNullOrWhiteSpace())
{
text.Append($"{{HttpUtility.HtmlEncode(message)}}");
}
else
{
text.Append($"<a href=\"{link}\">{HttpUtility.HtmlEncode(message)}</a>");
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For test notifications something like the following inside Test
:
var link = settings.MetadataLink == (int)MetadataLinkType.None ? null : "https://sonarr.tv";
SendNotification(settings.IncludeAppNameInTitle ? brandedTitle : title, body, link, settings);
This would allow people to see that the link works.
@@ -32,9 +39,27 @@ public class TelegramSettings : IProviderConfig | |||
[FieldDefinition(3, Label = "NotificationsTelegramSettingsSendSilently", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsSendSilentlyHelpText")] | |||
public bool SendSilently { get; set; } | |||
|
|||
public bool SendMetadataLink { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still needs to be removed.
public enum MetadataLinkType | ||
{ | ||
None = 0, | ||
[FieldOption(Label = "IMDb")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think leaving them off as fine as long as the UI is rendering them correctly.
|
||
var requestBuilder = new HttpRequestBuilder(URL).Resource("bot{token}/sendmessage").Post(); | ||
|
||
var request = requestBuilder.SetSegment("token", settings.BotToken) | ||
.AddFormParameter("chat_id", settings.ChatId) | ||
.AddFormParameter("parse_mode", "HTML") | ||
.AddFormParameter("parse_mode", "MarkdownV2") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which part of the message? A dash could also be in the series. We could escape the -
, possibly with just \-
, but what about *
and other special characters in markdown? _
could cause issues, especially if there are two in the title.
Co-authored-by: Mark McDowall <markus.mcd5@gmail.com>
Co-authored-by: Mark McDowall <markus.mcd5@gmail.com>
Co-authored-by: Mark McDowall <markus.mcd5@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested this locally and added some additional comments and suggestions on how to make this functional.
I do wonder if a slightly different approach would be better, where individual links are added for each selected Metadata type, instead of turning the body of the message into a single link.
Let me know what you think about that and whether you'll be able to pick up the rest of the fixes here.
"NotificationsTelegramSettingsSendMetadataLink": "Add a link to the series metadata", | ||
"NotificationsTelegramSettingsSendMetadataLinkHelpText": "Add a link to the series metadata when sending the notifications", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"NotificationsTelegramSettingsSendMetadataLink": "Add a link to the series metadata", | |
"NotificationsTelegramSettingsSendMetadataLinkHelpText": "Add a link to the series metadata when sending the notifications", | |
"NotificationsTelegramSettingsMetadataLink": "MetadataLink", | |
"NotificationsTelegramSettingsMetadataLinkHelpText": "Add a link to the series metadata when sending notifications", |
@@ -33,12 +34,16 @@ public override void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage) | |||
|
|||
public override void OnSeriesAdd(SeriesAddMessage message) | |||
{ | |||
_proxy.SendNotification(SERIES_ADDED_TITLE, message.Message, Settings); | |||
var text = FormatMessageWithLink(message.Message, message.Series); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These links should also be included for OnGrab
, OnDownload
and OnEpisodeFileDelete
|
||
var requestBuilder = new HttpRequestBuilder(URL).Resource("bot{token}/sendmessage").Post(); | ||
|
||
var request = requestBuilder.SetSegment("token", settings.BotToken) | ||
.AddFormParameter("chat_id", settings.ChatId) | ||
.AddFormParameter("parse_mode", "HTML") | ||
.AddFormParameter("parse_mode", "MarkdownV2") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because HttpUtility.HtmlEncode
is being called on the body text. The message body with the link can't be passed into SendNotification
, the link needs to be passed in separately and then built in the proxy, which is better because it hides that implementation detail from Telegram.cs
@@ -32,9 +39,27 @@ public class TelegramSettings : IProviderConfig | |||
[FieldDefinition(3, Label = "NotificationsTelegramSettingsSendSilently", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsSendSilentlyHelpText")] | |||
public bool SendSilently { get; set; } | |||
|
|||
public bool SendMetadataLink { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still needs to be removed.
@@ -32,9 +39,27 @@ public class TelegramSettings : IProviderConfig | |||
[FieldDefinition(3, Label = "NotificationsTelegramSettingsSendSilently", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsSendSilentlyHelpText")] | |||
public bool SendSilently { get; set; } | |||
|
|||
public bool SendMetadataLink { get; set; } | |||
[FieldDefinition(4, Label = "NotificationsTelegramSettingsMetadataLinkType", Type = FieldType.Select, SelectOptions = typeof(MetadataLinkType), HelpText = "NotificationsTelegramSettingsMetadataLinkType")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[FieldDefinition(4, Label = "NotificationsTelegramSettingsMetadataLinkType", Type = FieldType.Select, SelectOptions = typeof(MetadataLinkType), HelpText = "NotificationsTelegramSettingsMetadataLinkType")] | |
[FieldDefinition(4, Label = "NotificationsTelegramSettingsMetadataLink", Type = FieldType.Select, SelectOptions = typeof(MetadataLinkType), HelpText = "NotificationsTelegramSettingsMetadataLink")] |
@@ -32,9 +39,27 @@ public class TelegramSettings : IProviderConfig | |||
[FieldDefinition(3, Label = "NotificationsTelegramSettingsSendSilently", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsSendSilentlyHelpText")] | |||
public bool SendSilently { get; set; } | |||
|
|||
public bool SendMetadataLink { get; set; } | |||
[FieldDefinition(4, Label = "NotificationsTelegramSettingsMetadataLinkType", Type = FieldType.Select, SelectOptions = typeof(MetadataLinkType), HelpText = "NotificationsTelegramSettingsMetadataLinkType")] | |||
public MetadataLinkType MetadataLinkType { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public MetadataLinkType MetadataLinkType { get; set; } | |
public int MetadataLink { get; set; } |
@@ -69,5 +74,37 @@ public override ValidationResult Test() | |||
|
|||
return new ValidationResult(failures); | |||
} | |||
|
|||
private string FormatMessageWithLink(string message, Series series) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be renamed to GetLink
and just return the link, which gets passed to SendNotification
and the message is formatted there.
@@ -35,13 +35,13 @@ public TelegramProxy(IHttpClient httpClient, ILocalizationService localizationSe | |||
public void SendNotification(string title, string message, 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 = $"*{HttpUtility.HtmlEncode(title)}*\n{HttpUtility.HtmlEncode(message)}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should send HTML still, this works when the link is passed in:
var text = new StringBuilder($"<b>{HttpUtility.HtmlEncode(title)}</b>\n");
if (link.IsNullOrWhiteSpace())
{
text.Append($"{{HttpUtility.HtmlEncode(message)}}");
}
else
{
text.Append($"<a href=\"{link}\">{HttpUtility.HtmlEncode(message)}</a>");
}
@@ -35,13 +35,13 @@ public TelegramProxy(IHttpClient httpClient, ILocalizationService localizationSe | |||
public void SendNotification(string title, string message, 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 = $"*{HttpUtility.HtmlEncode(title)}*\n{HttpUtility.HtmlEncode(message)}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For test notifications something like the following inside Test
:
var link = settings.MetadataLink == (int)MetadataLinkType.None ? null : "https://sonarr.tv";
SendNotification(settings.IncludeAppNameInTitle ? brandedTitle : title, body, link, settings);
This would allow people to see that the link works.
Hey! I'll have a look at this sometime this week! |
Description
Adds a checkbox and a dropdown allowing you to select whether to add a clickable link to your Telegram notification, and which database you want a link to.
Questions:
None
orDisabled
-option instead? Probably easier to reason about for the user.I'd appreciate some input on wording. The setting-labels are not very enlightening at the moment.
Screenshots for UI Changes
Issues Fixed or Closed by this PR