feat: add ntfy

This commit is contained in:
gaetansnl 2022-07-27 09:08:33 +02:00
parent c3284bc70a
commit 43a1b24599
25 changed files with 492 additions and 5 deletions

View file

@ -0,0 +1,8 @@
using Ombi.Api.Ntfy.Models;
namespace Ombi.Api.Ntfy;
public interface INtfyApi
{
Task PushAsync(string endpoint, string authorizationHeader, NtfyNotificationBody body);
}

View file

@ -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; }
}

View file

@ -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);
}
}

View file

@ -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>

View file

@ -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; }
}
}

View file

@ -69,6 +69,7 @@ using Ombi.Api.CloudService;
using Ombi.Api.RottenTomatoes;
using System.Net.Http;
using Microsoft.Extensions.Logging;
using Ombi.Api.Ntfy;
using Ombi.Core.Services;
using Ombi.Core.Helpers;
@ -159,6 +160,7 @@ namespace Ombi.DependencyInjection
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>();
@ -223,6 +225,7 @@ namespace Ombi.DependencyInjection
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>();

View file

@ -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" />

View file

@ -37,6 +37,7 @@ namespace Ombi.Helpers
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);

View file

@ -12,6 +12,7 @@
Mobile = 7,
Gotify = 8,
Webhook = 9,
WhatsApp = 10
WhatsApp = 10,
Ntfy = 11
}
}

View file

@ -20,6 +20,7 @@ namespace Ombi.Mapping.Profiles
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();

View file

@ -25,8 +25,8 @@ namespace Ombi.Notifications.Tests
[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));
}
}

View file

@ -0,0 +1,6 @@
namespace Ombi.Notifications.Agents
{
public interface INtfyNotification : INotification
{
}
}

View file

@ -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);
}
}
}

View file

@ -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" />

View file

@ -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;
}
}

View file

@ -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
@ -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
@ -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}

View file

