feat(notifications): Send new request email notifications to power users (#4462)

* Send new request email notifications to power users

* Send new request to power users as convention

Remove option to toggle it off

* Send New Request notification to power users in app

* Better wording + fix mobile notifications
pull/4473/head
sephrat 2 years ago committed by GitHub
parent c5b7b673b1
commit 10cc0c0951
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Ombi.Api.Discord;
using Ombi.Api.Discord.Models;
@ -21,8 +22,8 @@ namespace Ombi.Notifications.Agents
public DiscordNotification(IDiscordApi api, ISettingsService<DiscordNotificationSettings> sn,
ILogger<DiscordNotification> 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)
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um)
: base(sn, r, m, t, s, log, sub, music, userPref, um)
{
Api = api;
Logger = log;

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MailKit.Net.Smtp;
@ -22,7 +23,7 @@ namespace Ombi.Notifications.Agents
{
public EmailNotification(ISettingsService<EmailNotificationSettings> settings, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, IEmailProvider prov, ISettingsService<CustomizationSettings> c,
ILogger<EmailNotification> log, UserManager<OmbiUser> um, IRepository<RequestSubscription> sub, IMusicRequestRepository music,
IRepository<UserNotificationPreferences> userPref) : base(settings, r, m, t, c, log, sub, music, userPref)
IRepository<UserNotificationPreferences> userPref) : base(settings, r, m, t, c, log, sub, music, userPref, um)
{
EmailProvider = prov;
Logger = log;
@ -114,7 +115,15 @@ namespace Ombi.Notifications.Agents
var plaintext = await LoadPlainTextMessage(NotificationType.NewRequest, model, settings);
message.Other.Add("PlainTextBody", plaintext);
await Send(message, settings);
foreach (var recipient in (await GetPrivilegedUsers()).DistinctBy(x => x.Email))
{
if (recipient.Email.IsNullOrEmpty())
{
continue;
}
message.To = recipient.Email;
await Send(message, settings);
}
}
protected override async Task NewIssue(NotificationOptions model, EmailNotificationSettings settings)

@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Ombi.Api.Gotify;
using Ombi.Core.Settings;
@ -17,7 +18,7 @@ namespace Ombi.Notifications.Agents
{
public GotifyNotification(IGotifyApi api, ISettingsService<GotifySettings> sn, ILogger<GotifyNotification> 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)
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um) : base(sn, r, m, t, s, log, sub, music, userPref, um)
{
Api = api;
Logger = log;

@ -23,7 +23,7 @@ namespace Ombi.Notifications.Agents
public LegacyMobileNotification(IOneSignalApi api, ISettingsService<MobileNotificationSettings> sn, ILogger<LegacyMobileNotification> log, INotificationTemplatesRepository r,
IMovieRequestRepository m, ITvRequestRepository t, ISettingsService<CustomizationSettings> s, IRepository<NotificationUserId> notification,
UserManager<OmbiUser> um, IRepository<RequestSubscription> sub, IMusicRequestRepository music, IRepository<Issues> issueRepository,
IRepository<UserNotificationPreferences> userPref) : base(sn, r, m, t, s, log, sub, music, userPref)
IRepository<UserNotificationPreferences> userPref) : base(sn, r, m, t, s, log, sub, music, userPref, um)
{
_api = api;
_logger = log;
@ -59,7 +59,7 @@ namespace Ombi.Notifications.Agents
};
// Get admin devices
var playerIds = await GetAdmins(NotificationType.NewRequest);
var playerIds = await GetPrivilegedUsersPlayerIds();
await Send(playerIds, notification, settings, model, true);
}
@ -77,7 +77,7 @@ namespace Ombi.Notifications.Agents
};
// Get admin devices
var playerIds = await GetAdmins(NotificationType.Issue);
var playerIds = await GetAdmins();
await Send(playerIds, notification, settings, model);
}
@ -106,7 +106,7 @@ namespace Ombi.Notifications.Agents
else
{
// Send to admin
var playerIds = await GetAdmins(NotificationType.IssueComment);
var playerIds = await GetAdmins();
await Send(playerIds, notification, settings, model);
}
}
@ -147,7 +147,7 @@ namespace Ombi.Notifications.Agents
};
// Get admin devices
var playerIds = await GetAdmins(NotificationType.Test);
var playerIds = await GetAdmins();
await Send(playerIds, notification, settings, model);
}
@ -241,15 +241,25 @@ namespace Ombi.Notifications.Agents
await Send(playerIds, notification, settings, model);
}
private async Task<List<string>> GetAdmins(NotificationType type)
private async Task<List<string>> GetAdmins()
{
var adminUsers = (await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin)).Select(x => x.Id).ToList();
return await GetNotificationRecipients(await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin));
}
private async Task<List<string>> GetPrivilegedUsersPlayerIds()
{
return await GetNotificationRecipients(await GetPrivilegedUsers());
}
private async Task<List<string>> GetNotificationRecipients(IEnumerable<OmbiUser> users)
{
var adminUsers = users.Select(x => x.Id).ToList();
var notificationUsers = _notifications.GetAll().Include(x => x.User).Where(x => adminUsers.Contains(x.UserId));
var playerIds = await notificationUsers.Select(x => x.PlayerId).ToListAsync();
if (!playerIds.Any())
{
_logger.LogInformation(
$"there are no admins to send a notification for {type}, for agent {NotificationAgent.Mobile}");
$"there are no users to send a notification for agent {NotificationAgent.Mobile}");
return null;
}
return playerIds;

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Ombi.Api.Mattermost;
using Ombi.Api.Mattermost.Models;
@ -19,7 +20,7 @@ namespace Ombi.Notifications.Agents
{
public MattermostNotification(IMattermostApi api, ISettingsService<MattermostNotificationSettings> sn, ILogger<MattermostNotification> 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)
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um) : base(sn, r, m, t, s, log, sub, music, userPref, um)
{
Api = api;
Logger = log;

@ -23,7 +23,7 @@ namespace Ombi.Notifications.Agents
public MobileNotification(ICloudMobileNotification api, ISettingsService<MobileNotificationSettings> sn, ILogger<MobileNotification> log, INotificationTemplatesRepository r,
IMovieRequestRepository m, ITvRequestRepository t, ISettingsService<CustomizationSettings> s, IRepository<MobileDevices> notification,
UserManager<OmbiUser> um, IRepository<RequestSubscription> sub, IMusicRequestRepository music, IRepository<Issues> issueRepository,
IRepository<UserNotificationPreferences> userPref) : base(sn, r, m, t, s, log, sub, music, userPref)
IRepository<UserNotificationPreferences> userPref) : base(sn, r, m, t, s, log, sub, music, userPref, um)
{
_api = api;
_logger = log;
@ -62,7 +62,7 @@ namespace Ombi.Notifications.Agents
};
// Get admin devices
var playerIds = await GetAdmins(NotificationType.NewRequest);
var playerIds = await GetPrivilegedUsersPlayerIds();
await Send(playerIds, notification, settings, model, true);
}
@ -82,7 +82,7 @@ namespace Ombi.Notifications.Agents
};
// Get admin devices
var playerIds = await GetAdmins(NotificationType.Issue);
var playerIds = await GetAdmins();
await Send(playerIds, notification, settings, model);
}
@ -112,7 +112,7 @@ namespace Ombi.Notifications.Agents
else
{
// Send to admin
var playerIds = await GetAdmins(NotificationType.IssueComment);
var playerIds = await GetAdmins();
await Send(playerIds, notification, settings, model);
}
}
@ -157,7 +157,7 @@ namespace Ombi.Notifications.Agents
};
// Get admin devices
var playerIds = await GetAdmins(NotificationType.Test);
var playerIds = await GetAdmins();
await Send(playerIds, notification, settings, model);
}
@ -279,15 +279,25 @@ namespace Ombi.Notifications.Agents
await Send(playerIds, notification, settings, model);
}
private async Task<List<string>> GetAdmins(NotificationType type)
private async Task<List<string>> GetAdmins()
{
var adminUsers = (await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin)).Select(x => x.Id).ToList();
return await GetNotificationRecipients(await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin));
}
private async Task<List<string>> GetPrivilegedUsersPlayerIds()
{
return await GetNotificationRecipients(await GetPrivilegedUsers());
}
private async Task<List<string>> GetNotificationRecipients(IEnumerable<OmbiUser> users)
{
var adminUsers = users.Select(x => x.Id).ToList();
var notificationUsers = _notifications.GetAll().Include(x => x.User).Where(x => adminUsers.Contains(x.UserId));
var playerIds = await notificationUsers.Select(x => x.Token).ToListAsync();
if (!playerIds.Any())
{
_logger.LogInformation(
$"there are no admins to send a notification for {type}, for agent {NotificationAgent.Mobile}");
$"there are no users to send a notification for agent {NotificationAgent.Mobile}");
return null;
}
return playerIds;
@ -377,7 +387,7 @@ namespace Ombi.Notifications.Agents
};
// Get admin devices
var playerIds = await GetAdmins(NotificationType.PartiallyAvailable);
var playerIds = await GetAdmins();
await Send(playerIds, notification, settings, model, true);
}
}

