Files
sct-overseerr/server/subscriber/IssueCommentSubscriber.ts
TheCatLady c9ffac33f7 feat(notif): issue notifications (#2242)
* feat(notif): issue notifications

* refactor: dedupe test notification strings

* fix: webhook key parsing

* fix(notif): skip send for admin who requested on behalf of another user

* fix(notif): send comment notifs to admins when other admins reply

* fix(notif): also send resolved notifs to admins, and reopened notifs to issue creator

* fix: don't send duplicate notifications

* fix(lang): tweak notification description strings

* fix(notif): tweak Slack notification styling

* fix(notif): tweak Pushbullet & Telegram notification styling

* docs: reformat webhooks page

* fix(notif): add missing issue_type & issue_status variables to LunaSea notif payloads

* fix: explicitly attach media & issue objects where applicable

* fix(notif): correctly notify both notifyUser and managers where applicable

* fix: update default webhook payload for new installs

* fix(notif): add missing comment_message to LunaSea notif payload

* refactor(sw): simplify notificationclick event listener logic

* fix(notif): add missing event description for MEDIA_AVAILABLE notifications
2021-12-04 21:24:26 +09:00

96 lines
2.7 KiB
TypeScript

import { sortBy } from 'lodash';
import {
EntitySubscriberInterface,
EventSubscriber,
getRepository,
InsertEvent,
} from 'typeorm';
import TheMovieDb from '../api/themoviedb';
import { IssueType, IssueTypeName } from '../constants/issue';
import { MediaType } from '../constants/media';
import IssueComment from '../entity/IssueComment';
import Media from '../entity/Media';
import notificationManager, { Notification } from '../lib/notifications';
import { Permission } from '../lib/permissions';
@EventSubscriber()
export class IssueCommentSubscriber
implements EntitySubscriberInterface<IssueComment>
{
public listenTo(): typeof IssueComment {
return IssueComment;
}
private async sendIssueCommentNotification(entity: IssueComment) {
let title: string;
let image: string;
const tmdb = new TheMovieDb();
const issue = (
await getRepository(IssueComment).findOne({
where: { id: entity.id },
relations: ['issue'],
})
)?.issue;
if (!issue) {
return;
}
const media = await getRepository(Media).findOne({
where: { id: issue.media.id },
});
if (!media) {
return;
}
if (media.mediaType === MediaType.MOVIE) {
const movie = await tmdb.getMovie({ movieId: media.tmdbId });
title = `${movie.title}${
movie.release_date ? ` (${movie.release_date.slice(0, 4)})` : ''
}`;
image = `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`;
} else {
const tvshow = await tmdb.getTvShow({ tvId: media.tmdbId });
title = `${tvshow.name}${
tvshow.first_air_date ? ` (${tvshow.first_air_date.slice(0, 4)})` : ''
}`;
image = `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tvshow.poster_path}`;
}
const [firstComment] = sortBy(issue.comments, 'id');
if (entity.id !== firstComment.id) {
// Send notifications to all issue managers
notificationManager.sendNotification(Notification.ISSUE_COMMENT, {
event: `New Comment on ${
issue.issueType !== IssueType.OTHER
? `${IssueTypeName[issue.issueType]} `
: ''
}Issue`,
subject: title,
message: firstComment.message,
comment: entity,
issue,
media,
image,
notifyAdmin: true,
notifyUser:
!issue.createdBy.hasPermission(Permission.MANAGE_ISSUES) &&
issue.createdBy.id !== entity.user.id
? issue.createdBy
: undefined,
});
}
}
public afterInsert(event: InsertEvent<IssueComment>): void {
if (!event.entity) {
return;
}
this.sendIssueCommentNotification(event.entity);
}
}