feat(notif): include requested season numbers in notifications (#1211)

This commit is contained in:
TheCatLady
2021-03-18 22:07:22 -04:00
committed by GitHub
parent 4a5a9cce48
commit 4ee78ab2fe
10 changed files with 209 additions and 161 deletions

View File

@@ -179,7 +179,7 @@ export class MediaRequest {
subject: movie.title,
message: movie.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
notifyUser: this.requestedBy,
notifyUser: autoApproved ? undefined : this.requestedBy,
media,
request: this,
}
@@ -444,15 +444,10 @@ export class MediaRequest {
label: 'Media Request',
}
);
const userRepository = getRepository(User);
const admin = await userRepository.findOneOrFail({
select: ['id', 'plexToken'],
order: { id: 'ASC' },
});
notificationManager.sendNotification(Notification.MEDIA_FAILED, {
subject: movie.title,
message: 'Movie failed to add to Radarr',
notifyUser: admin,
message: movie.overview,
media,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
request: this,
@@ -641,14 +636,10 @@ export class MediaRequest {
label: 'Media Request',
}
);
const userRepository = getRepository(User);
const admin = await userRepository.findOneOrFail({
order: { id: 'ASC' },
});
notificationManager.sendNotification(Notification.MEDIA_FAILED, {
subject: series.name,
message: 'Series failed to add to Sonarr',
notifyUser: admin,
message: series.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${series.poster_path}`,
media,
extra: [

View File

@@ -6,7 +6,7 @@ import { NotificationAgentConfig } from '../../settings';
export interface NotificationPayload {
subject: string;
notifyUser: User;
notifyUser?: User;
media?: Media;
image?: string;
message?: string;
@@ -21,15 +21,9 @@ export abstract class BaseAgent<T extends NotificationAgentConfig> {
}
protected abstract getSettings(): T;
protected userNotificationTypes: Notification[] = [
Notification.MEDIA_APPROVED,
Notification.MEDIA_DECLINED,
Notification.MEDIA_AVAILABLE,
];
}
export interface NotificationAgent {
shouldSend(type: Notification, payload: NotificationPayload): boolean;
shouldSend(type: Notification): boolean;
send(type: Notification, payload: NotificationPayload): Promise<boolean>;
}

View File

@@ -107,7 +107,7 @@ class DiscordAgent
if (payload.request) {
fields.push({
name: 'Requested By',
value: payload.notifyUser.displayName ?? '',
value: payload.request?.requestedBy.displayName ?? '',
inline: true,
});
}
@@ -217,7 +217,7 @@ class DiscordAgent
let content = undefined;
if (
this.userNotificationTypes.includes(type) &&
payload.notifyUser &&
payload.notifyUser.settings?.enableNotifications &&
payload.notifyUser.settings?.discordId
) {

View File

@@ -22,13 +22,12 @@ class EmailAgent
return settings.notifications.agents.email;
}
public shouldSend(type: Notification, payload: NotificationPayload): boolean {
public shouldSend(type: Notification): boolean {
const settings = this.getSettings();
if (
settings.enabled &&
hasNotificationType(type, this.getSettings().types) &&
(payload.notifyUser.settings?.enableNotifications ?? true)
hasNotificationType(type, this.getSettings().types)
) {
return true;
}
@@ -45,9 +44,13 @@ class EmailAgent
// Send to all users with the manage requests permission (or admins)
users
.filter((user) => user.hasPermission(Permission.MANAGE_REQUESTS))
.filter(
(user) =>
user.hasPermission(Permission.MANAGE_REQUESTS) &&
(user.settings?.enableNotifications ?? true)
)
.forEach((user) => {
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
const email = new PreparedEmail(user.settings?.pgpKey);
email.send({
template: path.join(
@@ -62,9 +65,11 @@ class EmailAgent
payload.media?.mediaType === MediaType.TV ? 'series' : 'movie'
}!`,
mediaName: payload.subject,
mediaPlot: payload.message,
mediaExtra: payload.extra ?? [],
imageUrl: payload.image,
timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.displayName,
requestedBy: payload.request?.requestedBy.displayName,
actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
@@ -95,9 +100,13 @@ class EmailAgent
// Send to all users with the manage requests permission (or admins)
users
.filter((user) => user.hasPermission(Permission.MANAGE_REQUESTS))
.filter(
(user) =>
user.hasPermission(Permission.MANAGE_REQUESTS) &&
(user.settings?.enableNotifications ?? true)
)
.forEach((user) => {
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
const email = new PreparedEmail(user.settings?.pgpKey);
email.send({
template: path.join(
@@ -112,11 +121,12 @@ class EmailAgent
payload.media?.mediaType === MediaType.TV ? 'series' : 'movie'
} could not be added to ${
payload.media?.mediaType === MediaType.TV ? 'Sonarr' : 'Radarr'
}`,
}:`,
mediaName: payload.subject,
mediaPlot: payload.message,
imageUrl: payload.image,
timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.displayName,
requestedBy: payload.request?.requestedBy.displayName,
actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
@@ -142,6 +152,10 @@ class EmailAgent
// This is getting main settings for the whole app
const { applicationUrl, applicationTitle } = getSettings().main;
try {
if (
payload.notifyUser &&
payload.notifyUser.settings?.enableNotifications
) {
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
await email.send({
@@ -157,9 +171,10 @@ class EmailAgent
payload.media?.mediaType === MediaType.TV ? 'series' : 'movie'
} has been approved:`,
mediaName: payload.subject,
mediaExtra: payload.extra ?? [],
imageUrl: payload.image,
timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.displayName,
requestedBy: payload.request?.requestedBy.displayName,
actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
@@ -170,6 +185,8 @@ class EmailAgent
} Request Approved`,
},
});
}
return true;
} catch (e) {
logger.error('Email notification failed to send', {
@@ -189,7 +206,11 @@ class EmailAgent
// Send to all users with the manage requests permission (or admins)
users
.filter((user) => user.hasPermission(Permission.MANAGE_REQUESTS))
.filter(
(user) =>
user.hasPermission(Permission.MANAGE_REQUESTS) &&
(user.settings?.enableNotifications ?? true)
)
.forEach((user) => {
const email = new PreparedEmail();
@@ -206,9 +227,10 @@ class EmailAgent
payload.media?.mediaType === MediaType.TV ? 'series' : 'movie'
} has been automatically approved:`,
mediaName: payload.subject,
mediaExtra: payload.extra ?? [],
imageUrl: payload.image,
timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.displayName,
requestedBy: payload.request?.requestedBy.displayName,
actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
@@ -234,6 +256,10 @@ class EmailAgent
// This is getting main settings for the whole app
const { applicationUrl, applicationTitle } = getSettings().main;
try {
if (
payload.notifyUser &&
payload.notifyUser.settings?.enableNotifications
) {
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
await email.send({
@@ -249,9 +275,10 @@ class EmailAgent
payload.media?.mediaType === MediaType.TV ? 'series' : 'movie'
} was declined:`,
mediaName: payload.subject,
mediaExtra: payload.extra ?? [],
imageUrl: payload.image,
timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.displayName,
requestedBy: payload.request?.requestedBy.displayName,
actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
@@ -262,6 +289,8 @@ class EmailAgent
} Request Declined`,
},
});
}
return true;
} catch (e) {
logger.error('Email notification failed to send', {
@@ -276,6 +305,10 @@ class EmailAgent
// This is getting main settings for the whole app
const { applicationUrl, applicationTitle } = getSettings().main;
try {
if (
payload.notifyUser &&
payload.notifyUser.settings?.enableNotifications
) {
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
await email.send({
@@ -291,9 +324,10 @@ class EmailAgent
payload.media?.mediaType === MediaType.TV ? 'series' : 'movie'
} you requested is now available!`,
mediaName: payload.subject,
mediaExtra: payload.extra ?? [],
imageUrl: payload.image,
timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.displayName,
requestedBy: payload.request?.requestedBy.displayName,
actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
@@ -304,6 +338,8 @@ class EmailAgent
} Now Available`,
},
});
}
return true;
} catch (e) {
logger.error('Email notification failed to send', {
@@ -318,6 +354,7 @@ class EmailAgent
// This is getting main settings for the whole app
const { applicationUrl, applicationTitle } = getSettings().main;
try {
if (payload.notifyUser) {
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
await email.send({
@@ -331,6 +368,8 @@ class EmailAgent
applicationTitle,
},
});
}
return true;
} catch (e) {
logger.error('Email notification failed to send', {

View File

@@ -47,7 +47,7 @@ class PushbulletAgent
const title = payload.subject;
const plot = payload.message;
const username = payload.notifyUser.displayName;
const username = payload.request?.requestedBy.displayName;
switch (type) {
case Notification.MEDIA_PENDING:
@@ -122,6 +122,10 @@ class PushbulletAgent
break;
}
for (const extra of payload.extra ?? []) {
message += `\n${extra.name}: ${extra.value}`;
}
return {
title: messageTitle,
body: message,

View File

@@ -61,7 +61,7 @@ class PushoverAgent
const title = payload.subject;
const plot = payload.message;
const username = payload.notifyUser.displayName;
const username = payload.request?.requestedBy.displayName;
switch (type) {
case Notification.MEDIA_PENDING:
@@ -70,10 +70,10 @@ class PushoverAgent
} Request`;
message += `<b>${title}</b>`;
if (plot) {
message += `\n${plot}`;
message += `<small>\n${plot}</small>`;
}
message += `\n\n<b>Requested By</b>\n${username}`;
message += `\n\n<b>Status</b>\nPending Approval`;
message += `<small>\n\n<b>Requested By</b>\n${username}</small>`;
message += `<small>\n\n<b>Status</b>\nPending Approval</small>`;
break;
case Notification.MEDIA_APPROVED:
messageTitle = `${
@@ -81,10 +81,10 @@ class PushoverAgent
} Request Approved`;
message += `<b>${title}</b>`;
if (plot) {
message += `\n${plot}`;
message += `<small>\n${plot}</small>`;
}
message += `\n\n<b>Requested By</b>\n${username}`;
message += `\n\n<b>Status</b>\nProcessing`;
message += `<small>\n\n<b>Requested By</b>\n${username}</small>`;
message += `<small>\n\n<b>Status</b>\nProcessing</small>`;
break;
case Notification.MEDIA_AUTO_APPROVED:
messageTitle = `${
@@ -92,10 +92,10 @@ class PushoverAgent
} Request Automatically Approved`;
message += `<b>${title}</b>`;
if (plot) {
message += `\n${plot}`;
message += `<small>\n${plot}</small>`;
}
message += `\n\n<b>Requested By</b>\n${username}`;
message += `\n\n<b>Status</b>\nProcessing`;
message += `<small>\n\n<b>Requested By</b>\n${username}</small>`;
message += `<small>\n\n<b>Status</b>\nProcessing</small>`;
break;
case Notification.MEDIA_AVAILABLE:
messageTitle = `${
@@ -103,10 +103,10 @@ class PushoverAgent
} Now Available`;
message += `<b>${title}</b>`;
if (plot) {
message += `\n${plot}`;
message += `<small>\n${plot}</small>`;
}
message += `\n\n<b>Requested By</b>\n${username}`;
message += `\n\n<b>Status</b>\nAvailable`;
message += `<small>\n\n<b>Requested By</b>\n${username}</small>`;
message += `<small>\n\n<b>Status</b>\nAvailable</small>`;
break;
case Notification.MEDIA_DECLINED:
messageTitle = `${
@@ -114,10 +114,10 @@ class PushoverAgent
} Request Declined`;
message += `<b>${title}</b>`;
if (plot) {
message += `\n${plot}`;
message += `<small>\n${plot}</small>`;
}
message += `\n\n<b>Requested By</b>\n${username}`;
message += `\n\n<b>Status</b>\nDeclined`;
message += `<small>\n\n<b>Requested By</b>\n${username}</small>`;
message += `<small>\n\n<b>Status</b>\nDeclined</small>`;
priority = 1;
break;
case Notification.MEDIA_FAILED:
@@ -126,18 +126,22 @@ class PushoverAgent
} Request`;
message += `<b>${title}</b>`;
if (plot) {
message += `\n${plot}`;
message += `<small>\n${plot}</small>`;
}
message += `\n\n<b>Requested By</b>\n${username}`;
message += `\n\n<b>Status</b>\nFailed`;
message += `<small>\n\n<b>Requested By</b>\n${username}</small>`;
message += `<small>\n\n<b>Status</b>\nFailed</small>`;
priority = 1;
break;
case Notification.TEST_NOTIFICATION:
messageTitle = 'Test Notification';
message += `${plot}`;
message += `<small>${plot}</small>`;
break;
}
for (const extra of payload.extra ?? []) {
message += `<small>\n\n<b>${extra.name}</b>\n${extra.value}</small>`;
}
if (settings.main.applicationUrl && payload.media) {
url = `${settings.main.applicationUrl}/${payload.media.mediaType}/${payload.media.tmdbId}`;
url_title = `Open in ${settings.main.applicationTitle}`;

View File

@@ -67,7 +67,9 @@ class SlackAgent
if (payload.request) {
fields.push({
type: 'mrkdwn',
text: `*Requested By*\n${payload.notifyUser.displayName ?? ''}`,
text: `*Requested By*\n${
payload.request?.requestedBy.displayName ?? ''
}`,
});
}
@@ -131,6 +133,13 @@ class SlackAgent
break;
}
for (const extra of payload.extra ?? []) {
fields.push({
type: 'mrkdwn',
text: `*${extra.name}*\n${extra.value}`,
});
}
if (settings.main.applicationUrl && payload.media) {
actionUrl = `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`;
}

View File

@@ -61,7 +61,7 @@ class TelegramAgent
const title = this.escapeText(payload.subject);
const plot = this.escapeText(payload.message);
const user = this.escapeText(payload.notifyUser.displayName);
const user = this.escapeText(payload.request?.requestedBy.displayName);
const applicationTitle = this.escapeText(settings.main.applicationTitle);
/* eslint-disable no-useless-escape */
@@ -138,6 +138,10 @@ class TelegramAgent
break;
}
for (const extra of payload.extra ?? []) {
message += `\n\n\*${extra.name}\*\n${extra.value}`;
}
if (settings.main.applicationUrl && payload.media) {
const actionUrl = `${settings.main.applicationUrl}/${payload.media.mediaType}/${payload.media.tmdbId}`;
message += `\n\n\[Open in ${applicationTitle}\]\(${actionUrl}\)`;
@@ -175,7 +179,7 @@ class TelegramAgent
// Send user notification
if (
this.userNotificationTypes.includes(type) &&
payload.notifyUser &&
payload.notifyUser.settings?.enableNotifications &&
payload.notifyUser.settings?.telegramChatId &&
payload.notifyUser.settings?.telegramChatId !==

View File

@@ -50,7 +50,7 @@ class NotificationManager {
label: 'Notifications',
});
this.activeAgents.forEach((agent) => {
if (settings.enabled && agent.shouldSend(type, payload)) {
if (settings.enabled && agent.shouldSend(type)) {
agent.send(type, payload);
}
});

View File

@@ -42,7 +42,6 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en')
table(style='width: 100%' width='100%' cellpadding='0' cellspacing='0' role='presentation')
tr
td(align='center' style='\
font-size: 16px;\
padding-top: 25px;\
padding-bottom: 25px;\
text-align: center;\
@@ -50,7 +49,7 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en')
a(href=applicationUrl style='\
text-shadow: 0 1px 0 #ffffff;\
font-weight: 700;\
font-size: 16px;\
font-size: 24px;\
color: #a8aaaf;\
text-decoration: none;\
')
@@ -70,11 +69,15 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en')
br
br
p(style='margin-top: 4px; text-align: center')
b
| #{mediaName}
table(cellpadding='0' cellspacing='0' role='presentation')
each extra in mediaExtra
br
| #{extra.name}:&nbsp;
| #{extra.value}
table(align='center' cellpadding='0' cellspacing='0' role='presentation')
tr
td
table(cellpadding='0' cellspacing='0' role='presentation')
a(href=actionUrl style='color: #3869d4')
img(src=imageUrl alt='')
p(style='\