@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Ombi.Api.Pushbullet;
using Ombi.Core.Settings;
@ -17,7 +18,7 @@ namespace Ombi.Notifications.Agents
{
public PushbulletNotification(IPushbulletApi api, ISettingsService<PushbulletSettings> sn, ILogger<PushbulletNotification> 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)
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um) : base(sn, r, m, t, s, log, sub, music, userPref, um)
{
Api = api;
Logger = log;

@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Ombi.Api.Pushbullet;
using Ombi.Api.Pushover;
@ -18,7 +19,7 @@ namespace Ombi.Notifications.Agents
{
public PushoverNotification(IPushoverApi api, ISettingsService<PushoverSettings> sn, ILogger<PushoverNotification> 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)
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um) : base(sn, r, m, t, s, log, sub, music, userPref, um)
{
Api = api;
Logger = log;

@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Ombi.Api.Slack;
using Ombi.Api.Slack.Models;
@ -18,7 +19,7 @@ namespace Ombi.Notifications.Agents
{
public SlackNotification(ISlackApi api, ISettingsService<SlackNotificationSettings> sn, ILogger<SlackNotification> 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)
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um) : base(sn, r, m, t, s, log, sub, music, userPref, um)
{
Api = api;
Logger = log;

@ -10,6 +10,7 @@ using Ombi.Store.Entities;
using Ombi.Store.Repository;
using Ombi.Store.Repository.Requests;
using Ombi.Api.Telegram;
using Microsoft.AspNetCore.Identity;
namespace Ombi.Notifications.Agents
{
@ -19,7 +20,7 @@ namespace Ombi.Notifications.Agents
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)
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um) : base(sn, r, m, t,s,log, sub, music, userPref, um)
{
Api = api;
Logger = log;

@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Ombi.Api.Webhook;
using Ombi.Core.Settings;
@ -18,7 +19,7 @@ namespace Ombi.Notifications.Agents
{
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)
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um) : base(sn, r, m, t, s, log, sub, music, userPref, um)
{
Api = api;
Logger = log;

@ -10,6 +10,7 @@ using Ombi.Store.Entities;
using Ombi.Store.Repository;
using Ombi.Store.Repository.Requests;
using Ombi.Api.Twilio;
using Microsoft.AspNetCore.Identity;
namespace Ombi.Notifications.Agents
{
@ -19,7 +20,7 @@ namespace Ombi.Notifications.Agents
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)
IRepository<UserNotificationPreferences> userPref, UserManager<OmbiUser> um) : base(sn, r, m, t,s,log, sub, music, userPref, um)
{
Api = api;
Logger = log;

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Core.Settings;
@ -19,7 +21,7 @@ namespace Ombi.Notifications
{
protected BaseNotification(ISettingsService<T> settings, INotificationTemplatesRepository templateRepo, IMovieRequestRepository movie, ITvRequestRepository tv,
ISettingsService<CustomizationSettings> customization, ILogger<BaseNotification<T>> log, IRepository<RequestSubscription> sub, IMusicRequestRepository album,
IRepository<UserNotificationPreferences> notificationUserPreferences)
IRepository<UserNotificationPreferences> notificationUserPreferences, UserManager<OmbiUser> um)
{
Settings = settings;
TemplateRepository = templateRepo;
@ -30,6 +32,7 @@ namespace Ombi.Notifications
_log = log;
AlbumRepository = album;
UserNotificationPreferences = notificationUserPreferences;
_userManager = um;
Settings.ClearCache();
}
@ -43,6 +46,7 @@ namespace Ombi.Notifications
protected IRepository<UserNotificationPreferences> UserNotificationPreferences { get; set; }
private ISettingsService<CustomizationSettings> CustomizationSettings { get; }
private readonly ILogger<BaseNotification<T>> _log;
private readonly UserManager<OmbiUser> _userManager;
protected ChildRequests TvRequest { get; set; }
@ -210,6 +214,13 @@ namespace Ombi.Notifications
.FirstOrDefault(x => x.Agent == agent && x.UserId == userId);
}
protected async Task<IEnumerable<OmbiUser>> GetPrivilegedUsers()
{
IEnumerable<OmbiUser> recipients = await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin);
recipients = recipients.Concat(await _userManager.GetUsersInRoleAsync(OmbiRoles.PowerUser));
return recipients;
}
private NotificationMessageContent Parse(NotificationOptions model, NotificationTemplates template, NotificationAgent agent)
{
var resolver = new NotificationMessageResolver();

@ -61,7 +61,7 @@
<div class="md-form-field">
<mat-form-field appearance="outline">
<mat-label>Admin Email</mat-label>
<input matInput formControlName="adminEmail" matTooltip="The administrator email will be used to send emails for admin only notifications (e.g. New Requests that require approvals)">
<input matInput formControlName="adminEmail" matTooltip="The administrator email will be used to send emails for admin only notifications (e.g. raised issues)">
<mat-error *ngIf="emailForm.get('adminEmail').hasError('required')">
Admin Email is <strong>required</strong>
</mat-error>

Loading…
Cancel
Save