pull/1488/head
Jamie.Rees 7 years ago
parent 018cd7a072
commit d5477adc6b

@ -0,0 +1,10 @@
using System.Threading.Tasks;
using Ombi.Api.Slack.Models;
namespace Ombi.Api.Slack
{
public interface ISlackApi
{
Task<string> PushAsync(string team, string token, string service, SlackNotificationBody message);
}
}

@ -0,0 +1,30 @@
using Newtonsoft.Json;
namespace Ombi.Api.Slack.Models
{
public class SlackNotificationBody
{
[JsonConstructor]
public SlackNotificationBody()
{
username = "Ombi";
}
[JsonIgnore]
private string _username;
public string username
{
get => _username;
set
{
if (!string.IsNullOrEmpty(value))
_username = value;
}
}
public string channel { get; set; }
public string text { get; set; }
public string icon_url { get; set; }
public string icon_emoji { get; set; }
}
}

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,42 @@
using System;
using System.Dynamic;
using System.Net.Http;
using System.Threading.Tasks;
using Ombi.Api.Slack.Models;
namespace Ombi.Api.Slack
{
public class SlackApi : ISlackApi
{
public SlackApi(IApi api)
{
Api = api;
}
private IApi Api { get; }
private const string BaseUrl = "https://hooks.slack.com/";
public async Task<string> PushAsync(string team, string token, string service, SlackNotificationBody message)
{
var request = new Request($"/services/{team}/{service}/{token}", BaseUrl, HttpMethod.Post);
dynamic body = new ExpandoObject();
body.channel = message.channel;
body.text = message.text;
body.username = message.username;
if (!string.IsNullOrEmpty(message.icon_url))
{
body.icon_url = message.icon_url;
}
if (!string.IsNullOrEmpty(message.icon_emoji))
{
body.icon_emoji = message.icon_emoji;
}
request.AddJsonBody(body);
request.ApplicationJsonContentType();
return await Api.Request<string>(request);
}
}
}

@ -0,0 +1,21 @@
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="SlackNotificationSettings" />
public class SlackNotificationsViewModel : SlackNotificationSettings
{
/// <summary>
/// Gets or sets the notification templates.
/// </summary>
/// <value>
/// The notification templates.
/// </value>
public List<NotificationTemplates> NotificationTemplates { get; set; }
}
}

@ -30,6 +30,7 @@ using Ombi.Api;
using Ombi.Api.FanartTv;
using Ombi.Api.Pushbullet;
using Ombi.Api.Service;
using Ombi.Api.Slack;
using Ombi.Core.Rule.Interfaces;
using Ombi.Core.Senders;
using Ombi.Schedule.Ombi;
@ -68,6 +69,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<IPlexApi, PlexApi>();
services.AddTransient<IEmbyApi, EmbyApi>();
services.AddTransient<ISonarrApi, SonarrApi>();
services.AddTransient<ISlackApi, SlackApi>();
services.AddTransient<ITvMazeApi, TvMazeApi>();
services.AddTransient<ITraktApi, TraktApi>();
services.AddTransient<IRadarrApi, RadarrApi>();
@ -104,6 +106,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<IDiscordNotification, DiscordNotification>();
services.AddTransient<IEmailNotification, EmailNotification>();
services.AddTransient<IPushbulletNotification, PushbulletNotification>();
services.AddTransient<ISlackNotification, SlackNotification>();
}
public static void RegisterJobs(this IServiceCollection services)

@ -18,6 +18,7 @@
<ProjectReference Include="..\Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj" />
<ProjectReference Include="..\Ombi.Api.Radarr\Ombi.Api.Radarr.csproj" />
<ProjectReference Include="..\Ombi.Api.Service\Ombi.Api.Service.csproj" />
<ProjectReference Include="..\Ombi.Api.Slack\Ombi.Api.Slack.csproj" />
<ProjectReference Include="..\Ombi.Api.Sonarr\Ombi.Api.Sonarr.csproj" />
<ProjectReference Include="..\Ombi.Api.Trakt\Ombi.Api.Trakt.csproj" />
<ProjectReference Include="..\Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj" />

@ -17,6 +17,7 @@ namespace Ombi.Helpers
public static EventId Notification => new EventId(4000);
public static EventId DiscordNotification => new EventId(4001);
public static EventId PushbulletNotification => new EventId(4002);
public static EventId SlackNotification => new EventId(4003);
public static EventId TvSender => new EventId(5000);
public static EventId SonarrSender => new EventId(5001);

@ -11,6 +11,7 @@ namespace Ombi.Mapping.Profiles
CreateMap<EmailNotificationsViewModel, EmailNotificationSettings>().ReverseMap();
CreateMap<DiscordNotificationsViewModel, DiscordNotificationSettings>().ReverseMap();
CreateMap<PushbulletNotificationViewModel, PushbulletSettings>().ReverseMap();
CreateMap<SlackNotificationsViewModel, SlackNotificationSettings>().ReverseMap();
}
}
}

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

@ -0,0 +1,168 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Ombi.Api.Slack;
using Ombi.Api.Slack.Models;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Notifications.Interfaces;
using Ombi.Notifications.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 SlackNotification : BaseNotification<SlackNotificationSettings>, ISlackNotification
{
public SlackNotification(ISlackApi api, ISettingsService<SlackNotificationSettings> sn, ILogger<SlackNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t) : base(sn, r, m, t)
{
Api = api;
Logger = log;
}
public override string NotificationName => "SlackNotification";
private ISlackApi Api { get; }
private ILogger<SlackNotification> Logger { get; }
protected override bool ValidateConfiguration(SlackNotificationSettings settings)
{
if (!settings.Enabled)
{
return false;
}
if (string.IsNullOrEmpty(settings.WebhookUrl))
{
return false;
}
try
{
var a = settings.Token;
var b = settings.Channel;
var c = settings.Service;
}
catch (IndexOutOfRangeException)
{
return false;
}
return true;
}
protected override async Task NewRequest(NotificationOptions model, SlackNotificationSettings settings)
{
var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.NewRequest, model);
var notification = new NotificationMessage
{
Message = parsed.Message,
};
notification.Other.Add("image", parsed.Image);
await Send(notification, settings);
}
protected override async Task Issue(NotificationOptions model, SlackNotificationSettings settings)
{
var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.Issue, model);
var notification = new NotificationMessage
{
Message = parsed.Message,
};
notification.Other.Add("image", parsed.Image);
await Send(notification, settings);
}
protected override async Task AddedToRequestQueue(NotificationOptions model, SlackNotificationSettings settings)
{
var user = string.Empty;
var title = string.Empty;
if (model.RequestType == RequestType.Movie)
{
user = MovieRequest.RequestedUser.UserAlias;
title = MovieRequest.Title;
}
else
{
user = TvRequest.RequestedUser.UserAlias;
title = TvRequest.ParentRequest.Title;
}
var message = $"Hello! The user '{user}' has requested {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(NotificationOptions model, SlackNotificationSettings settings)
{
var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.RequestDeclined, model);
var notification = new NotificationMessage
{
Message = parsed.Message,
};
notification.Other.Add("image", parsed.Image);
await Send(notification, settings);
}
protected override async Task RequestApproved(NotificationOptions model, SlackNotificationSettings settings)
{
var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.RequestApproved, model);
var notification = new NotificationMessage
{
Message = parsed.Message,
};
notification.Other.Add("image", parsed.Image);
await Send(notification, settings);
}
protected override async Task AvailableRequest(NotificationOptions model, SlackNotificationSettings settings)
{
var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.RequestAvailable, model);
var notification = new NotificationMessage
{
Message = parsed.Message,
};
notification.Other.Add("image", parsed.Image);
await Send(notification, settings);
}
protected override async Task Send(NotificationMessage model, SlackNotificationSettings settings)
{
try
{
var body = new SlackNotificationBody
{
channel = settings.Channel,
icon_emoji = settings.IconEmoji,
icon_url = settings.IconUrl,
text = model.Message,
username = settings.Username
};
await Api.PushAsync(settings.Team, settings.Token, settings.Service, body);
}
catch (Exception e)
{
Logger.LogError(LoggingEvents.SlackNotification, e, "Failed to send Slack Notification");
}
}
protected override async Task Test(NotificationOptions model, SlackNotificationSettings 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);
}
}
}

@ -11,6 +11,7 @@
<ItemGroup>
<ProjectReference Include="..\Ombi.Api.Discord\Ombi.Api.Discord.csproj" />
<ProjectReference Include="..\Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj" />
<ProjectReference Include="..\Ombi.Api.Slack\Ombi.Api.Slack.csproj" />
<ProjectReference Include="..\Ombi.Notifications.Templates\Ombi.Notifications.Templates.csproj" />
<ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" />
<ProjectReference Include="..\Ombi.Store\Ombi.Store.csproj" />

@ -0,0 +1,38 @@
using System;
using Newtonsoft.Json;
namespace Ombi.Settings.Settings.Models.Notifications
{
public class SlackNotificationSettings : Settings
{
public bool Enabled { get; set; }
public string WebhookUrl { get; set; }
public string Channel { get; set; }
public string Username { get; set; }
public string IconEmoji { get; set; }
public string IconUrl { get; set; }
[JsonIgnore]
public string Team => SplitWebUrl(3);
[JsonIgnore]
public string Service => SplitWebUrl(4);
[JsonIgnore]
public string Token => SplitWebUrl(5);
private string SplitWebUrl(int index)
{
if (!WebhookUrl.StartsWith("http", StringComparison.CurrentCultureIgnoreCase))
{
WebhookUrl = "https://" + WebhookUrl;
}
var split = WebhookUrl.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
return split.Length < index
? string.Empty
: split[index];
}
}
}

@ -73,6 +73,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.FanartTv", "Ombi.A
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Pushbullet", "Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj", "{E237CDF6-D044-437D-B157-E9A3CC0BCF53}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Slack", "Ombi.Api.Slack\Ombi.Api.Slack.csproj", "{71708256-9152-4E81-9FCA-E3181A185806}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -179,6 +181,10 @@ Global
{E237CDF6-D044-437D-B157-E9A3CC0BCF53}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E237CDF6-D044-437D-B157-E9A3CC0BCF53}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E237CDF6-D044-437D-B157-E9A3CC0BCF53}.Release|Any CPU.Build.0 = Release|Any CPU
{71708256-9152-4E81-9FCA-E3181A185806}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{71708256-9152-4E81-9FCA-E3181A185806}.Debug|Any CPU.Build.0 = Debug|Any CPU
{71708256-9152-4E81-9FCA-E3181A185806}.Release|Any CPU.ActiveCfg = Release|Any CPU
{71708256-9152-4E81-9FCA-E3181A185806}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -203,5 +209,6 @@ Global
{A0892896-F5BD-47E2-823E-DFCE82514EEC} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{FD947E63-A0D2-4878-8378-2005D5E9AB8A} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{E237CDF6-D044-437D-B157-E9A3CC0BCF53} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{71708256-9152-4E81-9FCA-E3181A185806} = {9293CA11-360A-4C20-A674-B9E794431BF5}
EndGlobalSection
EndGlobal

