mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat(notif): auto-request notif type (#2956)
This commit is contained in:
@@ -480,6 +480,10 @@ export class MediaRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.sendNotification(media, Notification.MEDIA_PENDING);
|
this.sendNotification(media, Notification.MEDIA_PENDING);
|
||||||
|
|
||||||
|
if (this.isAutoRequest) {
|
||||||
|
this.sendNotification(media, Notification.MEDIA_AUTO_REQUESTED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,6 +528,14 @@ export class MediaRequest {
|
|||||||
: Notification.MEDIA_APPROVED
|
: Notification.MEDIA_APPROVED
|
||||||
: Notification.MEDIA_DECLINED
|
: Notification.MEDIA_DECLINED
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.status === MediaRequestStatus.APPROVED &&
|
||||||
|
autoApproved &&
|
||||||
|
this.isAutoRequest
|
||||||
|
) {
|
||||||
|
this.sendNotification(media, Notification.MEDIA_AUTO_REQUESTED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1062,6 +1074,7 @@ export class MediaRequest {
|
|||||||
const mediaType = this.type === MediaType.MOVIE ? 'Movie' : 'Series';
|
const mediaType = this.type === MediaType.MOVIE ? 'Movie' : 'Series';
|
||||||
let event: string | undefined;
|
let event: string | undefined;
|
||||||
let notifyAdmin = true;
|
let notifyAdmin = true;
|
||||||
|
let notifySystem = true;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Notification.MEDIA_APPROVED:
|
case Notification.MEDIA_APPROVED:
|
||||||
@@ -1075,6 +1088,13 @@ export class MediaRequest {
|
|||||||
case Notification.MEDIA_PENDING:
|
case Notification.MEDIA_PENDING:
|
||||||
event = `New ${this.is4k ? '4K ' : ''}${mediaType} Request`;
|
event = `New ${this.is4k ? '4K ' : ''}${mediaType} Request`;
|
||||||
break;
|
break;
|
||||||
|
case Notification.MEDIA_AUTO_REQUESTED:
|
||||||
|
event = `${
|
||||||
|
this.is4k ? '4K ' : ''
|
||||||
|
}${mediaType} Request Automatically Submitted`;
|
||||||
|
notifyAdmin = false;
|
||||||
|
notifySystem = false;
|
||||||
|
break;
|
||||||
case Notification.MEDIA_AUTO_APPROVED:
|
case Notification.MEDIA_AUTO_APPROVED:
|
||||||
event = `${
|
event = `${
|
||||||
this.is4k ? '4K ' : ''
|
this.is4k ? '4K ' : ''
|
||||||
@@ -1091,6 +1111,7 @@ export class MediaRequest {
|
|||||||
media,
|
media,
|
||||||
request: this,
|
request: this,
|
||||||
notifyAdmin,
|
notifyAdmin,
|
||||||
|
notifySystem,
|
||||||
notifyUser: notifyAdmin ? undefined : this.requestedBy,
|
notifyUser: notifyAdmin ? undefined : this.requestedBy,
|
||||||
event,
|
event,
|
||||||
subject: `${movie.title}${
|
subject: `${movie.title}${
|
||||||
@@ -1109,6 +1130,7 @@ export class MediaRequest {
|
|||||||
media,
|
media,
|
||||||
request: this,
|
request: this,
|
||||||
notifyAdmin,
|
notifyAdmin,
|
||||||
|
notifySystem,
|
||||||
notifyUser: notifyAdmin ? undefined : this.requestedBy,
|
notifyUser: notifyAdmin ? undefined : this.requestedBy,
|
||||||
event,
|
event,
|
||||||
subject: `${tv.name}${
|
subject: `${tv.name}${
|
||||||
|
@@ -9,6 +9,7 @@ import type { NotificationAgentConfig } from '../../settings';
|
|||||||
export interface NotificationPayload {
|
export interface NotificationPayload {
|
||||||
event?: string;
|
event?: string;
|
||||||
subject: string;
|
subject: string;
|
||||||
|
notifySystem: boolean;
|
||||||
notifyAdmin: boolean;
|
notifyAdmin: boolean;
|
||||||
notifyUser?: User;
|
notifyUser?: User;
|
||||||
media?: Media;
|
media?: Media;
|
||||||
|
@@ -243,7 +243,10 @@ class DiscordAgent
|
|||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const settings = this.getSettings();
|
const settings = this.getSettings();
|
||||||
|
|
||||||
if (!hasNotificationType(type, settings.types ?? 0)) {
|
if (
|
||||||
|
!payload.notifySystem ||
|
||||||
|
!hasNotificationType(type, settings.types ?? 0)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -81,6 +81,11 @@ class EmailAgent
|
|||||||
is4k ? 'in 4K ' : ''
|
is4k ? 'in 4K ' : ''
|
||||||
}is pending approval:`;
|
}is pending approval:`;
|
||||||
break;
|
break;
|
||||||
|
case Notification.MEDIA_AUTO_REQUESTED:
|
||||||
|
body = `A new request for the following ${mediaType} ${
|
||||||
|
is4k ? 'in 4K ' : ''
|
||||||
|
}was automatically submitted:`;
|
||||||
|
break;
|
||||||
case Notification.MEDIA_APPROVED:
|
case Notification.MEDIA_APPROVED:
|
||||||
body = `Your request for the following ${mediaType} ${
|
body = `Your request for the following ${mediaType} ${
|
||||||
is4k ? 'in 4K ' : ''
|
is4k ? 'in 4K ' : ''
|
||||||
|
@@ -117,7 +117,10 @@ class GotifyAgent
|
|||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const settings = this.getSettings();
|
const settings = this.getSettings();
|
||||||
|
|
||||||
if (!hasNotificationType(type, settings.types ?? 0)) {
|
if (
|
||||||
|
!payload.notifySystem ||
|
||||||
|
!hasNotificationType(type, settings.types ?? 0)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -87,7 +87,10 @@ class LunaSeaAgent
|
|||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const settings = this.getSettings();
|
const settings = this.getSettings();
|
||||||
|
|
||||||
if (!hasNotificationType(type, settings.types ?? 0)) {
|
if (
|
||||||
|
!payload.notifySystem ||
|
||||||
|
!hasNotificationType(type, settings.types ?? 0)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@ import {
|
|||||||
shouldSendAdminNotification,
|
shouldSendAdminNotification,
|
||||||
} from '..';
|
} from '..';
|
||||||
import { IssueStatus, IssueTypeName } from '../../../constants/issue';
|
import { IssueStatus, IssueTypeName } from '../../../constants/issue';
|
||||||
|
import { MediaStatus } from '../../../constants/media';
|
||||||
import { getRepository } from '../../../datasource';
|
import { getRepository } from '../../../datasource';
|
||||||
import { User } from '../../../entity/User';
|
import { User } from '../../../entity/User';
|
||||||
import logger from '../../../logger';
|
import logger from '../../../logger';
|
||||||
@@ -52,6 +53,12 @@ class PushbulletAgent
|
|||||||
|
|
||||||
let status = '';
|
let status = '';
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case Notification.MEDIA_AUTO_REQUESTED:
|
||||||
|
status =
|
||||||
|
payload.media?.status === MediaStatus.PENDING
|
||||||
|
? 'Pending Approval'
|
||||||
|
: 'Processing';
|
||||||
|
break;
|
||||||
case Notification.MEDIA_PENDING:
|
case Notification.MEDIA_PENDING:
|
||||||
status = 'Pending Approval';
|
status = 'Pending Approval';
|
||||||
break;
|
break;
|
||||||
@@ -104,6 +111,7 @@ class PushbulletAgent
|
|||||||
|
|
||||||
// Send system notification
|
// Send system notification
|
||||||
if (
|
if (
|
||||||
|
payload.notifySystem &&
|
||||||
hasNotificationType(type, settings.types ?? 0) &&
|
hasNotificationType(type, settings.types ?? 0) &&
|
||||||
settings.enabled &&
|
settings.enabled &&
|
||||||
settings.options.accessToken
|
settings.options.accessToken
|
||||||
|
@@ -5,6 +5,7 @@ import {
|
|||||||
shouldSendAdminNotification,
|
shouldSendAdminNotification,
|
||||||
} from '..';
|
} from '..';
|
||||||
import { IssueStatus, IssueTypeName } from '../../../constants/issue';
|
import { IssueStatus, IssueTypeName } from '../../../constants/issue';
|
||||||
|
import { MediaStatus } from '../../../constants/media';
|
||||||
import { getRepository } from '../../../datasource';
|
import { getRepository } from '../../../datasource';
|
||||||
import { User } from '../../../entity/User';
|
import { User } from '../../../entity/User';
|
||||||
import logger from '../../../logger';
|
import logger from '../../../logger';
|
||||||
@@ -61,6 +62,12 @@ class PushoverAgent
|
|||||||
|
|
||||||
let status = '';
|
let status = '';
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case Notification.MEDIA_AUTO_REQUESTED:
|
||||||
|
status =
|
||||||
|
payload.media?.status === MediaStatus.PENDING
|
||||||
|
? 'Pending Approval'
|
||||||
|
: 'Processing';
|
||||||
|
break;
|
||||||
case Notification.MEDIA_PENDING:
|
case Notification.MEDIA_PENDING:
|
||||||
status = 'Pending Approval';
|
status = 'Pending Approval';
|
||||||
break;
|
break;
|
||||||
@@ -135,6 +142,7 @@ class PushoverAgent
|
|||||||
|
|
||||||
// Send system notification
|
// Send system notification
|
||||||
if (
|
if (
|
||||||
|
payload.notifySystem &&
|
||||||
hasNotificationType(type, settings.types ?? 0) &&
|
hasNotificationType(type, settings.types ?? 0) &&
|
||||||
settings.enabled &&
|
settings.enabled &&
|
||||||
settings.options.accessToken &&
|
settings.options.accessToken &&
|
||||||
|
@@ -225,7 +225,10 @@ class SlackAgent
|
|||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const settings = this.getSettings();
|
const settings = this.getSettings();
|
||||||
|
|
||||||
if (!hasNotificationType(type, settings.types ?? 0)) {
|
if (
|
||||||
|
!payload.notifySystem ||
|
||||||
|
!hasNotificationType(type, settings.types ?? 0)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@ import {
|
|||||||
shouldSendAdminNotification,
|
shouldSendAdminNotification,
|
||||||
} from '..';
|
} from '..';
|
||||||
import { IssueStatus, IssueTypeName } from '../../../constants/issue';
|
import { IssueStatus, IssueTypeName } from '../../../constants/issue';
|
||||||
|
import { MediaStatus } from '../../../constants/media';
|
||||||
import { getRepository } from '../../../datasource';
|
import { getRepository } from '../../../datasource';
|
||||||
import { User } from '../../../entity/User';
|
import { User } from '../../../entity/User';
|
||||||
import logger from '../../../logger';
|
import logger from '../../../logger';
|
||||||
@@ -79,6 +80,12 @@ class TelegramAgent
|
|||||||
|
|
||||||
let status = '';
|
let status = '';
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case Notification.MEDIA_AUTO_REQUESTED:
|
||||||
|
status =
|
||||||
|
payload.media?.status === MediaStatus.PENDING
|
||||||
|
? 'Pending Approval'
|
||||||
|
: 'Processing';
|
||||||
|
break;
|
||||||
case Notification.MEDIA_PENDING:
|
case Notification.MEDIA_PENDING:
|
||||||
status = 'Pending Approval';
|
status = 'Pending Approval';
|
||||||
break;
|
break;
|
||||||
@@ -157,6 +164,7 @@ class TelegramAgent
|
|||||||
|
|
||||||
// Send system notification
|
// Send system notification
|
||||||
if (
|
if (
|
||||||
|
payload.notifySystem &&
|
||||||
hasNotificationType(type, settings.types ?? 0) &&
|
hasNotificationType(type, settings.types ?? 0) &&
|
||||||
settings.options.chatId
|
settings.options.chatId
|
||||||
) {
|
) {
|
||||||
|
@@ -164,7 +164,10 @@ class WebhookAgent
|
|||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const settings = this.getSettings();
|
const settings = this.getSettings();
|
||||||
|
|
||||||
if (!hasNotificationType(type, settings.types ?? 0)) {
|
if (
|
||||||
|
!payload.notifySystem ||
|
||||||
|
!hasNotificationType(type, settings.types ?? 0)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -57,6 +57,11 @@ class WebPushAgent
|
|||||||
case Notification.TEST_NOTIFICATION:
|
case Notification.TEST_NOTIFICATION:
|
||||||
message = payload.message;
|
message = payload.message;
|
||||||
break;
|
break;
|
||||||
|
case Notification.MEDIA_AUTO_REQUESTED:
|
||||||
|
message = `Automatically submitted a new ${
|
||||||
|
is4k ? '4K ' : ''
|
||||||
|
}${mediaType} request.`;
|
||||||
|
break;
|
||||||
case Notification.MEDIA_APPROVED:
|
case Notification.MEDIA_APPROVED:
|
||||||
message = `Your ${
|
message = `Your ${
|
||||||
is4k ? '4K ' : ''
|
is4k ? '4K ' : ''
|
||||||
|
@@ -16,6 +16,7 @@ export enum Notification {
|
|||||||
ISSUE_COMMENT = 512,
|
ISSUE_COMMENT = 512,
|
||||||
ISSUE_RESOLVED = 1024,
|
ISSUE_RESOLVED = 1024,
|
||||||
ISSUE_REOPENED = 2048,
|
ISSUE_REOPENED = 2048,
|
||||||
|
MEDIA_AUTO_REQUESTED = 4096,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const hasNotificationType = (
|
export const hasNotificationType = (
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
import { Not } from 'typeorm';
|
|
||||||
import PlexTvAPI from '../api/plextv';
|
import PlexTvAPI from '../api/plextv';
|
||||||
import { User } from '../entity/User';
|
import { User } from '../entity/User';
|
||||||
import Media from '../entity/Media';
|
import Media from '../entity/Media';
|
||||||
@@ -20,12 +19,12 @@ class WatchlistSync {
|
|||||||
const userRepository = getRepository(User);
|
const userRepository = getRepository(User);
|
||||||
|
|
||||||
// Get users who actually have plex tokens
|
// Get users who actually have plex tokens
|
||||||
const users = await userRepository.find({
|
const users = await userRepository
|
||||||
select: { id: true, plexToken: true, permissions: true },
|
.createQueryBuilder('user')
|
||||||
where: {
|
.addSelect('user.plexToken')
|
||||||
plexToken: Not(''),
|
.leftJoinAndSelect('user.settings', 'settings')
|
||||||
},
|
.where("user.plexToken != ''")
|
||||||
});
|
.getMany();
|
||||||
|
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
await this.syncUserWatchlist(user);
|
await this.syncUserWatchlist(user);
|
||||||
@@ -36,7 +35,7 @@ class WatchlistSync {
|
|||||||
if (!user.plexToken) {
|
if (!user.plexToken) {
|
||||||
logger.warn('Skipping user watchlist sync for user without plex token', {
|
logger.warn('Skipping user watchlist sync for user without plex token', {
|
||||||
label: 'Plex Watchlist Sync',
|
label: 'Plex Watchlist Sync',
|
||||||
userId: user.id,
|
user: user.displayName,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ const notificationRoutes = Router();
|
|||||||
|
|
||||||
const sendTestNotification = async (agent: NotificationAgent, user: User) =>
|
const sendTestNotification = async (agent: NotificationAgent, user: User) =>
|
||||||
await agent.send(Notification.TEST_NOTIFICATION, {
|
await agent.send(Notification.TEST_NOTIFICATION, {
|
||||||
|
notifySystem: true,
|
||||||
notifyAdmin: false,
|
notifyAdmin: false,
|
||||||
notifyUser: user,
|
notifyUser: user,
|
||||||
subject: 'Test Notification',
|
subject: 'Test Notification',
|
||||||
@@ -247,7 +248,7 @@ notificationRoutes.post('/webpush/test', async (req, res, next) => {
|
|||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
return next({
|
return next({
|
||||||
status: 500,
|
status: 500,
|
||||||
message: 'User information missing from request',
|
message: 'User information is missing from the request.',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +364,7 @@ notificationRoutes.post('/lunasea/test', async (req, res, next) => {
|
|||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
return next({
|
return next({
|
||||||
status: 500,
|
status: 500,
|
||||||
message: 'User information missing from request',
|
message: 'User information is missing from the request.',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,34 +385,26 @@ notificationRoutes.get('/gotify', (_req, res) => {
|
|||||||
res.status(200).json(settings.notifications.agents.gotify);
|
res.status(200).json(settings.notifications.agents.gotify);
|
||||||
});
|
});
|
||||||
|
|
||||||
notificationRoutes.post('/gotify', (req, rest) => {
|
notificationRoutes.post('/gotify', (req, res) => {
|
||||||
const settings = getSettings();
|
const settings = getSettings();
|
||||||
|
|
||||||
settings.notifications.agents.gotify = req.body;
|
settings.notifications.agents.gotify = req.body;
|
||||||
settings.save();
|
settings.save();
|
||||||
|
|
||||||
rest.status(200).json(settings.notifications.agents.gotify);
|
res.status(200).json(settings.notifications.agents.gotify);
|
||||||
});
|
});
|
||||||
|
|
||||||
notificationRoutes.post('/gotify/test', async (req, rest, next) => {
|
notificationRoutes.post('/gotify/test', async (req, res, next) => {
|
||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
return next({
|
return next({
|
||||||
status: 500,
|
status: 500,
|
||||||
message: 'User information is missing from request',
|
message: 'User information is missing from the request.',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const gotifyAgent = new GotifyAgent(req.body);
|
const gotifyAgent = new GotifyAgent(req.body);
|
||||||
if (
|
if (await sendTestNotification(gotifyAgent, req.user)) {
|
||||||
await gotifyAgent.send(Notification.TEST_NOTIFICATION, {
|
return res.status(204).send();
|
||||||
notifyAdmin: false,
|
|
||||||
notifyUser: req.user,
|
|
||||||
subject: 'Test Notification',
|
|
||||||
message:
|
|
||||||
'This is a test notification! Check check, 1, 2, 3. Are we coming in clear?',
|
|
||||||
})
|
|
||||||
) {
|
|
||||||
return rest.status(204).send();
|
|
||||||
} else {
|
} else {
|
||||||
return next({
|
return next({
|
||||||
status: 500,
|
status: 500,
|
||||||
|
@@ -69,6 +69,7 @@ export class IssueCommentSubscriber
|
|||||||
media,
|
media,
|
||||||
image,
|
image,
|
||||||
notifyAdmin: true,
|
notifyAdmin: true,
|
||||||
|
notifySystem: true,
|
||||||
notifyUser:
|
notifyUser:
|
||||||
!issue.createdBy.hasPermission(Permission.MANAGE_ISSUES) &&
|
!issue.createdBy.hasPermission(Permission.MANAGE_ISSUES) &&
|
||||||
issue.createdBy.id !== entity.user.id
|
issue.createdBy.id !== entity.user.id
|
||||||
|
@@ -84,6 +84,7 @@ export class IssueSubscriber implements EntitySubscriberInterface<Issue> {
|
|||||||
image,
|
image,
|
||||||
extra,
|
extra,
|
||||||
notifyAdmin: true,
|
notifyAdmin: true,
|
||||||
|
notifySystem: true,
|
||||||
notifyUser:
|
notifyUser:
|
||||||
!entity.createdBy.hasPermission(Permission.MANAGE_ISSUES) &&
|
!entity.createdBy.hasPermission(Permission.MANAGE_ISSUES) &&
|
||||||
(type === Notification.ISSUE_RESOLVED ||
|
(type === Notification.ISSUE_RESOLVED ||
|
||||||
|
@@ -45,6 +45,7 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
|
|||||||
{
|
{
|
||||||
event: `${is4k ? '4K ' : ''}Movie Request Now Available`,
|
event: `${is4k ? '4K ' : ''}Movie Request Now Available`,
|
||||||
notifyAdmin: false,
|
notifyAdmin: false,
|
||||||
|
notifySystem: true,
|
||||||
notifyUser: request.requestedBy,
|
notifyUser: request.requestedBy,
|
||||||
subject: `${movie.title}${
|
subject: `${movie.title}${
|
||||||
movie.release_date
|
movie.release_date
|
||||||
@@ -143,6 +144,7 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
|
|||||||
omission: '…',
|
omission: '…',
|
||||||
}),
|
}),
|
||||||
notifyAdmin: false,
|
notifyAdmin: false,
|
||||||
|
notifySystem: true,
|
||||||
notifyUser: request.requestedBy,
|
notifyUser: request.requestedBy,
|
||||||
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
|
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
|
||||||
media: entity,
|
media: entity,
|
||||||
|
@@ -60,6 +60,9 @@ const messages = defineMessages({
|
|||||||
'Get notified when issues you reported are reopened.',
|
'Get notified when issues you reported are reopened.',
|
||||||
adminissuereopenedDescription:
|
adminissuereopenedDescription:
|
||||||
'Get notified when issues are reopened by other users.',
|
'Get notified when issues are reopened by other users.',
|
||||||
|
mediaautorequested: 'Request Automatically Submitted',
|
||||||
|
mediaautorequestedDescription:
|
||||||
|
'Get notified when new media requests are automatically submitted for items on your Plex Watchlist.',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const hasNotificationType = (
|
export const hasNotificationType = (
|
||||||
@@ -101,6 +104,7 @@ export enum Notification {
|
|||||||
ISSUE_COMMENT = 512,
|
ISSUE_COMMENT = 512,
|
||||||
ISSUE_RESOLVED = 1024,
|
ISSUE_RESOLVED = 1024,
|
||||||
ISSUE_REOPENED = 2048,
|
ISSUE_REOPENED = 2048,
|
||||||
|
MEDIA_AUTO_REQUESTED = 4096,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ALL_NOTIFICATIONS = Object.values(Notification)
|
export const ALL_NOTIFICATIONS = Object.values(Notification)
|
||||||
@@ -191,6 +195,25 @@ const NotificationTypeSelector = ({
|
|||||||
))));
|
))));
|
||||||
|
|
||||||
const types: NotificationItem[] = [
|
const types: NotificationItem[] = [
|
||||||
|
{
|
||||||
|
id: 'media-auto-requested',
|
||||||
|
name: intl.formatMessage(messages.mediaautorequested),
|
||||||
|
description: intl.formatMessage(messages.mediaautorequestedDescription),
|
||||||
|
value: Notification.MEDIA_AUTO_REQUESTED,
|
||||||
|
hidden:
|
||||||
|
!user ||
|
||||||
|
(!user.settings?.watchlistSyncMovies &&
|
||||||
|
!user.settings?.watchlistSyncTv) ||
|
||||||
|
!hasPermission(
|
||||||
|
[
|
||||||
|
Permission.AUTO_REQUEST,
|
||||||
|
Permission.AUTO_REQUEST_MOVIE,
|
||||||
|
Permission.AUTO_REQUEST_TV,
|
||||||
|
],
|
||||||
|
{ type: 'or' }
|
||||||
|
),
|
||||||
|
hasNotifyUser: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'media-requested',
|
id: 'media-requested',
|
||||||
name: intl.formatMessage(messages.mediarequested),
|
name: intl.formatMessage(messages.mediarequested),
|
||||||
|
@@ -31,6 +31,8 @@ export interface UserSettings {
|
|||||||
originalLanguage?: string;
|
originalLanguage?: string;
|
||||||
locale?: string;
|
locale?: string;
|
||||||
notificationTypes: Partial<NotificationAgentTypes>;
|
notificationTypes: Partial<NotificationAgentTypes>;
|
||||||
|
watchlistSyncMovies?: boolean;
|
||||||
|
watchlistSyncTv?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserHookResponse {
|
interface UserHookResponse {
|
||||||
|
@@ -197,6 +197,8 @@
|
|||||||
"components.NotificationTypeSelector.mediaAutoApprovedDescription": "Send notifications when users submit new media requests which are automatically approved.",
|
"components.NotificationTypeSelector.mediaAutoApprovedDescription": "Send notifications when users submit new media requests which are automatically approved.",
|
||||||
"components.NotificationTypeSelector.mediaapproved": "Request Approved",
|
"components.NotificationTypeSelector.mediaapproved": "Request Approved",
|
||||||
"components.NotificationTypeSelector.mediaapprovedDescription": "Send notifications when media requests are manually approved.",
|
"components.NotificationTypeSelector.mediaapprovedDescription": "Send notifications when media requests are manually approved.",
|
||||||
|
"components.NotificationTypeSelector.mediaautorequested": "Request Automatically Submitted",
|
||||||
|
"components.NotificationTypeSelector.mediaautorequestedDescription": "Get notified when new media requests are automatically submitted for items on your Plex Watchlist.",
|
||||||
"components.NotificationTypeSelector.mediaavailable": "Request Available",
|
"components.NotificationTypeSelector.mediaavailable": "Request Available",
|
||||||
"components.NotificationTypeSelector.mediaavailableDescription": "Send notifications when media requests become available.",
|
"components.NotificationTypeSelector.mediaavailableDescription": "Send notifications when media requests become available.",
|
||||||
"components.NotificationTypeSelector.mediadeclined": "Request Declined",
|
"components.NotificationTypeSelector.mediadeclined": "Request Declined",
|
||||||
|
Reference in New Issue
Block a user