mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-14 01:02:57 -07:00
Merge pull request #3291 from Namaneo/webhook-notifications
Add custom webhook notifications
This commit is contained in:
commit
f7ce3c36e3
27 changed files with 432 additions and 5 deletions
|
@ -74,6 +74,7 @@ Supported notifications:
|
|||
* Pushover
|
||||
* Mattermost
|
||||
* Telegram
|
||||
* Webhook
|
||||
|
||||
### The difference between Version 3 and 2
|
||||
|
||||
|
|
10
src/Ombi.Api.Webhook/IWebhookApi.cs
Normal file
10
src/Ombi.Api.Webhook/IWebhookApi.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Api.Webhook
|
||||
{
|
||||
public interface IWebhookApi
|
||||
{
|
||||
Task PushAsync(string endpoint, string accessToken, IDictionary<string, string> parameters);
|
||||
}
|
||||
}
|
15
src/Ombi.Api.Webhook/Ombi.Api.Webhook.csproj
Normal file
15
src/Ombi.Api.Webhook/Ombi.Api.Webhook.csproj
Normal file
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<Version></Version>
|
||||
<PackageVersion></PackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
40
src/Ombi.Api.Webhook/WebhookApi.cs
Normal file
40
src/Ombi.Api.Webhook/WebhookApi.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using Newtonsoft.Json.Serialization;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Api.Webhook
|
||||
{
|
||||
public class WebhookApi : IWebhookApi
|
||||
{
|
||||
private static readonly CamelCasePropertyNamesContractResolver _nameResolver = new CamelCasePropertyNamesContractResolver();
|
||||
|
||||
public WebhookApi(IApi api)
|
||||
{
|
||||
_api = api;
|
||||
}
|
||||
|
||||
private readonly IApi _api;
|
||||
|
||||
public async Task PushAsync(string baseUrl, string accessToken, IDictionary<string, string> parameters)
|
||||
{
|
||||
var request = new Request("/", baseUrl, HttpMethod.Post);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(accessToken))
|
||||
{
|
||||
request.AddHeader("Access-Token", accessToken);
|
||||
}
|
||||
|
||||
var body = parameters.ToDictionary(
|
||||
x => _nameResolver.GetResolvedPropertyName(x.Key),
|
||||
x => x.Value
|
||||
);
|
||||
|
||||
request.ApplicationJsonContentType();
|
||||
request.AddJsonBody(body);
|
||||
|
||||
await _api.Request(request);
|
||||
}
|
||||
}
|
||||
}
|
15
src/Ombi.Core/Models/UI/WebhookNotificationViewModel.cs
Normal file
15
src/Ombi.Core/Models/UI/WebhookNotificationViewModel.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
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="WebhookSettings" />
|
||||
public class WebhookNotificationViewModel : WebhookSettings
|
||||
{
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ using Ombi.Api.DogNzb;
|
|||
using Ombi.Api.FanartTv;
|
||||
using Ombi.Api.Github;
|
||||
using Ombi.Api.Gotify;
|
||||
using Ombi.Api.Webhook;
|
||||
using Ombi.Api.Lidarr;
|
||||
using Ombi.Api.Mattermost;
|
||||
using Ombi.Api.Notifications;
|
||||
|
@ -122,6 +123,7 @@ namespace Ombi.DependencyInjection
|
|||
services.AddTransient<IFanartTvApi, FanartTvApi>();
|
||||
services.AddTransient<IPushoverApi, PushoverApi>();
|
||||
services.AddTransient<IGotifyApi, GotifyApi>();
|
||||
services.AddTransient<IWebhookApi, WebhookApi>();
|
||||
services.AddTransient<IMattermostApi, MattermostApi>();
|
||||
services.AddTransient<ICouchPotatoApi, CouchPotatoApi>();
|
||||
services.AddTransient<IDogNzbApi, DogNzbApi>();
|
||||
|
@ -173,6 +175,7 @@ namespace Ombi.DependencyInjection
|
|||
services.AddTransient<IMattermostNotification, MattermostNotification>();
|
||||
services.AddTransient<IPushoverNotification, PushoverNotification>();
|
||||
services.AddTransient<IGotifyNotification, GotifyNotification>();
|
||||
services.AddTransient<IWebhookNotification, WebhookNotification>();
|
||||
services.AddTransient<ITelegramNotification, TelegramNotification>();
|
||||
services.AddTransient<IMobileNotification, MobileNotification>();
|
||||
services.AddTransient<IChangeLogProcessor, ChangeLogProcessor>();
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
<ProjectReference Include="..\Ombi.Api.Telegram\Ombi.Api.Telegram.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.Trakt\Ombi.Api.Trakt.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.Webhook\Ombi.Api.Webhook.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Schedule\Ombi.Schedule.csproj" />
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace Ombi.Helpers
|
|||
public static EventId PushoverNotification => new EventId(4005);
|
||||
public static EventId TelegramNotifcation => new EventId(4006);
|
||||
public static EventId GotifyNotification => new EventId(4007);
|
||||
public static EventId WebhookNotification => new EventId(4008);
|
||||
|
||||
public static EventId TvSender => new EventId(5000);
|
||||
public static EventId SonarrSender => new EventId(5001);
|
||||
|
|
|
@ -11,5 +11,6 @@
|
|||
Mattermost = 6,
|
||||
Mobile = 7,
|
||||
Gotify = 8,
|
||||
Webhook = 9,
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ namespace Ombi.Mapping.Profiles
|
|||
CreateMap<MobileNotificationsViewModel, MobileNotificationSettings>().ReverseMap();
|
||||
CreateMap<NewsletterNotificationViewModel, NewsletterSettings>().ReverseMap();
|
||||
CreateMap<GotifyNotificationViewModel, GotifySettings>().ReverseMap();
|
||||
CreateMap<WebhookNotificationViewModel, WebhookSettings>().ReverseMap();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
namespace Ombi.Notifications.Agents
|
||||
{
|
||||
public interface IWebhookNotification : INotification
|
||||
{
|
||||
}
|
||||
}
|
123
src/Ombi.Notifications/Agents/WebhookNotification.cs
Normal file
123
src/Ombi.Notifications/Agents/WebhookNotification.cs
Normal file
|
@ -0,0 +1,123 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Api.Webhook;
|
||||
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 WebhookNotification : BaseNotification<WebhookSettings>, IWebhookNotification
|
||||
{
|
||||
public WebhookNotification(IWebhookApi api, ISettingsService<WebhookSettings> sn, ILogger<WebhookNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t,
|
||||
ISettingsService<CustomizationSettings> s, IRepository<RequestSubscription> sub, IMusicRequestRepository music,
|
||||
IRepository<UserNotificationPreferences> userPref) : base(sn, r, m, t, s, log, sub, music, userPref)
|
||||
{
|
||||
Api = api;
|
||||
Logger = log;
|
||||
}
|
||||
|
||||
public override string NotificationName => "WebhookNotification";
|
||||
|
||||
private IWebhookApi Api { get; }
|
||||
private ILogger<WebhookNotification> Logger { get; }
|
||||
|
||||
protected override bool ValidateConfiguration(WebhookSettings settings)
|
||||
{
|
||||
return settings.Enabled && !string.IsNullOrEmpty(settings.WebhookUrl);
|
||||
}
|
||||
|
||||
protected override async Task NewRequest(NotificationOptions model, WebhookSettings settings)
|
||||
{
|
||||
await Run(model, settings, NotificationType.NewRequest);
|
||||
}
|
||||
|
||||
|
||||
protected override async Task NewIssue(NotificationOptions model, WebhookSettings settings)
|
||||
{
|
||||
await Run(model, settings, NotificationType.Issue);
|
||||
}
|
||||
|
||||
protected override async Task IssueComment(NotificationOptions model, WebhookSettings settings)
|
||||
{
|
||||
await Run(model, settings, NotificationType.IssueComment);
|
||||
}
|
||||
|
||||
protected override async Task IssueResolved(NotificationOptions model, WebhookSettings settings)
|
||||
{
|
||||
await Run(model, settings, NotificationType.IssueResolved);
|
||||
}
|
||||
|
||||
protected override async Task AddedToRequestQueue(NotificationOptions model, WebhookSettings settings)
|
||||
{
|
||||
await Run(model, settings, NotificationType.ItemAddedToFaultQueue);
|
||||
}
|
||||
|
||||
protected override async Task RequestDeclined(NotificationOptions model, WebhookSettings settings)
|
||||
{
|
||||
await Run(model, settings, NotificationType.RequestDeclined);
|
||||
}
|
||||
|
||||
protected override async Task RequestApproved(NotificationOptions model, WebhookSettings settings)
|
||||
{
|
||||
await Run(model, settings, NotificationType.RequestApproved);
|
||||
}
|
||||
|
||||
protected override async Task AvailableRequest(NotificationOptions model, WebhookSettings settings)
|
||||
{
|
||||
await Run(model, settings, NotificationType.RequestAvailable);
|
||||
}
|
||||
|
||||
protected override async Task Send(NotificationMessage model, WebhookSettings settings)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Api.PushAsync(settings.WebhookUrl, settings.ApplicationToken, model.Data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(LoggingEvents.WebhookNotification, e, "Failed to send webhook notification");
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task Test(NotificationOptions model, WebhookSettings settings)
|
||||
{
|
||||
var c = new NotificationMessageCurlys();
|
||||
|
||||
var testData = c.Curlys.ToDictionary(x => x.Key, x => x.Value);
|
||||
testData[nameof(NotificationType)] = NotificationType.Test.ToString();
|
||||
var notification = new NotificationMessage
|
||||
{
|
||||
Data = testData,
|
||||
};
|
||||
|
||||
await Send(notification, settings);
|
||||
}
|
||||
|
||||
private async Task Run(NotificationOptions model, WebhookSettings settings, NotificationType type)
|
||||
{
|
||||
var parsed = await LoadTemplate(NotificationAgent.Webhook, type, model);
|
||||
if (parsed.Disabled)
|
||||
{
|
||||
Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Webhook}");
|
||||
return;
|
||||
}
|
||||
|
||||
var notificationData = parsed.Data.ToDictionary(x => x.Key, x => x.Value);
|
||||
notificationData[nameof(NotificationType)] = type.ToString();
|
||||
var notification = new NotificationMessage
|
||||
{
|
||||
Data = notificationData,
|
||||
};
|
||||
|
||||
await Send(notification, settings);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,5 +9,6 @@ namespace Ombi.Notifications.Models
|
|||
public string To { get; set; }
|
||||
|
||||
public Dictionary<string, string> Other { get; set; } = new Dictionary<string, string>();
|
||||
public IDictionary<string, string> Data { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
namespace Ombi.Notifications
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Notifications
|
||||
{
|
||||
public class NotificationMessageContent
|
||||
{
|
||||
|
@ -6,5 +8,6 @@
|
|||
public string Subject { get; set; }
|
||||
public string Message { get; set; }
|
||||
public string Image { get; set; }
|
||||
public IReadOnlyDictionary<string, string> Data { get; set; }
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@ namespace Ombi.Notifications
|
|||
|
||||
body = ReplaceFields(bodyFields, parameters, body);
|
||||
subject = ReplaceFields(subjectFields, parameters, subject);
|
||||
return new NotificationMessageContent { Message = body ?? string.Empty, Subject = subject ?? string.Empty};
|
||||
return new NotificationMessageContent { Message = body ?? string.Empty, Subject = subject ?? string.Empty, Data = parameters };
|
||||
}
|
||||
|
||||
public IEnumerable<string> ProcessConditions(IEnumerable<string> conditionalFields, IReadOnlyDictionary<string, string> parameters)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Api.Discord\Ombi.Api.Discord.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.Gotify\Ombi.Api.Gotify.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" />
|
||||
<ProjectReference Include="..\Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj" />
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
namespace Ombi.Settings.Settings.Models.Notifications
|
||||
{
|
||||
public class WebhookSettings : Settings
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public string WebhookUrl { get; set; }
|
||||
public string ApplicationToken { get; set; }
|
||||
}
|
||||
}
|
11
src/Ombi.sln
11
src/Ombi.sln
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2027
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29519.87
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}"
|
||||
EndProject
|
||||
|
@ -100,6 +100,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Helpers.Tests", "Ombi.
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Gotify", "Ombi.Api.Gotify\Ombi.Api.Gotify.csproj", "{105EA346-766E-45B8-928B-DE6991DCB7EB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Webhook", "Ombi.Api.Webhook\Ombi.Api.Webhook.csproj", "{E2186FDA-D827-4781-8663-130AC382F12C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -262,6 +264,10 @@ Global
|
|||
{105EA346-766E-45B8-928B-DE6991DCB7EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{105EA346-766E-45B8-928B-DE6991DCB7EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{105EA346-766E-45B8-928B-DE6991DCB7EB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E2186FDA-D827-4781-8663-130AC382F12C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E2186FDA-D827-4781-8663-130AC382F12C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E2186FDA-D827-4781-8663-130AC382F12C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E2186FDA-D827-4781-8663-130AC382F12C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -300,6 +306,7 @@ Global
|
|||
{4FA21A20-92F4-462C-B929-2C517A88CC56} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
|
||||
{105EA346-766E-45B8-928B-DE6991DCB7EB} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{E2186FDA-D827-4781-8663-130AC382F12C} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}
|
||||
|
|
|
@ -101,6 +101,11 @@ export interface IGotifyNotificationSettings extends INotificationSettings {
|
|||
priority: number;
|
||||
}
|
||||
|
||||
export interface IWebhookNotificationSettings extends INotificationSettings {
|
||||
webhookUrl: string;
|
||||
applicationToken: string;
|
||||
}
|
||||
|
||||
export interface IMattermostNotifcationSettings extends INotificationSettings {
|
||||
webhookUrl: string;
|
||||
username: string;
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
ISlackNotificationSettings,
|
||||
ISonarrSettings,
|
||||
ITelegramNotifcationSettings,
|
||||
IWebhookNotificationSettings,
|
||||
} from "../../interfaces";
|
||||
|
||||
@Injectable()
|
||||
|
@ -48,6 +49,10 @@ export class TesterService extends ServiceHelpers {
|
|||
return this.http.post<boolean>(`${this.url}gotify`, 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 });
|
||||
}
|
||||
|
||||
public mattermostTest(settings: IMattermostNotifcationSettings): Observable<boolean> {
|
||||
return this.http.post<boolean>(`${this.url}mattermost`, JSON.stringify(settings), {headers: this.headers});
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import {
|
|||
IUpdateSettings,
|
||||
IUserManagementSettings,
|
||||
IVoteSettings,
|
||||
IWebhookNotificationSettings,
|
||||
} from "../interfaces";
|
||||
|
||||
import { ServiceHelpers } from "./service.helpers";
|
||||
|
@ -192,6 +193,14 @@ export class SettingsService extends ServiceHelpers {
|
|||
.post<boolean>(`${this.url}/notifications/gotify`, JSON.stringify(settings), { headers: this.headers });
|
||||
}
|
||||
|
||||
public getWebhookNotificationSettings(): Observable<IWebhookNotificationSettings> {
|
||||
return this.http.get<IWebhookNotificationSettings>(`${this.url}/notifications/webhook`, { headers: this.headers });
|
||||
}
|
||||
public saveWebhookNotificationSettings(settings: IWebhookNotificationSettings): Observable<boolean> {
|
||||
return this.http
|
||||
.post<boolean>(`${this.url}/notifications/webhook`, JSON.stringify(settings), { headers: this.headers });
|
||||
}
|
||||
|
||||
public getSlackNotificationSettings(): Observable<ISlackNotificationSettings> {
|
||||
return this.http.get<ISlackNotificationSettings>(`${this.url}/notifications/slack`, {headers: this.headers});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
<settings-menu></settings-menu>
|
||||
<div *ngIf="form">
|
||||
<fieldset>
|
||||
<legend>Webhook 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="webhookUrl" name="webhookUrl" [ngClass]="{'form-error': form.get('webhookUrl').hasError('required')}" formControlName="webhookUrl" pTooltip="Enter the URL of your webhook server.">
|
||||
<small *ngIf="form.get('webhookUrl').hasError('required')" class="error-text">The Webhook URL is required</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="applicationToken" class="control-label">Application Token
|
||||
<i class="fa fa-question-circle" pTooltip="Optional authentication token. Will be sent as 'Access-Token' header."></i>
|
||||
</label>
|
||||
|
||||
<input type="text" class="form-control form-control-custom " id="applicationToken" name="applicationToken" [ngClass]="{'form-error': form.get('applicationToken').hasError('required')}" formControlName="applicationToken" pTooltip="Enter your Application token from Webhook.">
|
||||
<small *ngIf="form.get('applicationToken').hasError('required')" class="error-text">The Application Token is required</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" 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" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
|
@ -0,0 +1,64 @@
|
|||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||
|
||||
import { INotificationTemplates, IWebhookNotificationSettings, NotificationType } from "../../interfaces";
|
||||
import { TesterService } from "../../services";
|
||||
import { NotificationService } from "../../services";
|
||||
import { SettingsService } from "../../services";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./webhook.component.html",
|
||||
})
|
||||
export class WebhookComponent implements OnInit {
|
||||
public NotificationType = NotificationType;
|
||||
public templates: INotificationTemplates[];
|
||||
public form: FormGroup;
|
||||
|
||||
constructor(private settingsService: SettingsService,
|
||||
private notificationService: NotificationService,
|
||||
private fb: FormBuilder,
|
||||
private testerService: TesterService) { }
|
||||
|
||||
public ngOnInit() {
|
||||
this.settingsService.getWebhookNotificationSettings().subscribe(x => {
|
||||
this.form = this.fb.group({
|
||||
enabled: [x.enabled],
|
||||
webhookUrl: [x.webhookUrl, [Validators.required]],
|
||||
applicationToken: [x.applicationToken],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public onSubmit(form: FormGroup) {
|
||||
if (form.invalid) {
|
||||
this.notificationService.error("Please check your entered values");
|
||||
return;
|
||||
}
|
||||
|
||||
const settings = <IWebhookNotificationSettings> form.value;
|
||||
|
||||
this.settingsService.saveWebhookNotificationSettings(settings).subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Successfully saved the Webhook settings");
|
||||
} else {
|
||||
this.notificationService.success("There was an error when saving the Webhook settings");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public test(form: FormGroup) {
|
||||
if (form.invalid) {
|
||||
this.notificationService.error("Please check your entered values");
|
||||
return;
|
||||
}
|
||||
|
||||
this.testerService.webhookTest(form.value).subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Successfully sent a Webhook message");
|
||||
} else {
|
||||
this.notificationService.error("There was an error when sending the Webhook message. Please check your settings");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import { PushbulletComponent } from "./notifications/pushbullet.component";
|
|||
import { PushoverComponent } from "./notifications/pushover.component";
|
||||
import { SlackComponent } from "./notifications/slack.component";
|
||||
import { TelegramComponent } from "./notifications/telegram.component";
|
||||
import { WebhookComponent } from "./notifications/webhook.component";
|
||||
import { OmbiComponent } from "./ombi/ombi.component";
|
||||
import { PlexComponent } from "./plex/plex.component";
|
||||
import { RadarrComponent } from "./radarr/radarr.component";
|
||||
|
@ -67,6 +68,7 @@ const routes: Routes = [
|
|||
{ path: "Pushover", component: PushoverComponent, canActivate: [AuthGuard] },
|
||||
{ path: "Pushbullet", component: PushbulletComponent, canActivate: [AuthGuard] },
|
||||
{ path: "Gotify", component: GotifyComponent, canActivate: [AuthGuard] },
|
||||
{ path: "Webhook", component: WebhookComponent, canActivate: [AuthGuard] },
|
||||
{ path: "Mattermost", component: MattermostComponent, canActivate: [AuthGuard] },
|
||||
{ path: "UserManagement", component: UserManagementComponent, canActivate: [AuthGuard] },
|
||||
{ path: "Update", component: UpdateComponent, canActivate: [AuthGuard] },
|
||||
|
@ -124,6 +126,7 @@ const routes: Routes = [
|
|||
MattermostComponent,
|
||||
PushbulletComponent,
|
||||
GotifyComponent,
|
||||
WebhookComponent,
|
||||
UserManagementComponent,
|
||||
UpdateComponent,
|
||||
AboutComponent,
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Mattermost']">Mattermost</a></li>
|
||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Telegram']">Telegram</a></li>
|
||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Gotify']">Gotify</a></li>
|
||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Webhook']">Webhook</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace Ombi.Controllers.External
|
|||
IPushbulletNotification pushbullet, ISlackNotification slack, IPushoverNotification po, IMattermostNotification mm,
|
||||
IPlexApi plex, IEmbyApi emby, IRadarrApi radarr, ISonarrApi sonarr, ILogger<TesterController> log, IEmailProvider provider,
|
||||
ICouchPotatoApi cpApi, ITelegramNotification telegram, ISickRageApi srApi, INewsletterJob newsletter, IMobileNotification mobileNotification,
|
||||
ILidarrApi lidarrApi, IGotifyNotification gotifyNotification)
|
||||
ILidarrApi lidarrApi, IGotifyNotification gotifyNotification, IWebhookNotification webhookNotification)
|
||||
{
|
||||
Service = service;
|
||||
DiscordNotification = notification;
|
||||
|
@ -62,6 +62,7 @@ namespace Ombi.Controllers.External
|
|||
MobileNotification = mobileNotification;
|
||||
LidarrApi = lidarrApi;
|
||||
GotifyNotification = gotifyNotification;
|
||||
WebhookNotification = webhookNotification;
|
||||
}
|
||||
|
||||
private INotificationService Service { get; }
|
||||
|
@ -71,6 +72,7 @@ namespace Ombi.Controllers.External
|
|||
private ISlackNotification SlackNotification { get; }
|
||||
private IPushoverNotification PushoverNotification { get; }
|
||||
private IGotifyNotification GotifyNotification { get; }
|
||||
private IWebhookNotification WebhookNotification { get; }
|
||||
private IMattermostNotification MattermostNotification { get; }
|
||||
private IPlexApi PlexApi { get; }
|
||||
private IRadarrApi RadarrApi { get; }
|
||||
|
@ -181,6 +183,30 @@ namespace Ombi.Controllers.External
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a test message to configured webhook using the provided settings
|
||||
/// </summary>
|
||||
/// <param name="settings">The settings.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("webhook")]
|
||||
public bool Webhook([FromBody] WebhookSettings settings)
|
||||
{
|
||||
try
|
||||
{
|
||||
settings.Enabled = true;
|
||||
WebhookNotification.NotifyAsync(
|
||||
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.LogError(LoggingEvents.Api, e, "Could not test your webhook");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a test message to mattermost using the provided settings
|
||||
/// </summary>
|
||||
|
|
|
@ -1007,6 +1007,33 @@ namespace Ombi.Controllers
|
|||
return model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the webhook notification settings.
|
||||
/// </summary>
|
||||
/// <param name="model">The model.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("notifications/webhook")]
|
||||
public async Task<bool> WebhookNotificationSettings([FromBody] WebhookNotificationViewModel model)
|
||||
{
|
||||
var settings = Mapper.Map<WebhookSettings>(model);
|
||||
var result = await Save(settings);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the webhook notification settings.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("notifications/webhook")]
|
||||
public async Task<WebhookNotificationViewModel> WebhookNotificationSettings()
|
||||
{
|
||||
var settings = await Get<WebhookSettings>();
|
||||
var model = Mapper.Map<WebhookNotificationViewModel>(settings);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the Newsletter notification settings.
|
||||
/// </summary>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue