diff --git a/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs b/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs index 3932801a6..d3ccf6e80 100644 --- a/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs +++ b/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Text; using FluentValidation.Results; using NLog; +using NzbDrone.Core.MediaCover; using NzbDrone.Core.Movies; namespace NzbDrone.Core.Notifications.Gotify @@ -20,39 +23,39 @@ namespace NzbDrone.Core.Notifications.Gotify public override string Name => "Gotify"; public override string Link => "https://gotify.net/"; - public override void OnGrab(GrabMessage grabMessage) + public override void OnGrab(GrabMessage message) { - _proxy.SendNotification(MOVIE_GRABBED_TITLE, grabMessage.Message, Settings); + SendNotification(MOVIE_GRABBED_TITLE, message.Message, message.Movie); } public override void OnDownload(DownloadMessage message) { - _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, Settings); + SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, message.Movie); } public override void OnMovieAdded(Movie movie) { - _proxy.SendNotification(MOVIE_ADDED_TITLE, $"{movie.Title} added to library", Settings); + SendNotification(MOVIE_ADDED_TITLE, $"{movie.Title} added to library", movie); } public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) { - _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings); + SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, deleteMessage.Movie); } public override void OnMovieDelete(MovieDeleteMessage deleteMessage) { - _proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings); + SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, deleteMessage.Movie); } public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { - _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); + SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, null); } - public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) + public override void OnApplicationUpdate(ApplicationUpdateMessage message) { - _proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings); + SendNotification(APPLICATION_UPDATE_TITLE, message.Message, null); } public override ValidationResult Test() @@ -61,10 +64,29 @@ namespace NzbDrone.Core.Notifications.Gotify try { + var isMarkdown = false; const string title = "Test Notification"; - const string body = "This is a test message from Radarr"; - _proxy.SendNotification(title, body, Settings); + var sb = new StringBuilder(); + sb.AppendLine("This is a test message from Radarr"); + + if (Settings.IncludeMoviePoster) + { + isMarkdown = true; + + sb.AppendLine("\r![](https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/128.png)"); + } + + var payload = new GotifyMessage + { + Title = title, + Message = sb.ToString(), + Priority = Settings.Priority + }; + + payload.SetContentType(isMarkdown); + + _proxy.SendNotification(payload, Settings); } catch (Exception ex) { @@ -74,5 +96,35 @@ namespace NzbDrone.Core.Notifications.Gotify return new ValidationResult(failures); } + + private void SendNotification(string title, string message, Movie movie) + { + var isMarkdown = false; + var sb = new StringBuilder(); + + sb.AppendLine(message); + + if (Settings.IncludeMoviePoster && movie != null) + { + var poster = movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.Url; + + if (poster != null) + { + isMarkdown = true; + sb.AppendLine($"\r![]({poster})"); + } + } + + var payload = new GotifyMessage + { + Title = title, + Message = sb.ToString(), + Priority = Settings.Priority + }; + + payload.SetContentType(isMarkdown); + + _proxy.SendNotification(payload, Settings); + } } } diff --git a/src/NzbDrone.Core/Notifications/Gotify/GotifyMessage.cs b/src/NzbDrone.Core/Notifications/Gotify/GotifyMessage.cs new file mode 100644 index 000000000..170ce1367 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Gotify/GotifyMessage.cs @@ -0,0 +1,40 @@ +using Newtonsoft.Json; + +namespace NzbDrone.Core.Notifications.Gotify +{ + public class GotifyMessage + { + public string Title { get; set; } + public string Message { get; set; } + public int Priority { get; set; } + public GotifyExtras Extras { get; set; } + + public GotifyMessage() + { + Extras = new GotifyExtras(); + } + + public void SetContentType(bool isMarkdown) + { + var contentType = isMarkdown ? "text/markdown" : "text/plain"; + + Extras.ClientDisplay = new GotifyClientDisplay(contentType); + } + } + + public class GotifyExtras + { + [JsonProperty("client::display")] + public GotifyClientDisplay ClientDisplay { get; set; } + } + + public class GotifyClientDisplay + { + public string ContentType { get; set; } + + public GotifyClientDisplay(string contentType) + { + ContentType = contentType; + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs b/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs index 16c5de217..cbdd660d0 100644 --- a/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs +++ b/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs @@ -1,11 +1,12 @@ using System.Net; using NzbDrone.Common.Http; +using NzbDrone.Common.Serializer; namespace NzbDrone.Core.Notifications.Gotify { public interface IGotifyProxy { - void SendNotification(string title, string message, GotifySettings settings); + void SendNotification(GotifyMessage payload, GotifySettings settings); } public class GotifyProxy : IGotifyProxy @@ -17,16 +18,20 @@ namespace NzbDrone.Core.Notifications.Gotify _httpClient = httpClient; } - public void SendNotification(string title, string message, GotifySettings settings) + public void SendNotification(GotifyMessage payload, GotifySettings settings) { try { - var request = new HttpRequestBuilder(settings.Server).Resource("message").Post() - .AddQueryParam("token", settings.AppToken) - .AddFormParameter("title", title) - .AddFormParameter("message", message) - .AddFormParameter("priority", settings.Priority) - .Build(); + var request = new HttpRequestBuilder(settings.Server) + .Resource("message") + .Post() + .AddQueryParam("token", settings.AppToken) + .Build(); + + request.Headers.ContentType = "application/json"; + + var json = payload.ToJson(); + request.SetContent(payload.ToJson()); _httpClient.Execute(request); } diff --git a/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs b/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs index 7c5021e58..dc84de665 100644 --- a/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs +++ b/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs @@ -32,6 +32,9 @@ namespace NzbDrone.Core.Notifications.Gotify [FieldDefinition(2, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(GotifyPriority), HelpText = "Priority of the notification")] public int Priority { get; set; } + [FieldDefinition(3, Label = "Include Movie Poster", Type = FieldType.Checkbox, HelpText = "Include movie poster in message")] + public bool IncludeMoviePoster { get; set; } + public NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this));