@ -44,12 +44,21 @@ export enum NotificationType {
ItemAddedToFaultQueue
}
export interface IDiscordNotifcationSettings extends INotificationSettings{
webhookUrl : string,
export interface IDiscordNotifcationSettings extends INotificationSettings {
webhookUrl: string,
username: string,
notificationTemplates: INotificationTemplates[],
}
export interface ISlackNotificationSettings extends INotificationSettings {
webhookUrl: string,
username: string,
channel: string,
iconEmoji: string,
iconUrl:string
notificationTemplates: INotificationTemplates[],
}
export interface IPushbulletNotificationSettings extends INotificationSettings {
accessToken: string,
notificationTemplates: INotificationTemplates[],

@ -4,7 +4,12 @@ import { Observable } from 'rxjs/Rx';
import { ServiceAuthHelpers } from '../service.helpers';
import { IDiscordNotifcationSettings, IEmailNotificationSettings, IPushbulletNotificationSettings } from '../../interfaces/INotifcationSettings'
import {
IDiscordNotifcationSettings,
IEmailNotificationSettings,
IPushbulletNotificationSettings,
ISlackNotificationSettings
} from '../../interfaces/INotifcationSettings'
@Injectable()
@ -21,6 +26,10 @@ export class TesterService extends ServiceAuthHelpers {
return this.http.post(`${this.url}pushbullet`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData);
}
slackTest(settings: ISlackNotificationSettings): Observable<boolean> {
return this.http.post(`${this.url}slack`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData);
}
emailTest(settings: IEmailNotificationSettings): Observable<boolean> {
return this.http.post(`${this.url}email`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData);
}

@ -13,7 +13,12 @@ import {
ICustomizationSettings,
IRadarrSettings
} from '../interfaces/ISettings';
import { IEmailNotificationSettings, IDiscordNotifcationSettings, IPushbulletNotificationSettings } from '../interfaces/INotifcationSettings';
import {
IEmailNotificationSettings,
IDiscordNotifcationSettings,
IPushbulletNotificationSettings,
ISlackNotificationSettings
} from '../interfaces/INotifcationSettings';
@Injectable()
export class SettingsService extends ServiceAuthHelpers {
@ -103,4 +108,12 @@ export class SettingsService extends ServiceAuthHelpers {
savePushbulletNotificationSettings(settings: IPushbulletNotificationSettings): Observable<boolean> {
return this.httpAuth.post(`${this.url}/notifications/pushbullet`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError)
}
getSlackNotificationSettings(): Observable<ISlackNotificationSettings> {
return this.httpAuth.get(`${this.url}/notifications/slack`).map(this.extractData).catch(this.handleError)
}
saveSlackNotificationSettings(settings: ISlackNotificationSettings): Observable<boolean> {
return this.httpAuth.post(`${this.url}/notifications/slack`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError)
}
}

@ -0,0 +1,84 @@

<settings-menu></settings-menu>
<div *ngIf="form">
<fieldset>
<legend>Slack 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 *ngIf="form.invalid && form.dirty" class="alert alert-danger">
<div *ngIf="form.get('webhookUrl').hasError('required')">The Webhook Url is required</div>
</div>
<div class="form-group">
<label for="webhookUrl" class="control-label">Webhook Url</label>
<div>
<small class="control-label"> Click <a target="_blank" href="https://my.slack.com/services/new/incoming-webhook/">Here</a> and follow the guide. You will then have a Webhook Url</small>
<input type="text" class="form-control form-control-custom " id="webhookUrl" name="webhookUrl" formControlName="webhookUrl">
</div>
</div>
<div class="form-group">
<label for="username" class="control-label">Username Override</label>
<div>
<input type="text" class="form-control form-control-custom " id="username" name="username" formControlName="username" pTooltip="Optional, this will override the username you used for the Webhook. Default is Ombi">
</div>
</div>
<div class="form-group">
<label for="channel" class="control-label">Channel Override</label>
<div>
<input type="text" class="form-control form-control-custom " id="channel" name="channel" formControlName="channel" pTooltip="Optional, this will override the channel you used for the Webhook">
</div>
</div>
<div class="form-group">
<label for="iconEmoji" class="control-label">Emoji Icon Override</label>
<div>
<input type="text" class="form-control form-control-custom " id="iconEmoji" name="iconEmoji" formControlName="iconEmoji" pTooltip="Optional, this will override the Icon you used for the Webhook">
</div>
</div>
<div class="form-group">
<label for="iconUrl" class="control-label">Url Icon Override</label>
<div>
<input type="text" class="form-control form-control-custom " id="iconUrl" name="iconUrl" formControlName="iconUrl" pTooltip="Optional, this will override the Icon you used for the Webhook">
</div>
</div>
<small>You can find more details about the Slack API <a target="_blank" href="https://api.slack.com/custom-integrations/incoming-webhooks">Here</a></small>
<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>
<div class="col-md-6">
<notification-templates [templates]="templates"></notification-templates>
</div>
</fieldset>
</div>

@ -0,0 +1,85 @@
import { Component, OnInit } from '@angular/core';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { INotificationTemplates, ISlackNotificationSettings, NotificationType } from '../../interfaces/INotifcationSettings';
import { SettingsService } from '../../services/settings.service';
import { NotificationService } from "../../services/notification.service";
import { TesterService } from "../../services/applications/tester.service";
@Component({
templateUrl: './slack.component.html',
})
export class SlackComponent implements OnInit {
constructor(private settingsService: SettingsService,
private notificationService: NotificationService,
private fb: FormBuilder,
private testerService : TesterService) { }
NotificationType = NotificationType;
templates: INotificationTemplates[];
form: FormGroup;
ngOnInit(): void {
this.settingsService.getSlackNotificationSettings().subscribe(x => {
this.templates = x.notificationTemplates;
this.form = this.fb.group({
enabled: [x.enabled],
username: [x.username],
webhookUrl: [x.webhookUrl, [Validators.required]],
iconEmoji: [x.iconEmoji],
iconUrl: [x.iconUrl],
channel: [x.channel]
});
});
}
onSubmit(form: FormGroup) {
if (form.invalid) {
this.notificationService.error("Validation", "Please check your entered values");
return
}
var settings = <ISlackNotificationSettings>form.value;
if (settings.iconEmoji && settings.iconUrl) {
this.notificationService.error("Validation", "You cannot have a Emoji icon and a URL icon");
return;
}
settings.notificationTemplates = this.templates;
this.settingsService.saveSlackNotificationSettings(settings).subscribe(x => {
if (x) {
this.notificationService.success("Settings Saved", "Successfully saved the Slack settings");
} else {
this.notificationService.success("Settings Saved", "There was an error when saving the Slack settings");
}
});
}
test(form: FormGroup) {
if (form.invalid) {
this.notificationService.error("Validation", "Please check your entered values");
return
}
var settings = <ISlackNotificationSettings>form.value;
if (settings.iconEmoji && settings.iconUrl) {
this.notificationService.error("Validation", "You cannot have a Emoji icon and a URL icon");
return;
}
this.testerService.slackTest(settings).subscribe(x => {
if (x) {
this.notificationService.success("Successful", "Successfully sent a Slack message, please check the discord channel");
} else {
this.notificationService.success("Error", "There was an error when sending the Slack message. Please check your settings");
}
})
}
}

@ -21,6 +21,7 @@ import { LandingPageComponent } from './landingpage/landingpage.component';
import { CustomizationComponent } from './customization/customization.component';
import { EmailNotificationComponent } from './notifications/emailnotification.component';
import { DiscordComponent } from './notifications/discord.component';
import { SlackComponent } from './notifications/slack.component';
import { NotificationTemplate } from './notifications/notificationtemplate.component';
import { SettingsMenuComponent } from './settingsmenu.component';
@ -38,6 +39,7 @@ const routes: Routes = [
{ path: 'Settings/Customization', component: CustomizationComponent, canActivate: [AuthGuard] },
{ path: 'Settings/Email', component: EmailNotificationComponent, canActivate: [AuthGuard] },
{ path: 'Settings/Discord', component: DiscordComponent, canActivate: [AuthGuard] },
{ path: 'Settings/Slack', component: SlackComponent, canActivate: [AuthGuard] },
];
@NgModule({
@ -65,6 +67,7 @@ const routes: Routes = [
CustomizationComponent,
DiscordComponent,
SonarrComponent,
SlackComponent,
RadarrComponent,
EmailNotificationComponent,
HumanizePipe,

@ -45,6 +45,7 @@
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Email']">Email</a></li>
<!--<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Newsletter']">Newsletter</a></li>-->
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Discord']">Discord</a></li>
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Slack']">Discord</a></li>
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Pushbullet']">Pushbullet</a></li>
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Pushover']">Pushover</a></li>
</ul>

@ -24,19 +24,23 @@ namespace Ombi.Controllers.External
/// <param name="service">The service.</param>
/// <param name="notification">The notification.</param>
/// <param name="emailN">The notification.</param>
/// <param name="pushbullet">The pushbullet.</param>
/// <param name="slack">The slack.</param>
public TesterController(INotificationService service, IDiscordNotification notification, IEmailNotification emailN,
IPushbulletNotification pushbullet)
IPushbulletNotification pushbullet, ISlackNotification slack)
{
Service = service;
DiscordNotification = notification;
EmailNotification = emailN;
PushbulletNotification = pushbullet;
SlackNotification = slack;
}
private INotificationService Service { get; }
private IDiscordNotification DiscordNotification { get; }
private IEmailNotification EmailNotification { get; }
private IPushbulletNotification PushbulletNotification { get; }
private ISlackNotification SlackNotification { get; }
/// <summary>
@ -52,10 +56,10 @@ namespace Ombi.Controllers.External
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true;
}
}
/// <summary>
/// Sends a test message to discord using the provided settings
/// Sends a test message to Pushbullet using the provided settings
/// </summary>
/// <param name="settings">The settings.</param>
/// <returns></returns>
@ -69,6 +73,22 @@ namespace Ombi.Controllers.External
return true;
}
/// <summary>
/// Sends a test message to Slack using the provided settings
/// </summary>
/// <param name="settings">The settings.</param>
/// <returns></returns>
[HttpPost("slack")]
public bool Slack([FromBody] SlackNotificationSettings settings)
{
settings.Enabled = true;
SlackNotification.NotifyAsync(
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true;
}
/// <summary>
/// Sends a test message via email to the admin email using the provided settings
/// </summary>

@ -295,6 +295,41 @@ namespace Ombi.Controllers
return model;
}
/// <summary>
/// Saves the slack notification settings.
/// </summary>
/// <param name="model">The model.</param>
/// <returns></returns>
[HttpPost("notifications/slack")]
public async Task<bool> SlacktNotificationSettings([FromBody] SlackNotificationsViewModel model)
{
// Save the email settings
var settings = Mapper.Map<SlackNotificationSettings>(model);
var result = await Save(settings);
// Save the templates
await TemplateRepository.UpdateRange(model.NotificationTemplates);
return result;
}
/// <summary>
/// Gets the slack Notification Settings.
/// </summary>
/// <returns></returns>
[HttpGet("notifications/slack")]
public async Task<SlackNotificationsViewModel> SlackNotificationSettings()
{
var settings = await Get<SlackNotificationSettings>();
var model = Mapper.Map<SlackNotificationsViewModel>(settings);
// Lookup to see if we have any templates saved
model.NotificationTemplates = await BuildTemplates(NotificationAgent.Slack);
return model;
}
private async Task<List<NotificationTemplates>> BuildTemplates(NotificationAgent agent)
{
var templates = await TemplateRepository.GetAllTemplates(agent);

@ -76,5 +76,11 @@
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.Api.TheMovieDb.csproj" />
<ProjectReference Include="..\Ombi.Updater\Ombi.Updater.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="ClientApp\app\settings\notifications\slack.component.js">
<DependentUpon>slack.component.ts</DependentUpon>
</None>
</ItemGroup>
</Project>

Loading…
Cancel
Save