Fixed: Sending Manual Interaction Required notifications for unknown series

For Discord/Slack/Webhooks/CustomScript
This commit is contained in:
Bogdan 2024-07-19 18:46:09 +03:00
parent 80ca1a6ac2
commit 2ebf89a6ab
4 changed files with 135 additions and 108 deletions

View File

@ -406,18 +406,18 @@ namespace NzbDrone.Core.Notifications.CustomScript
environmentVariables.Add("Sonarr_EventType", "ManualInteractionRequired"); environmentVariables.Add("Sonarr_EventType", "ManualInteractionRequired");
environmentVariables.Add("Sonarr_InstanceName", _configFileProvider.InstanceName); environmentVariables.Add("Sonarr_InstanceName", _configFileProvider.InstanceName);
environmentVariables.Add("Sonarr_ApplicationUrl", _configService.ApplicationUrl); environmentVariables.Add("Sonarr_ApplicationUrl", _configService.ApplicationUrl);
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString()); environmentVariables.Add("Sonarr_Series_Id", series?.Id.ToString());
environmentVariables.Add("Sonarr_Series_Title", series.Title); environmentVariables.Add("Sonarr_Series_Title", series?.Title);
environmentVariables.Add("Sonarr_Series_TitleSlug", series.TitleSlug); environmentVariables.Add("Sonarr_Series_TitleSlug", series?.TitleSlug);
environmentVariables.Add("Sonarr_Series_Path", series.Path); environmentVariables.Add("Sonarr_Series_Path", series?.Path);
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString()); environmentVariables.Add("Sonarr_Series_TvdbId", series?.TvdbId.ToString());
environmentVariables.Add("Sonarr_Series_TvMazeId", series.TvMazeId.ToString()); environmentVariables.Add("Sonarr_Series_TvMazeId", series?.TvMazeId.ToString());
environmentVariables.Add("Sonarr_Series_TmdbId", series.TmdbId.ToString()); environmentVariables.Add("Sonarr_Series_TmdbId", series?.TmdbId.ToString());
environmentVariables.Add("Sonarr_Series_ImdbId", series.ImdbId ?? string.Empty); environmentVariables.Add("Sonarr_Series_ImdbId", series?.ImdbId ?? string.Empty);
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString()); environmentVariables.Add("Sonarr_Series_Type", series?.SeriesType.ToString());
environmentVariables.Add("Sonarr_Series_Year", series.Year.ToString()); environmentVariables.Add("Sonarr_Series_Year", series?.Year.ToString());
environmentVariables.Add("Sonarr_Series_OriginalLanguage", IsoLanguages.Get(series.OriginalLanguage).ThreeLetterCode); environmentVariables.Add("Sonarr_Series_OriginalLanguage", IsoLanguages.Get(series?.OriginalLanguage)?.ThreeLetterCode);
environmentVariables.Add("Sonarr_Series_Genres", string.Join("|", series.Genres)); environmentVariables.Add("Sonarr_Series_Genres", string.Join("|", series?.Genres ?? new List<string>()));
environmentVariables.Add("Sonarr_Series_Tags", string.Join("|", GetTagLabels(series))); environmentVariables.Add("Sonarr_Series_Tags", string.Join("|", GetTagLabels(series)));
environmentVariables.Add("Sonarr_Download_Client", message.DownloadClientInfo?.Name ?? string.Empty); environmentVariables.Add("Sonarr_Download_Client", message.DownloadClientInfo?.Name ?? string.Empty);
environmentVariables.Add("Sonarr_Download_Client_Type", message.DownloadClientInfo?.Type ?? string.Empty); environmentVariables.Add("Sonarr_Download_Client_Type", message.DownloadClientInfo?.Type ?? string.Empty);
@ -482,6 +482,11 @@ namespace NzbDrone.Core.Notifications.CustomScript
private List<string> GetTagLabels(Series series) private List<string> GetTagLabels(Series series)
{ {
if (series == null)
{
return null;
}
return _tagRepository.GetTags(series.Tags) return _tagRepository.GetTags(series.Tags)
.Select(s => s.Label) .Select(s => s.Label)
.Where(l => l.IsNotNullOrWhiteSpace()) .Where(l => l.IsNotNullOrWhiteSpace())

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using FluentValidation.Results; using FluentValidation.Results;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
@ -329,12 +330,12 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnRename(Series series, List<RenamedEpisodeFile> renamedFiles) public override void OnRename(Series series, List<RenamedEpisodeFile> renamedFiles)
{ {
var attachments = new List<Embed> var attachments = new List<Embed>
{ {
new Embed new ()
{ {
Title = series.Title, Title = series.Title,
} }
}; };
var payload = CreatePayload("Renamed", attachments); var payload = CreatePayload("Renamed", attachments);
@ -361,8 +362,8 @@ namespace NzbDrone.Core.Notifications.Discord
Color = (int)DiscordColors.Danger, Color = (int)DiscordColors.Danger,
Fields = new List<DiscordField> Fields = new List<DiscordField>
{ {
new DiscordField { Name = "Reason", Value = reason.ToString() }, new () { Name = "Reason", Value = reason.ToString() },
new DiscordField { Name = "File name", Value = string.Format("```{0}```", deletedFile) } new () { Name = "File name", Value = string.Format("```{0}```", deletedFile) }
}, },
Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
}; };
@ -386,7 +387,7 @@ namespace NzbDrone.Core.Notifications.Discord
Title = series.Title, Title = series.Title,
Description = "Series Added", Description = "Series Added",
Color = (int)DiscordColors.Success, Color = (int)DiscordColors.Success,
Fields = new List<DiscordField> { new DiscordField { Name = "Links", Value = GetLinksString(series) } } Fields = new List<DiscordField> { new () { Name = "Links", Value = GetLinksString(series) } }
}; };
if (Settings.ImportFields.Contains((int)DiscordImportFieldType.Poster)) if (Settings.ImportFields.Contains((int)DiscordImportFieldType.Poster))
@ -425,7 +426,7 @@ namespace NzbDrone.Core.Notifications.Discord
Title = series.Title, Title = series.Title,
Description = deleteMessage.DeletedFilesMessage, Description = deleteMessage.DeletedFilesMessage,
Color = (int)DiscordColors.Danger, Color = (int)DiscordColors.Danger,
Fields = new List<DiscordField> { new DiscordField { Name = "Links", Value = GetLinksString(series) } } Fields = new List<DiscordField> { new () { Name = "Links", Value = GetLinksString(series) } }
}; };
if (Settings.ImportFields.Contains((int)DiscordImportFieldType.Poster)) if (Settings.ImportFields.Contains((int)DiscordImportFieldType.Poster))
@ -503,12 +504,12 @@ namespace NzbDrone.Core.Notifications.Discord
Color = (int)DiscordColors.Standard, Color = (int)DiscordColors.Standard,
Fields = new List<DiscordField>() Fields = new List<DiscordField>()
{ {
new DiscordField() new ()
{ {
Name = "Previous Version", Name = "Previous Version",
Value = updateMessage.PreviousVersion.ToString() Value = updateMessage.PreviousVersion.ToString()
}, },
new DiscordField() new ()
{ {
Name = "New Version", Name = "New Version",
Value = updateMessage.NewVersion.ToString() Value = updateMessage.NewVersion.ToString()
@ -533,7 +534,7 @@ namespace NzbDrone.Core.Notifications.Discord
Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author,
IconUrl = "https://raw.githubusercontent.com/Sonarr/Sonarr/develop/Logo/256.png" IconUrl = "https://raw.githubusercontent.com/Sonarr/Sonarr/develop/Logo/256.png"
}, },
Url = $"http://thetvdb.com/?tab=series&id={series.TvdbId}", Url = series?.TvdbId > 0 ? $"http://thetvdb.com/?tab=series&id={series.TvdbId}" : null,
Description = "Manual interaction needed", Description = "Manual interaction needed",
Title = GetTitle(series, episodes), Title = GetTitle(series, episodes),
Color = (int)DiscordColors.Standard, Color = (int)DiscordColors.Standard,
@ -545,7 +546,7 @@ namespace NzbDrone.Core.Notifications.Discord
{ {
embed.Thumbnail = new DiscordImage embed.Thumbnail = new DiscordImage
{ {
Url = series.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.Url Url = series?.Images?.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.Url
}; };
} }
@ -553,7 +554,7 @@ namespace NzbDrone.Core.Notifications.Discord
{ {
embed.Image = new DiscordImage embed.Image = new DiscordImage
{ {
Url = series.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.Url Url = series?.Images?.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.Url
}; };
} }
@ -564,26 +565,26 @@ namespace NzbDrone.Core.Notifications.Discord
switch ((DiscordManualInteractionFieldType)field) switch ((DiscordManualInteractionFieldType)field)
{ {
case DiscordManualInteractionFieldType.Overview: case DiscordManualInteractionFieldType.Overview:
var overview = episodes.First().Overview ?? ""; var overview = episodes.FirstOrDefault()?.Overview ?? "";
discordField.Name = "Overview"; discordField.Name = "Overview";
discordField.Value = overview.Length <= 300 ? overview : $"{overview.AsSpan(0, 300)}..."; discordField.Value = overview.Length <= 300 ? overview : $"{overview.AsSpan(0, 300)}...";
break; break;
case DiscordManualInteractionFieldType.Rating: case DiscordManualInteractionFieldType.Rating:
discordField.Name = "Rating"; discordField.Name = "Rating";
discordField.Value = episodes.First().Ratings.Value.ToString(); discordField.Value = episodes.FirstOrDefault()?.Ratings?.Value.ToString(CultureInfo.InvariantCulture);
break; break;
case DiscordManualInteractionFieldType.Genres: case DiscordManualInteractionFieldType.Genres:
discordField.Name = "Genres"; discordField.Name = "Genres";
discordField.Value = series.Genres.Take(5).Join(", "); discordField.Value = series?.Genres.Take(5).Join(", ");
break; break;
case DiscordManualInteractionFieldType.Quality: case DiscordManualInteractionFieldType.Quality:
discordField.Name = "Quality"; discordField.Name = "Quality";
discordField.Inline = true; discordField.Inline = true;
discordField.Value = message.Quality.Quality.Name; discordField.Value = message.Quality?.Quality?.Name;
break; break;
case DiscordManualInteractionFieldType.Group: case DiscordManualInteractionFieldType.Group:
discordField.Name = "Group"; discordField.Name = "Group";
discordField.Value = message.Episode.ParsedEpisodeInfo.ReleaseGroup; discordField.Value = message.Episode?.ParsedEpisodeInfo?.ReleaseGroup;
break; break;
case DiscordManualInteractionFieldType.Size: case DiscordManualInteractionFieldType.Size:
discordField.Name = "Size"; discordField.Name = "Size";
@ -592,7 +593,7 @@ namespace NzbDrone.Core.Notifications.Discord
break; break;
case DiscordManualInteractionFieldType.DownloadTitle: case DiscordManualInteractionFieldType.DownloadTitle:
discordField.Name = "Download"; discordField.Name = "Download";
discordField.Value = string.Format("```{0}```", message.TrackedDownload.DownloadItem.Title); discordField.Value = $"```{message.TrackedDownload.DownloadItem.Title}```";
break; break;
case DiscordManualInteractionFieldType.Links: case DiscordManualInteractionFieldType.Links:
discordField.Name = "Links"; discordField.Name = "Links";
@ -677,10 +678,16 @@ namespace NzbDrone.Core.Notifications.Discord
private string GetLinksString(Series series) private string GetLinksString(Series series)
{ {
var links = new List<string>(); if (series == null)
{
return null;
}
links.Add($"[The TVDB](https://thetvdb.com/?tab=series&id={series.TvdbId})"); var links = new List<string>
links.Add($"[Trakt](https://trakt.tv/search/tvdb/{series.TvdbId}?id_type=show)"); {
$"[The TVDB](https://thetvdb.com/?tab=series&id={series.TvdbId})",
$"[Trakt](https://trakt.tv/search/tvdb/{series.TvdbId}?id_type=show)"
};
if (series.ImdbId.IsNotNullOrWhiteSpace()) if (series.ImdbId.IsNotNullOrWhiteSpace())
{ {
@ -692,6 +699,11 @@ namespace NzbDrone.Core.Notifications.Discord
private string GetTitle(Series series, List<Episode> episodes) private string GetTitle(Series series, List<Episode> episodes)
{ {
if (series == null)
{
return null;
}
if (series.SeriesType == SeriesTypes.Daily) if (series.SeriesType == SeriesTypes.Daily)
{ {
var episode = episodes.First(); var episode = episodes.First();

View File

@ -28,15 +28,15 @@ namespace NzbDrone.Core.Notifications.Slack
public override void OnGrab(GrabMessage message) public override void OnGrab(GrabMessage message)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Fallback = message.Message, Fallback = message.Message,
Title = message.Series.Title, Title = message.Series.Title,
Text = message.Message, Text = message.Message,
Color = "warning" Color = "warning"
} }
}; };
var payload = CreatePayload($"Grabbed: {message.Message}", attachments); var payload = CreatePayload($"Grabbed: {message.Message}", attachments);
_proxy.SendPayload(payload, Settings); _proxy.SendPayload(payload, Settings);
@ -45,15 +45,15 @@ namespace NzbDrone.Core.Notifications.Slack
public override void OnDownload(DownloadMessage message) public override void OnDownload(DownloadMessage message)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Fallback = message.Message, Fallback = message.Message,
Title = message.Series.Title, Title = message.Series.Title,
Text = message.Message, Text = message.Message,
Color = "good" Color = "good"
} }
}; };
var payload = CreatePayload($"Imported: {message.Message}", attachments); var payload = CreatePayload($"Imported: {message.Message}", attachments);
_proxy.SendPayload(payload, Settings); _proxy.SendPayload(payload, Settings);
@ -63,7 +63,7 @@ namespace NzbDrone.Core.Notifications.Slack
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Fallback = message.Message, Fallback = message.Message,
Title = message.Series.Title, Title = message.Series.Title,
@ -79,12 +79,12 @@ namespace NzbDrone.Core.Notifications.Slack
public override void OnRename(Series series, List<RenamedEpisodeFile> renamedFiles) public override void OnRename(Series series, List<RenamedEpisodeFile> renamedFiles)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Title = series.Title, Title = series.Title,
} }
}; };
var payload = CreatePayload("Renamed", attachments); var payload = CreatePayload("Renamed", attachments);
@ -94,12 +94,12 @@ namespace NzbDrone.Core.Notifications.Slack
public override void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage) public override void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Title = GetTitle(deleteMessage.Series, deleteMessage.EpisodeFile.Episodes), Title = GetTitle(deleteMessage.Series, deleteMessage.EpisodeFile.Episodes),
} }
}; };
var payload = CreatePayload("Episode Deleted", attachments); var payload = CreatePayload("Episode Deleted", attachments);
@ -109,12 +109,12 @@ namespace NzbDrone.Core.Notifications.Slack
public override void OnSeriesAdd(SeriesAddMessage message) public override void OnSeriesAdd(SeriesAddMessage message)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Title = message.Series.Title, Title = message.Series.Title,
} }
}; };
var payload = CreatePayload("Series Added", attachments); var payload = CreatePayload("Series Added", attachments);
@ -124,13 +124,13 @@ namespace NzbDrone.Core.Notifications.Slack
public override void OnSeriesDelete(SeriesDeleteMessage deleteMessage) public override void OnSeriesDelete(SeriesDeleteMessage deleteMessage)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Title = deleteMessage.Series.Title, Title = deleteMessage.Series.Title,
Text = deleteMessage.DeletedFilesMessage Text = deleteMessage.DeletedFilesMessage
} }
}; };
var payload = CreatePayload("Series Deleted", attachments); var payload = CreatePayload("Series Deleted", attachments);
@ -140,14 +140,14 @@ namespace NzbDrone.Core.Notifications.Slack
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Title = healthCheck.Source.Name, Title = healthCheck.Source.Name,
Text = healthCheck.Message, Text = healthCheck.Message,
Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? "warning" : "danger" Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? "warning" : "danger"
} }
}; };
var payload = CreatePayload("Health Issue", attachments); var payload = CreatePayload("Health Issue", attachments);
@ -157,14 +157,14 @@ namespace NzbDrone.Core.Notifications.Slack
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck) public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Title = previousCheck.Source.Name, Title = previousCheck.Source.Name,
Text = $"The following issue is now resolved: {previousCheck.Message}", Text = $"The following issue is now resolved: {previousCheck.Message}",
Color = "good" Color = "good"
} }
}; };
var payload = CreatePayload("Health Issue Resolved", attachments); var payload = CreatePayload("Health Issue Resolved", attachments);
@ -174,14 +174,14 @@ namespace NzbDrone.Core.Notifications.Slack
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Title = Environment.MachineName, Title = Environment.MachineName,
Text = updateMessage.Message, Text = updateMessage.Message,
Color = "good" Color = "good"
} }
}; };
var payload = CreatePayload("Application Updated", attachments); var payload = CreatePayload("Application Updated", attachments);
@ -192,9 +192,9 @@ namespace NzbDrone.Core.Notifications.Slack
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>
{ {
new Attachment new ()
{ {
Title = Environment.MachineName, Title = GetTitle(message.Series, message.Episode.Episodes),
Text = message.Message, Text = message.Message,
Color = "warning" Color = "warning"
} }

View File

@ -229,9 +229,9 @@ namespace NzbDrone.Core.Notifications.Webhook
TvdbId = 1234, TvdbId = 1234,
Tags = new List<string> { "test-tag" } Tags = new List<string> { "test-tag" }
}, },
Episodes = new List<WebhookEpisode>() Episodes = new List<WebhookEpisode>
{ {
new WebhookEpisode() new ()
{ {
Id = 123, Id = 123,
EpisodeNumber = 1, EpisodeNumber = 1,
@ -244,6 +244,11 @@ namespace NzbDrone.Core.Notifications.Webhook
private WebhookSeries GetSeries(Series series) private WebhookSeries GetSeries(Series series)
{ {
if (series == null)
{
return null;
}
_mediaCoverService.ConvertToLocalUrls(series.Id, series.Images); _mediaCoverService.ConvertToLocalUrls(series.Id, series.Images);
return new WebhookSeries(series, GetTagLabels(series)); return new WebhookSeries(series, GetTagLabels(series));
@ -251,6 +256,11 @@ namespace NzbDrone.Core.Notifications.Webhook
private List<string> GetTagLabels(Series series) private List<string> GetTagLabels(Series series)
{ {
if (series == null)
{
return null;
}
return _tagRepository.GetTags(series.Tags) return _tagRepository.GetTags(series.Tags)
.Select(s => s.Label) .Select(s => s.Label)
.Where(l => l.IsNotNullOrWhiteSpace()) .Where(l => l.IsNotNullOrWhiteSpace())