diff --git a/Ombi.Api.Interfaces/IDiscordApi.cs b/Ombi.Api.Interfaces/IDiscordApi.cs
new file mode 100644
index 000000000..cb3ff9203
--- /dev/null
+++ b/Ombi.Api.Interfaces/IDiscordApi.cs
@@ -0,0 +1,38 @@
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2017 Jamie Rees
+// File: IDiscordApi.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+
+using System.Threading.Tasks;
+using Ombi.Api.Models.Notifications;
+
+namespace Ombi.Api.Interfaces
+{
+ public interface IDiscordApi
+ {
+ void SendMessage(string message, string webhookId, string webhookToken, string username = null);
+ Task SendMessageAsync(string message, string webhookId, string webhookToken, string username = null);
+ }
+}
\ No newline at end of file
diff --git a/Ombi.Api.Interfaces/Ombi.Api.Interfaces.csproj b/Ombi.Api.Interfaces/Ombi.Api.Interfaces.csproj
index 201d97b71..05c1aae09 100644
--- a/Ombi.Api.Interfaces/Ombi.Api.Interfaces.csproj
+++ b/Ombi.Api.Interfaces/Ombi.Api.Interfaces.csproj
@@ -47,6 +47,7 @@
+
diff --git a/Ombi.Api.Models/Notifications/DiscordWebhookRequest.cs b/Ombi.Api.Models/Notifications/DiscordWebhookRequest.cs
new file mode 100644
index 000000000..653235c08
--- /dev/null
+++ b/Ombi.Api.Models/Notifications/DiscordWebhookRequest.cs
@@ -0,0 +1,34 @@
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2017 Jamie Rees
+// File: DiscordWebhookRequest.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+namespace Ombi.Api.Models.Notifications
+{
+ public class DiscordWebhookRequest
+ {
+ public string content { get; set; }
+ public string username { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Ombi.Api.Models/Notifications/DiscordWebhookResponse.cs b/Ombi.Api.Models/Notifications/DiscordWebhookResponse.cs
new file mode 100644
index 000000000..ac7978c4c
--- /dev/null
+++ b/Ombi.Api.Models/Notifications/DiscordWebhookResponse.cs
@@ -0,0 +1,47 @@
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2017 Jamie Rees
+// File: DiscordWebhookResponse.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+
+namespace Ombi.Api.Models.Notifications
+{
+ public class DiscordWebhookResponse
+ {
+ public string name { get; set; }
+ [JsonProperty(PropertyName = "channel_id")]
+ public string channelid { get; set; }
+
+ public string token { get; set; }
+ public string avatar { get; set; }
+ [JsonProperty(PropertyName = "guild_id")]
+ public string guildid { get; set; }
+
+ public string id { get; set; }
+
+ }
+}
\ No newline at end of file
diff --git a/Ombi.Api.Models/Ombi.Api.Models.csproj b/Ombi.Api.Models/Ombi.Api.Models.csproj
index 32a55c507..f053da006 100644
--- a/Ombi.Api.Models/Ombi.Api.Models.csproj
+++ b/Ombi.Api.Models/Ombi.Api.Models.csproj
@@ -62,6 +62,8 @@
+
+
diff --git a/Ombi.Api/DiscordApi.cs b/Ombi.Api/DiscordApi.cs
new file mode 100644
index 000000000..a5214c503
--- /dev/null
+++ b/Ombi.Api/DiscordApi.cs
@@ -0,0 +1,113 @@
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2017 Jamie Rees
+// File: NetflixRouletteApi.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Ombi.Api.Interfaces;
+using Ombi.Api.Models.Netflix;
+using Ombi.Api.Models.Notifications;
+using RestSharp;
+
+namespace Ombi.Api
+{
+ public class DiscordApi : IDiscordApi
+ {
+ public DiscordApi(IApiRequest req)
+ {
+ Api = req;
+ }
+
+ private IApiRequest Api { get; }
+ private Uri Endpoint => new Uri("https://discordapp.com/api/"); //webhooks/270828242636636161/lLysOMhJ96AFO1kvev0bSqP-WCZxKUh1UwfubhIcLkpS0DtM3cg4Pgeraw3waoTXbZii
+
+
+ public void SendMessage(string message, string webhookId, string webhookToken, string username = null)
+ {
+ var request = new RestRequest
+ {
+ Resource = "webhooks/{webhookId}/{webhookToken}"
+ };
+
+ request.AddUrlSegment("webhookId", webhookId);
+ request.AddUrlSegment("webhookToken", webhookToken);
+
+ var body = new DiscordWebhookRequest
+ {
+ content = message,
+ username = username
+ };
+ request.AddJsonBody(body);
+
+ request.AddHeader("Content-Type", "application/json");
+
+ Api.Execute(request, Endpoint);
+ }
+
+ public async Task SendMessageAsync(string message, string webhookId, string webhookToken, string username = null)
+ {
+ var request = new RestRequest
+ {
+ Resource = "webhooks/{webhookId}/{webhookToken}"
+ };
+
+ request.AddUrlSegment("webhookId", webhookId);
+ request.AddUrlSegment("webhookToken", webhookToken);
+
+ var body = new DiscordWebhookRequest
+ {
+ content = message,
+ username = username
+ };
+ request.AddJsonBody(body);
+
+ request.AddHeader("Content-Type", "application/json");
+
+ await Task.Run(
+ () =>
+ {
+ Api.Execute(request, Endpoint);
+
+ });
+ }
+
+
+
+ public NetflixMovieResult CheckNetflix(string title, string year = null)
+ {
+ var request = new RestRequest();
+ request.AddQueryParameter("title", title);
+ if (!string.IsNullOrEmpty(year))
+ {
+ request.AddQueryParameter("year", year);
+ }
+ var result = Api.Execute(request, Endpoint);
+
+ return JsonConvert.DeserializeObject(result.Content);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ombi.Api/Ombi.Api.csproj b/Ombi.Api/Ombi.Api.csproj
index b9151ca5d..0e60de918 100644
--- a/Ombi.Api/Ombi.Api.csproj
+++ b/Ombi.Api/Ombi.Api.csproj
@@ -69,6 +69,7 @@
+
diff --git a/Ombi.Core/ISecurityExtensions.cs b/Ombi.Core/ISecurityExtensions.cs
index e3b52a613..0743b5a51 100644
--- a/Ombi.Core/ISecurityExtensions.cs
+++ b/Ombi.Core/ISecurityExtensions.cs
@@ -29,7 +29,10 @@ namespace Ombi.Core
/// Gets the username this could be the alias! We should always use this method when getting the username
///
/// The username.
- /// null if we cannot find a user
+ /// The session.
+ ///
+ /// null if we cannot find a user
+ ///
string GetUsername(string username, ISession session);
}
}
\ No newline at end of file
diff --git a/Ombi.Core/Ombi.Core.csproj b/Ombi.Core/Ombi.Core.csproj
index 828ed3b4e..6746f6631 100644
--- a/Ombi.Core/Ombi.Core.csproj
+++ b/Ombi.Core/Ombi.Core.csproj
@@ -122,6 +122,7 @@
+
diff --git a/Ombi.Core/SecurityExtensions.cs b/Ombi.Core/SecurityExtensions.cs
index 8ec7f3689..a68884009 100644
--- a/Ombi.Core/SecurityExtensions.cs
+++ b/Ombi.Core/SecurityExtensions.cs
@@ -94,34 +94,23 @@ namespace Ombi.Core
/// Gets the username this could be the alias! We should always use this method when getting the username
///
/// The username.
- /// null if we cannot find a user
+ ///
+ ///
+ /// null if we cannot find a user
+ ///
public string GetUsername(string username, ISession session)
{
var plexUser = PlexUsers.GetUserByUsername(username);
if (plexUser != null)
{
- if (!string.IsNullOrEmpty(plexUser.UserAlias))
- {
- return plexUser.UserAlias;
- }
- else
- {
- return plexUser.Username;
- }
+ return !string.IsNullOrEmpty(plexUser.UserAlias) ? plexUser.UserAlias : plexUser.Username;
}
var dbUser = UserRepository.GetUserByUsername(username);
if (dbUser != null)
{
var userProps = ByteConverterHelper.ReturnObject(dbUser.UserProperties);
- if (!string.IsNullOrEmpty(userProps.UserAlias))
- {
- return userProps.UserAlias;
- }
- else
- {
- return dbUser.UserName;
- }
+ return !string.IsNullOrEmpty(userProps.UserAlias) ? userProps.UserAlias : dbUser.UserName;
}
// could be a local user
diff --git a/Ombi.Core/SettingModels/DiscordNotificationSettings.cs b/Ombi.Core/SettingModels/DiscordNotificationSettings.cs
new file mode 100644
index 000000000..899b7f16e
--- /dev/null
+++ b/Ombi.Core/SettingModels/DiscordNotificationSettings.cs
@@ -0,0 +1,31 @@
+using System;
+using Newtonsoft.Json;
+
+namespace Ombi.Core.SettingModels
+{
+ public sealed class DiscordNotificationSettings : NotificationSettings
+ {
+ public string WebhookUrl { get; set; }
+ public string Username { get; set; }
+
+ [JsonIgnore]
+ public string WebookId => SplitWebUrl(4);
+
+ [JsonIgnore]
+ public string Token => SplitWebUrl(5);
+
+ private string SplitWebUrl(int index)
+ {
+ if (!WebhookUrl.StartsWith("http", StringComparison.InvariantCulture))
+ {
+ WebhookUrl = "https://" + WebhookUrl;
+ }
+ var split = WebhookUrl.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+
+ return split.Length < index
+ ? string.Empty
+ : split[index];
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Ombi.Services/Notification/DiscordNotification.cs b/Ombi.Services/Notification/DiscordNotification.cs
new file mode 100644
index 000000000..4cfdfdbb5
--- /dev/null
+++ b/Ombi.Services/Notification/DiscordNotification.cs
@@ -0,0 +1,165 @@
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2016 Jamie Rees
+// File: SlackNotification.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using NLog;
+using Ombi.Api.Interfaces;
+using Ombi.Api.Models.Notifications;
+using Ombi.Core;
+using Ombi.Core.Models;
+using Ombi.Core.SettingModels;
+using Ombi.Services.Interfaces;
+
+namespace Ombi.Services.Notification
+{
+ public class DiscordNotification : INotification
+ {
+ public DiscordNotification(IDiscordApi api, ISettingsService sn)
+ {
+ Api = api;
+ Settings = sn;
+ }
+
+ public string NotificationName => "DiscordNotification";
+
+ private IDiscordApi Api { get; }
+ private ISettingsService Settings { get; }
+ private static Logger Log = LogManager.GetCurrentClassLogger();
+
+
+ public async Task NotifyAsync(NotificationModel model)
+ {
+ var settings = Settings.GetSettings();
+
+ await NotifyAsync(model, settings);
+ }
+
+ public async Task NotifyAsync(NotificationModel model, Settings settings)
+ {
+ if (settings == null) await NotifyAsync(model);
+
+ var pushSettings = (DiscordNotificationSettings)settings;
+ if (!ValidateConfiguration(pushSettings))
+ {
+ Log.Error("Settings for Slack was not correct, we cannot push a notification");
+ return;
+ }
+
+ switch (model.NotificationType)
+ {
+ case NotificationType.NewRequest:
+ await PushNewRequestAsync(model, pushSettings);
+ break;
+ case NotificationType.Issue:
+ await PushIssueAsync(model, pushSettings);
+ break;
+ case NotificationType.RequestAvailable:
+ break;
+ case NotificationType.RequestApproved:
+ break;
+ case NotificationType.AdminNote:
+ break;
+ case NotificationType.Test:
+ await PushTest(pushSettings);
+ break;
+ case NotificationType.RequestDeclined:
+ await PushRequestDeclinedAsync(model, pushSettings);
+ break;
+ case NotificationType.ItemAddedToFaultQueue:
+ await PushFaultQueue(model, pushSettings);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ private async Task PushNewRequestAsync(NotificationModel model, DiscordNotificationSettings settings)
+ {
+ var message = $"{model.Title} has been requested by user: {model.User}";
+ await Push(settings, message);
+ }
+
+ private async Task PushRequestDeclinedAsync(NotificationModel model, DiscordNotificationSettings settings)
+ {
+ var message = $"Hello! Your request for {model.Title} has been declined, Sorry!";
+ await Push(settings, message);
+ }
+
+ private async Task PushIssueAsync(NotificationModel model, DiscordNotificationSettings settings)
+ {
+ var message = $"A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}";
+ await Push(settings, message);
+ }
+
+ private async Task PushTest(DiscordNotificationSettings settings)
+ {
+ var message = $"This is a test from Ombi, if you can see this then we have successfully pushed a notification!";
+ await Push(settings, message);
+ }
+
+ private async Task PushFaultQueue(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";
+ await Push(settings, message);
+ }
+
+ private async Task Push(DiscordNotificationSettings config, string message)
+ {
+ try
+ {
+ await Api.SendMessageAsync(message, config.WebookId, config.Token, config.Username);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e);
+ }
+ }
+
+ private 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ombi.Services/Ombi.Services.csproj b/Ombi.Services/Ombi.Services.csproj
index fabb8e69f..ec412e87f 100644
--- a/Ombi.Services/Ombi.Services.csproj
+++ b/Ombi.Services/Ombi.Services.csproj
@@ -126,6 +126,7 @@
+
diff --git a/Ombi.UI/Modules/Admin/AdminModule.cs b/Ombi.UI/Modules/Admin/AdminModule.cs
index ea320ff14..c0d79d183 100644
--- a/Ombi.UI/Modules/Admin/AdminModule.cs
+++ b/Ombi.UI/Modules/Admin/AdminModule.cs
@@ -93,6 +93,8 @@ namespace Ombi.UI.Modules.Admin
private IAnalytics Analytics { get; }
private IRecentlyAdded RecentlyAdded { get; }
private ISettingsService NotifySettings { get; }
+ private ISettingsService DiscordSettings { get; }
+ private IDiscordApi DiscordApi { get; }
private static Logger Log = LogManager.GetCurrentClassLogger();
public AdminModule(ISettingsService prService,
@@ -118,7 +120,9 @@ namespace Ombi.UI.Modules.Admin
ISlackApi slackApi, ISettingsService lp,
ISettingsService scheduler, IJobRecord rec, IAnalytics analytics,
ISettingsService notifyService, IRecentlyAdded recentlyAdded,
- ISettingsService watcherSettings
+ ISettingsService watcherSettings ,
+ ISettingsService discord,
+ IDiscordApi discordapi
, ISecurityExtensions security) : base("admin", prService, security)
{
PrService = prService;
@@ -150,6 +154,8 @@ namespace Ombi.UI.Modules.Admin
NotifySettings = notifyService;
RecentlyAdded = recentlyAdded;
WatcherSettings = watcherSettings;
+ DiscordSettings = discord;
+ DiscordApi = discordapi;
Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx);
@@ -208,10 +214,13 @@ namespace Ombi.UI.Modules.Admin
Post["/testslacknotification", true] = async (x, ct) => await TestSlackNotification();
-
Get["/slacknotification"] = _ => SlackNotifications();
Post["/slacknotification"] = _ => SaveSlackNotifications();
+ Post["/testdiscordnotification", true] = async (x, ct) => await TestDiscordNotification();
+ Get["/discordnotification", true] = async (x, ct) => await DiscordNotification();
+ Post["/discordnotification", true] = async (x, ct) => await SaveDiscordNotifications();
+
Get["/landingpage", true] = async (x, ct) => await LandingPage();
Post["/landingpage", true] = async (x, ct) => await SaveLandingPage();
@@ -918,6 +927,71 @@ namespace Ombi.UI.Modules.Admin
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
}
+ private async Task DiscordNotification()
+ {
+ var settings = await DiscordSettings.GetSettingsAsync();
+ return View["DiscordNotification", settings];
+ }
+
+ private async Task TestDiscordNotification()
+ {
+ var settings = this.BindAndValidate();
+ if (!ModelValidationResult.IsValid)
+ {
+ return Response.AsJson(ModelValidationResult.SendJsonError());
+ }
+ var notificationModel = new NotificationModel
+ {
+ NotificationType = NotificationType.Test,
+ DateTime = DateTime.Now
+ };
+
+ var currentDicordSettings = await DiscordSettings.GetSettingsAsync();
+ try
+ {
+ NotificationService.Subscribe(new DiscordNotification(DiscordApi, DiscordSettings));
+ settings.Enabled = true;
+ await NotificationService.Publish(notificationModel, settings);
+ Log.Info("Sent Discord notification test");
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, "Failed to subscribe and publish test Discord Notification");
+ }
+ finally
+ {
+ if (!currentDicordSettings.Enabled)
+ {
+ NotificationService.UnSubscribe(new DiscordNotification(DiscordApi, DiscordSettings));
+ }
+ }
+ return Response.AsJson(new JsonResponseModel { Result = true, Message = "Successfully sent a test Discord Notification! If you do not receive it please check the logs." });
+ }
+
+ private async Task SaveDiscordNotifications()
+ {
+ var settings = this.BindAndValidate();
+ if (!ModelValidationResult.IsValid)
+ {
+ return Response.AsJson(ModelValidationResult.SendJsonError());
+ }
+
+ var result = await DiscordSettings.SaveSettingsAsync(settings);
+ if (settings.Enabled)
+ {
+ NotificationService.Subscribe(new DiscordNotification(DiscordApi, DiscordSettings));
+ }
+ else
+ {
+ NotificationService.UnSubscribe(new DiscordNotification(DiscordApi, DiscordSettings));
+ }
+
+ Log.Info("Saved discord settings, result: {0}", result);
+ return Response.AsJson(result
+ ? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Discord Notifications!" }
+ : new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
+ }
+
private async Task LandingPage()
{
var settings = await LandingSettings.GetSettingsAsync();
diff --git a/Ombi.UI/Modules/BaseModule.cs b/Ombi.UI/Modules/BaseModule.cs
index 59904dcb6..989e3ee1a 100644
--- a/Ombi.UI/Modules/BaseModule.cs
+++ b/Ombi.UI/Modules/BaseModule.cs
@@ -115,7 +115,7 @@ namespace Ombi.UI.Modules
var username = Security.GetUsername(User.UserName, Session);
if (string.IsNullOrEmpty(username))
{
- return Session[SessionKeys.UsernameKey].ToString();
+ return "Unknown User";
}
_username = username;
}
diff --git a/Ombi.UI/Ombi.UI.csproj b/Ombi.UI/Ombi.UI.csproj
index d984e4562..30083f4d5 100644
--- a/Ombi.UI/Ombi.UI.csproj
+++ b/Ombi.UI/Ombi.UI.csproj
@@ -789,6 +789,9 @@
Always
+
+ Always
+
web.config
diff --git a/Ombi.UI/Views/Admin/DiscordNotification.cshtml b/Ombi.UI/Views/Admin/DiscordNotification.cshtml
new file mode 100644
index 000000000..008b96e01
--- /dev/null
+++ b/Ombi.UI/Views/Admin/DiscordNotification.cshtml
@@ -0,0 +1,99 @@
+@using Ombi.UI.Helpers
+@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase
+@Html.Partial("Shared/Partial/_Sidebar")
+
+
+
+
\ No newline at end of file
diff --git a/Ombi.UI/Views/Shared/Partial/_Sidebar.cshtml b/Ombi.UI/Views/Shared/Partial/_Sidebar.cshtml
index df5969a95..d38827cf8 100644
--- a/Ombi.UI/Views/Shared/Partial/_Sidebar.cshtml
+++ b/Ombi.UI/Views/Shared/Partial/_Sidebar.cshtml
@@ -19,6 +19,7 @@
@Html.GetSidebarUrl(Context, "/admin/pushbulletnotification", "Pushbullet Notifications")
@Html.GetSidebarUrl(Context, "/admin/pushovernotification", "Pushover Notifications")
@Html.GetSidebarUrl(Context, "/admin/slacknotification", "Slack Notifications")
+ @Html.GetSidebarUrl(Context, "/admin/discordnotification", "Discord Notifications")
@Html.GetSidebarUrl(Context, "/admin/logs", "Logs")
@Html.GetSidebarUrl(Context, "/admin/status", "Status")
@Html.GetSidebarUrl(Context, "/admin/scheduledjobs", "Scheduled Jobs")