feat(notifications): add notification for declined requests

closes #663
pull/681/head
sct 4 years ago
parent 4fe8172eb1
commit 2f97f61a6e

@ -138,8 +138,11 @@ export class MediaRequest {
* auto approved content * auto approved content
*/ */
@AfterUpdate() @AfterUpdate()
private async _notifyApproved() { public async notifyApprovedOrDeclined(): Promise<void> {
if (this.status === MediaRequestStatus.APPROVED) { if (
this.status === MediaRequestStatus.APPROVED ||
this.status === MediaRequestStatus.DECLINED
) {
const mediaRepository = getRepository(Media); const mediaRepository = getRepository(Media);
const media = await mediaRepository.findOne({ const media = await mediaRepository.findOne({
where: { id: this.media.id }, where: { id: this.media.id },
@ -151,30 +154,40 @@ export class MediaRequest {
const tmdb = new TheMovieDb(); const tmdb = new TheMovieDb();
if (this.media.mediaType === MediaType.MOVIE) { if (this.media.mediaType === MediaType.MOVIE) {
const movie = await tmdb.getMovie({ movieId: this.media.tmdbId }); const movie = await tmdb.getMovie({ movieId: this.media.tmdbId });
notificationManager.sendNotification(Notification.MEDIA_APPROVED, { notificationManager.sendNotification(
subject: movie.title, this.status === MediaRequestStatus.APPROVED
message: movie.overview, ? Notification.MEDIA_APPROVED
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`, : Notification.MEDIA_DECLINED,
notifyUser: this.requestedBy, {
media, subject: movie.title,
}); message: movie.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
notifyUser: this.requestedBy,
media,
}
);
} else if (this.media.mediaType === MediaType.TV) { } else if (this.media.mediaType === MediaType.TV) {
const tv = await tmdb.getTvShow({ tvId: this.media.tmdbId }); const tv = await tmdb.getTvShow({ tvId: this.media.tmdbId });
notificationManager.sendNotification(Notification.MEDIA_APPROVED, { notificationManager.sendNotification(
subject: tv.name, this.status === MediaRequestStatus.APPROVED
message: tv.overview, ? Notification.MEDIA_APPROVED
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`, : Notification.MEDIA_DECLINED,
notifyUser: this.requestedBy, {
media, subject: tv.name,
extra: [ message: tv.overview,
{ image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
name: 'Seasons', notifyUser: this.requestedBy,
value: this.seasons media,
.map((season) => season.seasonNumber) extra: [
.join(', '), {
}, name: 'Seasons',
], value: this.seasons
}); .map((season) => season.seasonNumber)
.join(', '),
},
],
}
);
} }
} }
} }

@ -158,6 +158,28 @@ class DiscordAgent
} }
); );
if (settings.main.applicationUrl) {
fields.push({
name: 'View Media',
value: `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`,
});
}
break;
case Notification.MEDIA_DECLINED:
color = EmbedColors.RED;
fields.push(
{
name: 'Requested By',
value: payload.notifyUser.username ?? '',
inline: true,
},
{
name: 'Status',
value: 'Declined',
inline: true,
}
);
if (settings.main.applicationUrl) { if (settings.main.applicationUrl) {
fields.push({ fields.push({
name: 'View Media', name: 'View Media',

@ -162,6 +162,43 @@ class EmailAgent
} }
} }
private async sendMediaDeclinedEmail(payload: NotificationPayload) {
// This is getting main settings for the whole app
const applicationUrl = getSettings().main.applicationUrl;
try {
const email = new PreparedEmail();
await email.send({
template: path.join(
__dirname,
'../../../templates/email/media-request'
),
message: {
to: payload.notifyUser.email,
},
locals: {
body: 'Your request for the following media was declined:',
mediaName: payload.subject,
imageUrl: payload.image,
timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.username,
actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
applicationUrl,
requestType: 'Request Declined',
},
});
return true;
} catch (e) {
logger.error('Mail notification failed to send', {
label: 'Notifications',
message: e.message,
});
return false;
}
}
private async sendMediaAvailableEmail(payload: NotificationPayload) { private async sendMediaAvailableEmail(payload: NotificationPayload) {
// This is getting main settings for the whole app // This is getting main settings for the whole app
const applicationUrl = getSettings().main.applicationUrl; const applicationUrl = getSettings().main.applicationUrl;

@ -72,6 +72,13 @@ class PushoverAgent
message += `<b>Requested By</b>\n${user}\n\n`; message += `<b>Requested By</b>\n${user}\n\n`;
message += `<b>Status</b>\nAvailable\n`; message += `<b>Status</b>\nAvailable\n`;
break; break;
case Notification.MEDIA_DECLINED:
messageTitle = 'Request Declined';
message += `${title}\n\n`;
message += `${plot}\n\n`;
message += `<b>Requested By</b>\n${user}\n\n`;
message += `<b>Status</b>\nDeclined\n`;
break;
case Notification.TEST_NOTIFICATION: case Notification.TEST_NOTIFICATION:
messageTitle = 'Test Notification'; messageTitle = 'Test Notification';
message += `${title}\n\n`; message += `${title}\n\n`;

@ -96,6 +96,22 @@ class SlackAgent
actionUrl = `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`; actionUrl = `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`;
} }
break; break;
case Notification.MEDIA_DECLINED:
header = 'Request Declined';
fields.push(
{
type: 'mrkdwn',
text: `*Requested By*\n${payload.notifyUser.username ?? ''}`,
},
{
type: 'mrkdwn',
text: '*Status*\nDeclined',
}
);
if (settings.main.applicationUrl) {
actionUrl = `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`;
}
break;
case Notification.MEDIA_AVAILABLE: case Notification.MEDIA_AVAILABLE:
header = 'Now available!'; header = 'Now available!';
fields.push( fields.push(

@ -70,6 +70,14 @@ class TelegramAgent
message += `\*Requested By\*\n${user}\n\n`; message += `\*Requested By\*\n${user}\n\n`;
message += `\*Status\*\nProcessing Request\n`; message += `\*Status\*\nProcessing Request\n`;
break;
case Notification.MEDIA_DECLINED:
message += `\*Request Declined\*\n`;
message += `${title}\n\n`;
message += `${plot}\n\n`;
message += `\*Requested By\*\n${user}\n\n`;
message += `\*Status\*\nDeclined\n`;
break; break;
case Notification.MEDIA_AVAILABLE: case Notification.MEDIA_AVAILABLE:
message += `\*Now available\\!\*\n`; message += `\*Now available\\!\*\n`;

@ -7,6 +7,7 @@ export enum Notification {
MEDIA_AVAILABLE = 8, MEDIA_AVAILABLE = 8,
MEDIA_FAILED = 16, MEDIA_FAILED = 16,
TEST_NOTIFICATION = 32, TEST_NOTIFICATION = 32,
MEDIA_DECLINED = 64,
} }
export const hasNotificationType = ( export const hasNotificationType = (

@ -14,6 +14,8 @@ const messages = defineMessages({
mediafailed: 'Media Failed', mediafailed: 'Media Failed',
mediafailedDescription: mediafailedDescription:
'Sends a notification when media fails to be added to services (Radarr/Sonarr). For certain agents, this will only send the notification to admins or users with the "Manage Requests" permission.', 'Sends a notification when media fails to be added to services (Radarr/Sonarr). For certain agents, this will only send the notification to admins or users with the "Manage Requests" permission.',
mediadeclined: 'Media Declined',
mediadeclinedDescription: 'Sends a notification when a request is declined.',
}); });
export const hasNotificationType = ( export const hasNotificationType = (
@ -41,6 +43,7 @@ export enum Notification {
MEDIA_AVAILABLE = 8, MEDIA_AVAILABLE = 8,
MEDIA_FAILED = 16, MEDIA_FAILED = 16,
TEST_NOTIFICATION = 32, TEST_NOTIFICATION = 32,
MEDIA_DECLINED = 64,
} }
export interface NotificationItem { export interface NotificationItem {
@ -75,6 +78,12 @@ const NotificationTypeSelector: React.FC<NotificationTypeSelectorProps> = ({
description: intl.formatMessage(messages.mediaapprovedDescription), description: intl.formatMessage(messages.mediaapprovedDescription),
value: Notification.MEDIA_APPROVED, value: Notification.MEDIA_APPROVED,
}, },
{
id: 'media-declined',
name: intl.formatMessage(messages.mediadeclined),
description: intl.formatMessage(messages.mediadeclinedDescription),
value: Notification.MEDIA_DECLINED,
},
{ {
id: 'media-available', id: 'media-available',
name: intl.formatMessage(messages.mediaavailable), name: intl.formatMessage(messages.mediaavailable),

@ -72,6 +72,8 @@
"components.NotificationTypeSelector.mediaapprovedDescription": "Sends a notification when media is approved.", "components.NotificationTypeSelector.mediaapprovedDescription": "Sends a notification when media is approved.",
"components.NotificationTypeSelector.mediaavailable": "Media Available", "components.NotificationTypeSelector.mediaavailable": "Media Available",
"components.NotificationTypeSelector.mediaavailableDescription": "Sends a notification when media becomes available.", "components.NotificationTypeSelector.mediaavailableDescription": "Sends a notification when media becomes available.",
"components.NotificationTypeSelector.mediadeclined": "Media Declined",
"components.NotificationTypeSelector.mediadeclinedDescription": "Sends a notification when a request is declined.",
"components.NotificationTypeSelector.mediafailed": "Media Failed", "components.NotificationTypeSelector.mediafailed": "Media Failed",
"components.NotificationTypeSelector.mediafailedDescription": "Sends a notification when media fails to be added to services (Radarr/Sonarr). For certain agents, this will only send the notification to admins or users with the \"Manage Requests\" permission.", "components.NotificationTypeSelector.mediafailedDescription": "Sends a notification when media fails to be added to services (Radarr/Sonarr). For certain agents, this will only send the notification to admins or users with the \"Manage Requests\" permission.",
"components.NotificationTypeSelector.mediarequested": "Media Requested", "components.NotificationTypeSelector.mediarequested": "Media Requested",

Loading…
Cancel
Save