@ -35,7 +35,8 @@ export enum NotificationAgent {
Mattermost = 6,
Mobile = 7,
Gotify = 8,
WhatsApp = 9
WhatsApp = 9,
Ntfy = 10
}
export enum NotificationType {
@ -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;

View file

@ -13,6 +13,7 @@ import {
IEmbyServer,
IJellyfinServer,
IGotifyNotificationSettings,
INtfyNotificationSettings,
ILidarrSettings,
IMattermostNotifcationSettings,
IMobileNotificationTestSettings,
@ -52,6 +53,10 @@ export class TesterService extends ServiceHelpers {
return this.http.post<boolean>(`${this.url}gotify`, JSON.stringify(settings), { headers: this.headers });
}
public ntfyTest(settings: INtfyNotificationSettings): Observable<boolean> {
return this.http.post<boolean>(`${this.url}ntfy`, JSON.stringify(settings), { headers: this.headers });
}
public webhookTest(settings: IWebhookNotificationSettings): Observable<boolean> {
return this.http.post<boolean>(`${this.url}webhook`, JSON.stringify(settings), { headers: this.headers });
}

View file

@ -16,6 +16,7 @@ import {
IEmbySettings,
IJellyfinSettings,
IGotifyNotificationSettings,
INtfyNotificationSettings,
IIssueSettings,
IJobSettings,
IJobSettingsViewModel,
@ -204,6 +205,14 @@ export class SettingsService extends ServiceHelpers {
.post<boolean>(`${this.url}/notifications/gotify`, JSON.stringify(settings), { headers: this.headers });
}
public getNtfyNotificationSettings(): Observable<INtfyNotificationSettings> {
return this.http.get<INtfyNotificationSettings>(`${this.url}/notifications/ntfy`, { headers: this.headers });
}
public saveNtfyNotificationSettings(settings: INtfyNotificationSettings): Observable<boolean> {
return this.http
.post<boolean>(`${this.url}/notifications/ntfy`, JSON.stringify(settings), { headers: this.headers });
}
public getWebhookNotificationSettings(): Observable<IWebhookNotificationSettings> {
return this.http.get<IWebhookNotificationSettings>(`${this.url}/notifications/webhook`, { headers: this.headers });
}

View file

@ -0,0 +1,74 @@
<settings-menu></settings-menu>
<div *ngIf="form" class="small-middle-container">
<fieldset>
<legend>Ntfy Notifications</legend>
<div class="col-md-6">
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="enable" formControlName="enabled">
<label for="enable">Enabled</label>
</div>
</div>
<div class="form-group">
<label for="baseUrl" class="control-label">Base URL</label>
<input type="text" class="form-control form-control-custom " id="baseUrl" name="baseUrl" [ngClass]="{'form-error': form.get('baseUrl').hasError('required')}" formControlName="baseUrl" pTooltip="Enter the URL of your ntfy server.">
<small *ngIf="form.get('baseUrl').hasError('required')" class="error-text">The Base URL is required</small>
</div>
<div class="form-group">
<label for="authorizationHeader" class="control-label">Authorization Header</label>
<input type="text" class="form-control form-control-custom " id="authorizationHeader" name="authorizationHeader" [ngClass]="{'form-error': form.get('authorizationHeader').hasError('required')}" formControlName="authorizationHeader" pTooltip="Enter your Authorization header from Ntfy.">
<small *ngIf="form.get('authorizationHeader').hasError('required')" class="error-text">The Authorization Header is required</small>
</div>
<div class="form-group">
<label for="topic" class="control-label">Topic</label>
<input type="text" class="form-control form-control-custom " id="topic" name="topic" [ngClass]="{'form-error': form.get('topic').hasError('required')}" formControlName="topic" pTooltip="Enter your topic from Ntfy.">
<small *ngIf="form.get('topic').hasError('required')" class="error-text">The Topic is required</small>
</div>
<div class="form-group">
<label for="priority" class="control-label">Priority</label>
<div>
<select class="form-control form-control-custom " id="priority" name="priority" formControlName="priority" pTooltip="The priority you want your ntfy notifications sent as.">
<option value="4">Normal</option>
<option value="8">High</option>
<option value="2">Low</option>
<option value="0">Lowest</option>
</select>
</div>
</div>
<div class="form-group">
<div>
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="test(form)" class="btn btn-primary-outline">
Test
<div id="spinner"></div>
</button>
</div>
</div>
<div class="form-group">
<div>
<button [disabled]="form.invalid" mat-raised-button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
</div>
</div>
</form>
</div>
<div class="col-md-6">
<notification-templates [templates]="templates" [showSubject]="false"></notification-templates>
</div>
</fieldset>
</div>

View file

@ -0,0 +1,70 @@
import { Component, OnInit } from "@angular/core";
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { INtfyNotificationSettings, INotificationTemplates, NotificationType } from "../../interfaces";
import { TesterService } from "../../services";
import { NotificationService } from "../../services";
import { SettingsService } from "../../services";
@Component({
templateUrl: "./ntfy.component.html",
styleUrls: ["./notificationtemplate.component.scss"]
})
export class NtfyComponent implements OnInit {
public NotificationType = NotificationType;
public templates: INotificationTemplates[];
public form: UntypedFormGroup;
constructor(private settingsService: SettingsService,
private notificationService: NotificationService,
private fb: UntypedFormBuilder,
private testerService: TesterService) { }
public ngOnInit() {
this.settingsService.getNtfyNotificationSettings().subscribe(x => {
this.templates = x.notificationTemplates;
this.form = this.fb.group({
enabled: [x.enabled],
baseUrl: [x.baseUrl, [Validators.required]],
authorizationHeader: [x.authorizationHeader, []],
topic: [x.topic, [Validators.required]],
priority: [x.priority],
});
});
}
public onSubmit(form: UntypedFormGroup) {
if (form.invalid) {
this.notificationService.error("Please check your entered values");
return;
}
const settings = <INtfyNotificationSettings> form.value;
settings.notificationTemplates = this.templates;
this.settingsService.saveNtfyNotificationSettings(settings).subscribe(x => {
if (x) {
this.notificationService.success("Successfully saved the Ntfy settings");
} else {
this.notificationService.success("There was an error when saving the Ntfy settings");
}
});
}
public test(form: UntypedFormGroup) {
if (form.invalid) {
this.notificationService.error("Please check your entered values");
return;
}
this.testerService.ntfyTest(form.value).subscribe(x => {
if (x) {
this.notificationService.success("Successfully sent a Ntfy message");
} else {
this.notificationService.error("There was an error when sending the Ntfy message. Please check your settings");
}
});
}
}

View file

@ -40,6 +40,7 @@ import { EmbyComponent } from "./emby/emby.component";
import { FailedRequestsComponent } from "./failedrequests/failedrequests.component";
import { FeaturesComponent } from "./features/features.component";
import { GotifyComponent } from "./notifications/gotify.component";
import { NtfyComponent } from "./notifications/ntfy.component";
import { HubService } from "../services/hub.service";
import {InputSwitchModule} from "primeng/inputswitch";
import {InputTextModule} from "primeng/inputtext";
@ -100,6 +101,7 @@ const routes: Routes = [
{ path: "Pushover", component: PushoverComponent, canActivate: [AuthGuard] },
{ path: "Pushbullet", component: PushbulletComponent, canActivate: [AuthGuard] },
{ path: "Gotify", component: GotifyComponent, canActivate: [AuthGuard] },
{ path: "Ntfy", component: NtfyComponent, canActivate: [AuthGuard] },
{ path: "Webhook", component: WebhookComponent, canActivate: [AuthGuard] },
{ path: "Mattermost", component: MattermostComponent, canActivate: [AuthGuard] },
{ path: "Twilio", component: TwilioComponent, canActivate: [AuthGuard] },
@ -165,6 +167,7 @@ const routes: Routes = [
MattermostComponent,
PushbulletComponent,
GotifyComponent,
NtfyComponent,
WebhookComponent,
UserManagementComponent,
UpdateComponent,

View file

@ -52,6 +52,7 @@
<button mat-menu-item [routerLink]="['/Settings/Mattermost']"><i class="far fa-comments icon-spacing"></i> Mattermost</button>
<button mat-menu-item [routerLink]="['/Settings/Telegram']"><i class="fab fa-telegram icon-spacing"></i> Telegram</button>
<button mat-menu-item [routerLink]="['/Settings/Gotify']"><i class="fas fa-comments icon-spacing"></i> Gotify</button>
<button mat-menu-item [routerLink]="['/Settings/Ntfy']"><i class="fas fa-comments icon-spacing"></i> Ntfy</button>
<button mat-menu-item [routerLink]="['/Settings/Twilio']"><i class="fas fa-sms icon-spacing"></i> Twilio</button>
<button mat-menu-item [routerLink]="['/Settings/Webhook']"><i class="fas fa-sync icon-spacing"></i> Webhook</button>
</mat-menu>

View file

@ -48,7 +48,7 @@ namespace Ombi.Controllers.V1.External
IPushbulletNotification pushbullet, ISlackNotification slack, IPushoverNotification po, IMattermostNotification mm,
IPlexApi plex, IEmbyApiFactory emby, IRadarrV3Api radarr, ISonarrApi sonarr, ILogger<TesterController> log, IEmailProvider provider,
ICouchPotatoApi cpApi, ITelegramNotification telegram, ISickRageApi srApi, INewsletterJob newsletter, ILegacyMobileNotification mobileNotification,
ILidarrApi lidarrApi, IGotifyNotification gotifyNotification, IWhatsAppApi whatsAppApi, OmbiUserManager um, IWebhookNotification webhookNotification,
ILidarrApi lidarrApi, IGotifyNotification gotifyNotification,INtfyNotification ntfyNotification, IWhatsAppApi whatsAppApi, OmbiUserManager um, IWebhookNotification webhookNotification,
IJellyfinApi jellyfinApi, IPrincipal user)
{
Service = service;
@ -71,6 +71,7 @@ namespace Ombi.Controllers.V1.External
MobileNotification = mobileNotification;
LidarrApi = lidarrApi;
GotifyNotification = gotifyNotification;
NtfyNotification = ntfyNotification;
WhatsAppApi = whatsAppApi;
UserManager = um;
WebhookNotification = webhookNotification;
@ -85,6 +86,7 @@ namespace Ombi.Controllers.V1.External
private ISlackNotification SlackNotification { get; }
private IPushoverNotification PushoverNotification { get; }
private IGotifyNotification GotifyNotification { get; }
private INtfyNotification NtfyNotification { get; }
private IWebhookNotification WebhookNotification { get; }
private IMattermostNotification MattermostNotification { get; }
private IPlexApi PlexApi { get; }
@ -198,6 +200,31 @@ namespace Ombi.Controllers.V1.External
}
}
/// <summary>
/// Sends a test message to Ntfy using the provided settings
/// </summary>
/// <param name="settings">The settings.</param>
/// <returns></returns>
[HttpPost("ntfy")]
public bool Ntfy([FromBody] NtfySettings settings)
{
try
{
settings.Enabled = true;
NtfyNotification.NotifyAsync(
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true;
}
catch (Exception e)
{
Log.LogError(LoggingEvents.Api, e, "Could not test Ntfy");
return false;
}
}
/// <summary>
/// Sends a test message to configured webhook using the provided settings

View file

@ -1140,6 +1140,40 @@ namespace Ombi.Controllers.V1
return model;
}
/// <summary>
/// Saves the ntfy notification settings.
/// </summary>
/// <param name="model">The model.</param>
/// <returns></returns>
[HttpPost("notifications/ntfy")]
public async Task<bool> NtfyNotificationSettings([FromBody] NtfyNotificationViewModel model)
{
// Save the email settings
var settings = Mapper.Map<NtfySettings>(model);
var result = await Save(settings);
// Save the templates
await TemplateRepository.UpdateRange(model.NotificationTemplates);
return result;
}
/// <summary>
/// Gets the ntfy Notification Settings.
/// </summary>
/// <returns></returns>
[HttpGet("notifications/ntfy")]
public async Task<NtfyNotificationViewModel> NtfyNotificationSettings()
{
var settings = await Get<NtfySettings>();
var model = Mapper.Map<NtfyNotificationViewModel>(settings);
// Lookup to see if we have any templates saved
model.NotificationTemplates = BuildTemplates(NotificationAgent.Ntfy);
return model;
}
/// <summary>
/// Saves the webhook notification settings.