Skip to content

Commit

Permalink
feat(notifications): add notification for declined requests
Browse files Browse the repository at this point in the history
closes #663
  • Loading branch information
sct committed Jan 18, 2021
1 parent 4fe8172 commit 2f97f61
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 24 deletions.
61 changes: 37 additions & 24 deletions server/entity/MediaRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,11 @@ export class MediaRequest {
* auto approved content
*/
@AfterUpdate()
private async _notifyApproved() {
if (this.status === MediaRequestStatus.APPROVED) {
public async notifyApprovedOrDeclined(): Promise<void> {
if (
this.status === MediaRequestStatus.APPROVED ||
this.status === MediaRequestStatus.DECLINED
) {
const mediaRepository = getRepository(Media);
const media = await mediaRepository.findOne({
where: { id: this.media.id },
Expand All @@ -151,30 +154,40 @@ export class MediaRequest {
const tmdb = new TheMovieDb();
if (this.media.mediaType === MediaType.MOVIE) {
const movie = await tmdb.getMovie({ movieId: this.media.tmdbId });
notificationManager.sendNotification(Notification.MEDIA_APPROVED, {
subject: movie.title,
message: movie.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
notifyUser: this.requestedBy,
media,
});
notificationManager.sendNotification(
this.status === MediaRequestStatus.APPROVED
? Notification.MEDIA_APPROVED
: Notification.MEDIA_DECLINED,
{
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) {
const tv = await tmdb.getTvShow({ tvId: this.media.tmdbId });
notificationManager.sendNotification(Notification.MEDIA_APPROVED, {
subject: tv.name,
message: tv.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
notifyUser: this.requestedBy,
media,
extra: [
{
name: 'Seasons',
value: this.seasons
.map((season) => season.seasonNumber)
.join(', '),
},
],
});
notificationManager.sendNotification(
this.status === MediaRequestStatus.APPROVED
? Notification.MEDIA_APPROVED
: Notification.MEDIA_DECLINED,
{
subject: tv.name,
message: tv.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
notifyUser: this.requestedBy,
media,
extra: [
{
name: 'Seasons',
value: this.seasons
.map((season) => season.seasonNumber)
.join(', '),
},
],
}
);
}
}
}
Expand Down
22 changes: 22 additions & 0 deletions server/lib/notifications/agents/discord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
fields.push({
name: 'View Media',
Expand Down
37 changes: 37 additions & 0 deletions server/lib/notifications/agents/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
// This is getting main settings for the whole app
const applicationUrl = getSettings().main.applicationUrl;
Expand Down
7 changes: 7 additions & 0 deletions server/lib/notifications/agents/pushover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ class PushoverAgent
message += `<b>Requested By</b>\n${user}\n\n`;
message += `<b>Status</b>\nAvailable\n`;
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:
messageTitle = 'Test Notification';
message += `${title}\n\n`;
Expand Down
16 changes: 16 additions & 0 deletions server/lib/notifications/agents/slack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,22 @@ class SlackAgent
actionUrl = `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`;
}
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:
header = 'Now available!';
fields.push(
Expand Down
8 changes: 8 additions & 0 deletions server/lib/notifications/agents/telegram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ class TelegramAgent
message += `\*Requested By\*\n${user}\n\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;
case Notification.MEDIA_AVAILABLE:
message += `\*Now available\\!\*\n`;
Expand Down
1 change: 1 addition & 0 deletions server/lib/notifications/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export enum Notification {
MEDIA_AVAILABLE = 8,
MEDIA_FAILED = 16,
TEST_NOTIFICATION = 32,
MEDIA_DECLINED = 64,
}

export const hasNotificationType = (
Expand Down
9 changes: 9 additions & 0 deletions src/components/NotificationTypeSelector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const messages = defineMessages({
mediafailed: 'Media Failed',
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.',
mediadeclined: 'Media Declined',
mediadeclinedDescription: 'Sends a notification when a request is declined.',
});

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

export interface NotificationItem {
Expand Down Expand Up @@ -75,6 +78,12 @@ const NotificationTypeSelector: React.FC<NotificationTypeSelectorProps> = ({
description: intl.formatMessage(messages.mediaapprovedDescription),
value: Notification.MEDIA_APPROVED,
},
{
id: 'media-declined',
name: intl.formatMessage(messages.mediadeclined),
description: intl.formatMessage(messages.mediadeclinedDescription),
value: Notification.MEDIA_DECLINED,
},
{
id: 'media-available',
name: intl.formatMessage(messages.mediaavailable),
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"components.NotificationTypeSelector.mediaapprovedDescription": "Sends a notification when media is approved.",
"components.NotificationTypeSelector.mediaavailable": "Media 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.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",
Expand Down

0 comments on commit 2f97f61

Please sign in to comment.