diff --git a/src/Ombi.Api.Discord/DiscordApi.cs b/src/Ombi.Api.Discord/DiscordApi.cs
new file mode 100644
index 000000000..537bf15ef
--- /dev/null
+++ b/src/Ombi.Api.Discord/DiscordApi.cs
@@ -0,0 +1,33 @@
+using System.Net.Http;
+using System.Threading.Tasks;
+using Ombi.Api.Discord.Models;
+
+namespace Ombi.Api.Discord
+{
+ public class DiscordApi : IDiscordApi
+ {
+ public DiscordApi()
+ {
+ Api = new Api();
+ }
+
+ private string Endpoint => "https://discordapp.com/api/"; //webhooks/270828242636636161/lLysOMhJ96AFO1kvev0bSqP-WCZxKUh1UwfubhIcLkpS0DtM3cg4Pgeraw3waoTXbZii
+ private Api Api { get; }
+
+ public async Task SendMessage(string message, string webhookId, string webhookToken, string username = null)
+ {
+ var request = new Request(Endpoint, $"webhooks/{webhookId}/{webhookToken}", HttpMethod.Post);
+
+ var body = new DiscordWebhookBody
+ {
+ content = message,
+ username = username
+ };
+ request.AddJsonBody(body);
+
+ request.AddHeader("Content-Type", "application/json");
+
+ await Api.Request(request);
+ }
+ }
+}
diff --git a/src/Ombi.Api.Discord/IDiscordApi.cs b/src/Ombi.Api.Discord/IDiscordApi.cs
new file mode 100644
index 000000000..2a5375ee2
--- /dev/null
+++ b/src/Ombi.Api.Discord/IDiscordApi.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace Ombi.Api.Discord
+{
+ public interface IDiscordApi
+ {
+ Task SendMessage(string message, string webhookId, string webhookToken, string username = null);
+ }
+}
\ No newline at end of file
diff --git a/src/Ombi.Api.Discord/Models/DiscordWebhookBody.cs b/src/Ombi.Api.Discord/Models/DiscordWebhookBody.cs
new file mode 100644
index 000000000..a80423a84
--- /dev/null
+++ b/src/Ombi.Api.Discord/Models/DiscordWebhookBody.cs
@@ -0,0 +1,8 @@
+namespace Ombi.Api.Discord.Models
+{
+ public class DiscordWebhookBody
+ {
+ public string content { get; set; }
+ public string username { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj b/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj
new file mode 100644
index 000000000..a8c3e7a4c
--- /dev/null
+++ b/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj
@@ -0,0 +1,11 @@
+
+
+
+ netstandard1.6
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Ombi.Api.Radarr/RadarrApi.cs b/src/Ombi.Api.Radarr/RadarrApi.cs
index e04c7c8bb..9ea5490cb 100644
--- a/src/Ombi.Api.Radarr/RadarrApi.cs
+++ b/src/Ombi.Api.Radarr/RadarrApi.cs
@@ -82,7 +82,7 @@ namespace Ombi.Api.Radarr
try
{
- var response = await Api.Request(request);
+ var response = await Api.RequestContent(request);
if (response.Contains("\"message\":"))
{
var error = JsonConvert.DeserializeObject(response);
diff --git a/src/Ombi.Api/Api.cs b/src/Ombi.Api/Api.cs
index 248257468..fcf688c26 100644
--- a/src/Ombi.Api/Api.cs
+++ b/src/Ombi.Api/Api.cs
@@ -60,7 +60,7 @@ namespace Ombi.Api
}
}
- public async Task Request(Request request)
+ public async Task RequestContent(Request request)
{
using (var httpClient = new HttpClient())
{
@@ -93,5 +93,34 @@ namespace Ombi.Api
}
}
}
+
+ public async Task Request(Request request)
+ {
+ using (var httpClient = new HttpClient())
+ {
+ using (var httpRequestMessage = new HttpRequestMessage(request.HttpMethod, request.FullUri))
+ {
+ // Add the Json Body
+ if (request.JsonBody != null)
+ {
+ httpRequestMessage.Content = new JsonContent(request.JsonBody);
+ }
+
+ // Add headers
+ foreach (var header in request.Headers)
+ {
+ httpRequestMessage.Headers.Add(header.Key, header.Value);
+
+ }
+ using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage))
+ {
+ if (!httpResponseMessage.IsSuccessStatusCode)
+ {
+ // Logging
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/src/Ombi.Api/Request.cs b/src/Ombi.Api/Request.cs
index c9714f3c4..56ff100eb 100644
--- a/src/Ombi.Api/Request.cs
+++ b/src/Ombi.Api/Request.cs
@@ -50,7 +50,7 @@ namespace Ombi.Api
public List> Headers { get; } = new List>();
public List> ContentHeaders { get; } = new List>();
- public object JsonBody { get; set; }
+ public object JsonBody { get; private set; }
public bool IsValidUrl
{
diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs
index 15dc99cd2..f88d41e81 100644
--- a/src/Ombi.DependencyInjection/IocExtensions.cs
+++ b/src/Ombi.DependencyInjection/IocExtensions.cs
@@ -2,6 +2,8 @@
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
+
+using Ombi.Api.Discord;
using Ombi.Api.Emby;
using Ombi.Api.Plex;
using Ombi.Api.Radarr;
@@ -60,6 +62,7 @@ namespace Ombi.DependencyInjection
services.AddTransient();
services.AddTransient();
services.AddTransient();
+ services.AddTransient();
}
public static void RegisterStore(this IServiceCollection services)
diff --git a/src/Ombi.Helpers/LoggingEvents.cs b/src/Ombi.Helpers/LoggingEvents.cs
index acab47918..525035c98 100644
--- a/src/Ombi.Helpers/LoggingEvents.cs
+++ b/src/Ombi.Helpers/LoggingEvents.cs
@@ -6,8 +6,13 @@ namespace Ombi.Helpers
{
public static EventId ApiException => new EventId(1000);
public static EventId RadarrApiException => new EventId(1001);
+
public static EventId CacherException => new EventId(2000);
public static EventId RadarrCacherException => new EventId(2001);
+
public static EventId MovieSender => new EventId(3000);
+
+ public static EventId Notification => new EventId(4000);
+ public static EventId DiscordNotification => new EventId(4001);
}
}
\ No newline at end of file
diff --git a/src/Ombi.Notification.Discord/Class1.cs b/src/Ombi.Notification.Discord/Class1.cs
new file mode 100644
index 000000000..aa693b363
--- /dev/null
+++ b/src/Ombi.Notification.Discord/Class1.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Ombi.Api.Discord;
+using Ombi.Core.Settings;
+using Ombi.Helpers;
+using Ombi.Notifications;
+using Ombi.Notifications.Models;
+using Ombi.Settings.Settings.Models.Notifications;
+
+namespace Ombi.Notification.Discord
+{
+ public class DiscordNotification : BaseNotification
+ {
+ public DiscordNotification(IDiscordApi api, ISettingsService sn, ILogger log) : base(sn)
+ {
+ Api = api;
+ Logger = log;
+ }
+
+ public override string NotificationName => "DiscordNotification";
+
+ private IDiscordApi Api { get; }
+ private ILogger Logger { get; }
+
+ protected override bool ValidateConfiguration(DiscordNotificationSettings settings)
+ {
+ if (!settings.Enabled)
+ {
+ return false;
+ }
+ if (string.IsNullOrEmpty(settings.WebhookUrl))
+ {
+ return false;
+ }
+ try
+ {
+ var a = settings.Token;
+ var b = settings.WebookId;
+ }
+ catch (IndexOutOfRangeException)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ protected override async Task NewRequest(NotificationModel model, DiscordNotificationSettings settings)
+ {
+ var message = $"{model.Title} has been requested by user: {model.User}";
+
+ var notification = new NotificationMessage
+ {
+ Message = message,
+ };
+ await Send(notification, settings);
+ }
+
+ protected override async Task Issue(NotificationModel model, DiscordNotificationSettings settings)
+ {
+ var message = $"A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}";
+ var notification = new NotificationMessage
+ {
+ Message = message,
+ };
+ await Send(notification, settings);
+ }
+
+ protected override async Task AddedToRequestQueue(NotificationModel model, DiscordNotificationSettings settings)
+ {
+ var message = $"Hello! The user '{model.User}' has requested {model.Title} but it could not be added. This has been added into the requests queue and will keep retrying";
+ var notification = new NotificationMessage
+ {
+ Message = message,
+ };
+ await Send(notification, settings);
+ }
+
+ protected override async Task RequestDeclined(NotificationModel model, DiscordNotificationSettings settings)
+ {
+ var message = $"Hello! Your request for {model.Title} has been declined, Sorry!";
+ var notification = new NotificationMessage
+ {
+ Message = message,
+ };
+ await Send(notification, settings);
+ }
+
+ protected override async Task RequestApproved(NotificationModel model, DiscordNotificationSettings settings)
+ {
+ var message = $"Hello! The request for {model.Title} has now been approved!";
+ var notification = new NotificationMessage
+ {
+ Message = message,
+ };
+ await Send(notification, settings);
+ }
+
+ protected override async Task AvailableRequest(NotificationModel model, DiscordNotificationSettings settings)
+ {
+ var message = $"Hello! The request for {model.Title} is now available!";
+ var notification = new NotificationMessage
+ {
+ Message = message,
+ };
+ await Send(notification, settings);
+ }
+
+ protected override async Task Send(NotificationMessage model, DiscordNotificationSettings settings)
+ {
+ try
+ {
+ await Api.SendMessage(model.Message, settings.WebookId, settings.Token, settings.Username);
+ }
+ catch (Exception e)
+ {
+ Logger.LogError(LoggingEvents.DiscordNotification, e, "Failed to send Discord Notification");
+ }
+ }
+
+ protected override async Task Test(NotificationModel model, DiscordNotificationSettings 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);
+ }
+ }
+}
diff --git a/src/Ombi.Notification.Discord/Ombi.Notification.Discord.csproj b/src/Ombi.Notification.Discord/Ombi.Notification.Discord.csproj
new file mode 100644
index 000000000..ecacf8bcf
--- /dev/null
+++ b/src/Ombi.Notification.Discord/Ombi.Notification.Discord.csproj
@@ -0,0 +1,12 @@
+
+
+
+ netstandard1.6
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Ombi.Notifications.Email/EmailNotification.cs b/src/Ombi.Notifications.Email/EmailNotification.cs
index 9f633320c..f5986dc34 100644
--- a/src/Ombi.Notifications.Email/EmailNotification.cs
+++ b/src/Ombi.Notifications.Email/EmailNotification.cs
@@ -4,9 +4,9 @@ using MailKit.Net.Smtp;
using MimeKit;
using Ombi.Core.Models.Requests;
using Ombi.Core.Settings;
-using Ombi.Core.Settings.Models.Notifications;
using Ombi.Notifications.Models;
using Ombi.Notifications.Templates;
+using Ombi.Settings.Settings.Models.Notifications;
namespace Ombi.Notifications.Email
{
@@ -20,6 +20,10 @@ namespace Ombi.Notifications.Email
protected override bool ValidateConfiguration(EmailNotificationSettings settings)
{
+ if (!settings.Enabled)
+ {
+ return false;
+ }
if (settings.Authentication)
{
if (string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword))
diff --git a/src/Ombi.Notifications/BaseNotification.cs b/src/Ombi.Notifications/BaseNotification.cs
index 86fd18bcf..fe81ac2c4 100644
--- a/src/Ombi.Notifications/BaseNotification.cs
+++ b/src/Ombi.Notifications/BaseNotification.cs
@@ -25,7 +25,7 @@ namespace Ombi.Notifications
public async Task NotifyAsync(NotificationModel model, Settings.Settings.Models.Settings settings)
{
if (settings == null) await NotifyAsync(model);
-
+
var notificationSettings = (T)settings;
if (!ValidateConfiguration(notificationSettings))
diff --git a/src/Ombi.Notifications/Interfaces/INotificationService.cs b/src/Ombi.Notifications/Interfaces/INotificationService.cs
index 9001b299a..35e239764 100644
--- a/src/Ombi.Notifications/Interfaces/INotificationService.cs
+++ b/src/Ombi.Notifications/Interfaces/INotificationService.cs
@@ -7,12 +7,8 @@ namespace Ombi.Notifications
{
public interface INotificationService
{
- ConcurrentDictionary Observers { get; }
-
Task Publish(NotificationModel model);
Task Publish(NotificationModel model, Settings.Settings.Models.Settings settings);
Task PublishTest(NotificationModel model, Settings.Settings.Models.Settings settings, INotification type);
- void Subscribe(INotification notification);
- void UnSubscribe(INotification notification);
}
}
\ No newline at end of file
diff --git a/src/Ombi.Notifications/NotificationService.cs b/src/Ombi.Notifications/NotificationService.cs
index f73361108..f513f263a 100644
--- a/src/Ombi.Notifications/NotificationService.cs
+++ b/src/Ombi.Notifications/NotificationService.cs
@@ -1,15 +1,47 @@
using System;
-using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using System.Threading.Tasks;
-using Ombi.Core.Settings.Models;
+using Microsoft.Extensions.Logging;
+using Ombi.Helpers;
using Ombi.Notifications.Models;
namespace Ombi.Notifications
{
public class NotificationService : INotificationService
{
- public ConcurrentDictionary Observers { get; } = new ConcurrentDictionary();
+ public NotificationService(IServiceProvider provider, ILogger log)
+ {
+ Log = log;
+ NotificationAgents = new List();
+
+ var baseSearchType = typeof(BaseNotification<>).FullName;
+
+ var ass = typeof(NotificationService).GetTypeInfo().Assembly;
+
+ foreach (var ti in ass.DefinedTypes)
+ {
+ if (ti?.BaseType?.FullName == baseSearchType)
+ {
+ var type = ti?.AsType();
+ var ctors = type.GetConstructors();
+ var ctor = ctors.FirstOrDefault();
+
+ var services = new List