Skip to content

Commit

Permalink
feat: add ntfy
Browse files Browse the repository at this point in the history
  • Loading branch information
gaetansnl committed Jul 30, 2022
1 parent c3284bc commit 43a1b24
Show file tree
Hide file tree
Showing 25 changed files with 492 additions and 5 deletions.
8 changes: 8 additions & 0 deletions src/Ombi.Api.Ntfy/INtfyApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Ombi.Api.Ntfy.Models;

namespace Ombi.Api.Ntfy;

public interface INtfyApi
{
Task PushAsync(string endpoint, string authorizationHeader, NtfyNotificationBody body);
}
21 changes: 21 additions & 0 deletions src/Ombi.Api.Ntfy/Models/NtfyNotificationBody.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Newtonsoft.Json;

namespace Ombi.Api.Ntfy.Models;

public class NtfyNotificationBody
{
[JsonConstructor]
public NtfyNotificationBody()
{
}

public string topic { get; set; }
public string message { get; set; }
public string title { get; set; }
public List<string> tags { get; set; }
public sbyte priority { get; set; }
public string click { get; set; }
public string attach { get; set; }
public string filename { get; set; }
public string delay { get; set; }
}
26 changes: 26 additions & 0 deletions src/Ombi.Api.Ntfy/NtfyApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Ombi.Api.Ntfy.Models;

namespace Ombi.Api.Ntfy;

public class NtfyApi: INtfyApi
{
public NtfyApi(IApi api)
{
_api = api;
}

private readonly IApi _api;

public async Task PushAsync(string endpoint, string authorizationHeader, NtfyNotificationBody body)
{
var request = new Request("/", endpoint, HttpMethod.Post);
if(!String.IsNullOrEmpty(authorizationHeader)) request.AddHeader("Authorization", authorizationHeader);
request.ApplicationJsonContentType();
request.AddJsonBody(body);

Console.WriteLine(endpoint);
Console.WriteLine(request.JsonBody);

await _api.Request(request);
}
}
13 changes: 13 additions & 0 deletions src/Ombi.Api.Ntfy/Ombi.Api.Ntfy.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
</ItemGroup>

</Project>
23 changes: 23 additions & 0 deletions src/Ombi.Core/Models/UI/NtfyNotificationViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

using System.Collections.Generic;
using Ombi.Settings.Settings.Models.Notifications;
using Ombi.Store.Entities;

namespace Ombi.Core.Models.UI
{
/// <summary>
/// The view model for the notification settings page
/// </summary>
/// <seealso cref="NtfyNotificationViewModel" />
public class NtfyNotificationViewModel : NtfySettings
{
/// <summary>
/// Gets or sets the notification templates.
/// </summary>
/// <value>
/// The notification templates.
/// </value>
public List<NotificationTemplates> NotificationTemplates { get; set; }

}
}
3 changes: 3 additions & 0 deletions src/Ombi.DependencyInjection/IocExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
using Ombi.Api.RottenTomatoes;
using System.Net.Http;
using Microsoft.Extensions.Logging;
using Ombi.Api.Ntfy;
using Ombi.Core.Services;
using Ombi.Core.Helpers;

Expand Down Expand Up @@ -159,6 +160,7 @@ public static void RegisterApi(this IServiceCollection services)
services.AddTransient<IFanartTvApi, FanartTvApi>();
services.AddTransient<IPushoverApi, PushoverApi>();
services.AddTransient<IGotifyApi, GotifyApi>();
services.AddTransient<INtfyApi, NtfyApi>();
services.AddTransient<IWebhookApi, WebhookApi>();
services.AddTransient<IMattermostApi, MattermostApi>();
services.AddTransient<ICouchPotatoApi, CouchPotatoApi>();
Expand Down Expand Up @@ -223,6 +225,7 @@ public static void RegisterServices(this IServiceCollection services)
services.AddTransient<IMattermostNotification, MattermostNotification>();
services.AddTransient<IPushoverNotification, PushoverNotification>();
services.AddTransient<IGotifyNotification, GotifyNotification>();
services.AddTransient<INtfyNotification, NtfyNotification>();
services.AddTransient<IWebhookNotification, WebhookNotification>();
services.AddTransient<ITelegramNotification, TelegramNotification>();
services.AddTransient<ILegacyMobileNotification, LegacyMobileNotification>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<ProjectReference Include="..\Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj" />
<ProjectReference Include="..\Ombi.Api.MusicBrainz\Ombi.Api.MusicBrainz.csproj" />
<ProjectReference Include="..\Ombi.Api.Notifications\Ombi.Api.Notifications.csproj" />
<ProjectReference Include="..\Ombi.Api.Ntfy\Ombi.Api.Ntfy.csproj" />
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
<ProjectReference Include="..\Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj" />
<ProjectReference Include="..\Ombi.Api.Pushover\Ombi.Api.Pushover.csproj" />
Expand Down
1 change: 1 addition & 0 deletions src/Ombi.Helpers/LoggingEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class LoggingEvents
public static EventId GotifyNotification => new EventId(4007);
public static EventId WhatsApp => new EventId(4008);
public static EventId WebhookNotification => new EventId(4009);
public static EventId NtfyNotification => new EventId(4010);

public static EventId TvSender => new EventId(5000);
public static EventId SonarrSender => new EventId(5001);
Expand Down
3 changes: 2 additions & 1 deletion src/Ombi.Helpers/NotificationAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public enum NotificationAgent
Mobile = 7,
Gotify = 8,
Webhook = 9,
WhatsApp = 10
WhatsApp = 10,
Ntfy = 11
}
}
1 change: 1 addition & 0 deletions src/Ombi.Mapping/Profiles/SettingsProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public SettingsProfile()
CreateMap<MobileNotificationsViewModel, MobileNotificationSettings>().ReverseMap();
CreateMap<NewsletterNotificationViewModel, NewsletterSettings>().ReverseMap();
CreateMap<GotifyNotificationViewModel, GotifySettings>().ReverseMap();
CreateMap<NtfyNotificationViewModel, NtfySettings>().ReverseMap();
CreateMap<WhatsAppSettingsViewModel, WhatsAppSettings>().ReverseMap();
CreateMap<TwilioSettingsViewModel, TwilioSettings>().ReverseMap();
CreateMap<WebhookNotificationViewModel, WebhookSettings>().ReverseMap();
Expand Down
4 changes: 2 additions & 2 deletions src/Ombi.Notifications.Tests/NotificationServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public void Setup()
[Test]
public void PopulateAgentsTests()
{
Assert.That(_subject.Agents, Has.Count.EqualTo(12));
Assert.That(_subject.Agents.DistinctBy(x => x.NotificationName).ToList(), Has.Count.EqualTo(12));
Assert.That(_subject.Agents, Has.Count.EqualTo(13));
Assert.That(_subject.Agents.DistinctBy(x => x.NotificationName).ToList(), Has.Count.EqualTo(13));
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/Ombi.Notifications/Agents/Interfaces/INtfyNotification.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Ombi.Notifications.Agents
{
public interface INtfyNotification : INotification
{
}
}
130 changes: 130 additions & 0 deletions src/Ombi.Notifications/Agents/NtfyNotification.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Ombi.Api.Ntfy;
using Ombi.Api.Ntfy;
using Ombi.Api.Ntfy.Models;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Notifications.Models;
using Ombi.Settings.Settings.Models;
using Ombi.Settings.Settings.Models.Notifications;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using Ombi.Store.Repository.Requests;

namespace Ombi.Notifications.Agents
{
public class NtfyNotification : BaseNotification<NtfySettings>, INtfyNotification
{
public NtfyNotification(INtfyApi api, ISettingsService<NtfySettings> sn, ILogger<NtfyNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t,
ISettingsService<CustomizationSettings> s, IRepository<RequestSubscription> sub, IMusicRequestRepository music,
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um) : base(sn, r, m, t, s, log, sub, music, userPref, um)
{
Api = api;
Logger = log;
}

public override string NotificationName => "NtfyNotification";

private INtfyApi Api { get; }
private ILogger<NtfyNotification> Logger { get; }

protected override bool ValidateConfiguration(NtfySettings settings)
{
return settings.Enabled && !string.IsNullOrEmpty(settings.BaseUrl);
}

protected override async Task NewRequest(NotificationOptions model, NtfySettings settings)
{
await Run(model, settings, NotificationType.NewRequest);
}


protected override async Task NewIssue(NotificationOptions model, NtfySettings settings)
{
await Run(model, settings, NotificationType.Issue);
}

protected override async Task IssueComment(NotificationOptions model, NtfySettings settings)
{
await Run(model, settings, NotificationType.IssueComment);
}

protected override async Task IssueResolved(NotificationOptions model, NtfySettings settings)
{
await Run(model, settings, NotificationType.IssueResolved);
}

protected override async Task AddedToRequestQueue(NotificationOptions model, NtfySettings settings)
{
await Run(model, settings, NotificationType.ItemAddedToFaultQueue);
}

protected override async Task RequestDeclined(NotificationOptions model, NtfySettings settings)
{
await Run(model, settings, NotificationType.RequestDeclined);
}

protected override async Task RequestApproved(NotificationOptions model, NtfySettings settings)
{
await Run(model, settings, NotificationType.RequestApproved);
}

protected override async Task AvailableRequest(NotificationOptions model, NtfySettings settings)
{
await Run(model, settings, NotificationType.RequestAvailable);
}

protected override async Task Send(NotificationMessage model, NtfySettings settings)
{
try
{
await Api.PushAsync(settings.BaseUrl, settings.AuthorizationHeader, new NtfyNotificationBody()
{
topic = settings.Topic, // To change
title = model.Subject,
message = model.Message,
priority = settings.Priority
});
}
catch (Exception e)
{
Logger.LogError(LoggingEvents.NtfyNotification, e, "Failed to send Ntfy notification");
}
}

protected override async Task Test(NotificationOptions model, NtfySettings settings)
{
var message = $"This is a test from Ombi, if you can see this then we have successfully pushed a notification!";
var notification = new NotificationMessage
{
Message = message,
};
await Send(notification, settings);
}

private async Task Run(NotificationOptions model, NtfySettings settings, NotificationType type)
{
var parsed = await LoadTemplate(NotificationAgent.Ntfy, type, model);
if (parsed.Disabled)
{
Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Ntfy}");
return;
}

var notification = new NotificationMessage
{
Message = parsed.Message,
};

await Send(notification, settings);
}

protected override async Task PartiallyAvailable(NotificationOptions model, NtfySettings settings)
{
await Run(model, settings, NotificationType.PartiallyAvailable);
}
}
}
1 change: 1 addition & 0 deletions src/Ombi.Notifications/Ombi.Notifications.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<ProjectReference Include="..\Ombi.Api.CloudService\Ombi.Api.CloudService.csproj" />
<ProjectReference Include="..\Ombi.Api.Discord\Ombi.Api.Discord.csproj" />
<ProjectReference Include="..\Ombi.Api.Gotify\Ombi.Api.Gotify.csproj" />
<ProjectReference Include="..\Ombi.Api.Ntfy\Ombi.Api.Ntfy.csproj" />
<ProjectReference Include="..\Ombi.Api.Webhook\Ombi.Api.Webhook.csproj" />
<ProjectReference Include="..\Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj" />
<ProjectReference Include="..\Ombi.Api.Notifications\Ombi.Api.Notifications.csproj" />
Expand Down
11 changes: 11 additions & 0 deletions src/Ombi.Settings/Settings/Models/Notifications/NtfySettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Ombi.Settings.Settings.Models.Notifications
{
public class NtfySettings : Settings
{
public bool Enabled { get; set; }
public string BaseUrl { get; set; }
public string AuthorizationHeader { get; set; }
public string Topic { get; set; }
public sbyte Priority { get; set; } = 4;
}
}
9 changes: 9 additions & 0 deletions src/Ombi.sln
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.I18n", "Ombi.I18n\Ombi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.MediaServer", "Ombi.Api.MediaServer\Ombi.Api.MediaServer.csproj", "{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Ntfy", "Ombi.Api.Ntfy\Ombi.Api.Ntfy.csproj", "{8E9AD285-C322-45CA-8D7B-6FE4E8E5D580}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -447,6 +449,12 @@ Global
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.NonUiBuild|Any CPU.Build.0 = NonUiBuild|Any CPU
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Release|Any CPU.Build.0 = Release|Any CPU
{8E9AD285-C322-45CA-8D7B-6FE4E8E5D580}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E9AD285-C322-45CA-8D7B-6FE4E8E5D580}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E9AD285-C322-45CA-8D7B-6FE4E8E5D580}.NonUiBuild|Any CPU.ActiveCfg = Debug|Any CPU
{8E9AD285-C322-45CA-8D7B-6FE4E8E5D580}.NonUiBuild|Any CPU.Build.0 = Debug|Any CPU
{8E9AD285-C322-45CA-8D7B-6FE4E8E5D580}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E9AD285-C322-45CA-8D7B-6FE4E8E5D580}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -496,6 +504,7 @@ Global
{5DE40A66-B369-469E-8626-ECE23D9D8034} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{8F19C701-7881-4BC7-8BBA-B068A6B954AD} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{8E9AD285-C322-45CA-8D7B-6FE4E8E5D580} = {9293CA11-360A-4C20-A674-B9E794431BF5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}
Expand Down
11 changes: 10 additions & 1 deletion src/Ombi/ClientApp/src/app/interfaces/INotificationSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export enum NotificationAgent {
Mattermost = 6,
Mobile = 7,
Gotify = 8,
WhatsApp = 9
WhatsApp = 9,
Ntfy = 10
}

export enum NotificationType {
Expand Down Expand Up @@ -120,6 +121,14 @@ export interface IGotifyNotificationSettings extends INotificationSettings {
priority: number;
}

export interface INtfyNotificationSettings extends INotificationSettings {
notificationTemplates: INotificationTemplates[];
baseUrl: string;
authorizationHeader: string;
topic: string;
priority: number;
}

export interface IWebhookNotificationSettings extends INotificationSettings {
webhookUrl: string;
applicationToken: string;
Expand Down
Loading

0 comments on commit 43a1b24

Please sign in to comment.