mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-14 02:26:55 -07:00
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
This commit is contained in:
parent
c5b7b673b1
commit
10cc0c0951
14 changed files with 80 additions and 31 deletions
|
@ -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…
Add table
Add a link
Reference in a new issue