mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
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
This commit is contained in:
@@ -4,7 +4,7 @@ import { IssueType } from '../../../server/constants/issue';
|
||||
const messages = defineMessages({
|
||||
issueAudio: 'Audio',
|
||||
issueVideo: 'Video',
|
||||
issueSubtitles: 'Subtitles',
|
||||
issueSubtitles: 'Subtitle',
|
||||
issueOther: 'Other',
|
||||
});
|
||||
|
||||
|
@@ -44,12 +44,21 @@ const messages = defineMessages({
|
||||
issuecommentDescription:
|
||||
'Send notifications when issues receive new comments.',
|
||||
userissuecommentDescription:
|
||||
'Get notified when your issues receive new comments.',
|
||||
'Get notified when issues you reported receive new comments.',
|
||||
adminissuecommentDescription:
|
||||
'Get notified when issues receive new comments.',
|
||||
'Get notified when other users comment on issues.',
|
||||
issueresolved: 'Issue Resolved',
|
||||
issueresolvedDescription: 'Send notifications when issues are resolved.',
|
||||
userissueresolvedDescription: 'Get notified when your issues are resolved.',
|
||||
userissueresolvedDescription:
|
||||
'Get notified when issues you reported are resolved.',
|
||||
adminissueresolvedDescription:
|
||||
'Get notified when issues are resolved by other users.',
|
||||
issuereopened: 'Issue Reopened',
|
||||
issuereopenedDescription: 'Send notifications when issues are reopened.',
|
||||
userissuereopenedDescription:
|
||||
'Get notified when issues you reported are reopened.',
|
||||
adminissuereopenedDescription:
|
||||
'Get notified when issues are reopened by other users.',
|
||||
});
|
||||
|
||||
export const hasNotificationType = (
|
||||
@@ -90,6 +99,7 @@ export enum Notification {
|
||||
ISSUE_CREATED = 256,
|
||||
ISSUE_COMMENT = 512,
|
||||
ISSUE_RESOLVED = 1024,
|
||||
ISSUE_REOPENED = 2048,
|
||||
}
|
||||
|
||||
export const ALL_NOTIFICATIONS = Object.values(Notification)
|
||||
@@ -287,7 +297,9 @@ const NotificationTypeSelector: React.FC<NotificationTypeSelectorProps> = ({
|
||||
name: intl.formatMessage(messages.issueresolved),
|
||||
description: intl.formatMessage(
|
||||
user
|
||||
? messages.userissueresolvedDescription
|
||||
? hasPermission(Permission.MANAGE_ISSUES)
|
||||
? messages.adminissueresolvedDescription
|
||||
: messages.userissueresolvedDescription
|
||||
: messages.issueresolvedDescription
|
||||
),
|
||||
value: Notification.ISSUE_RESOLVED,
|
||||
@@ -296,7 +308,27 @@ const NotificationTypeSelector: React.FC<NotificationTypeSelectorProps> = ({
|
||||
!hasPermission([Permission.MANAGE_ISSUES, Permission.CREATE_ISSUES], {
|
||||
type: 'or',
|
||||
}),
|
||||
hasNotifyUser: true,
|
||||
hasNotifyUser:
|
||||
!user || hasPermission(Permission.MANAGE_ISSUES) ? false : true,
|
||||
},
|
||||
{
|
||||
id: 'issue-reopened',
|
||||
name: intl.formatMessage(messages.issuereopened),
|
||||
description: intl.formatMessage(
|
||||
user
|
||||
? hasPermission(Permission.MANAGE_ISSUES)
|
||||
? messages.adminissuereopenedDescription
|
||||
: messages.userissuereopenedDescription
|
||||
: messages.issuereopenedDescription
|
||||
),
|
||||
value: Notification.ISSUE_REOPENED,
|
||||
hidden:
|
||||
user &&
|
||||
!hasPermission([Permission.MANAGE_ISSUES, Permission.CREATE_ISSUES], {
|
||||
type: 'or',
|
||||
}),
|
||||
hasNotifyUser:
|
||||
!user || hasPermission(Permission.MANAGE_ISSUES) ? false : true,
|
||||
},
|
||||
];
|
||||
|
||||
|
@@ -6,6 +6,7 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
import * as Yup from 'yup';
|
||||
import useSettings from '../../../hooks/useSettings';
|
||||
import globalMessages from '../../../i18n/globalMessages';
|
||||
import Button from '../../Common/Button';
|
||||
import LoadingSpinner from '../../Common/LoadingSpinner';
|
||||
@@ -29,6 +30,7 @@ const messages = defineMessages({
|
||||
|
||||
const NotificationsDiscord: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const settings = useSettings();
|
||||
const { addToast, removeToast } = useToasts();
|
||||
const [isTesting, setIsTesting] = useState(false);
|
||||
const { data, error, revalidate } = useSWR(
|
||||
@@ -195,7 +197,12 @@ const NotificationsDiscord: React.FC = () => {
|
||||
</label>
|
||||
<div className="form-input">
|
||||
<div className="form-input-field">
|
||||
<Field id="botUsername" name="botUsername" type="text" />
|
||||
<Field
|
||||
id="botUsername"
|
||||
name="botUsername"
|
||||
type="text"
|
||||
placeholder={settings.currentSettings.applicationTitle}
|
||||
/>
|
||||
</div>
|
||||
{errors.botUsername && touched.botUsername && (
|
||||
<div className="error">{errors.botUsername}</div>
|
||||
|
@@ -18,27 +18,38 @@ const JSONEditor = dynamic(() => import('../../../JSONEditor'), { ssr: false });
|
||||
|
||||
const defaultPayload = {
|
||||
notification_type: '{{notification_type}}',
|
||||
event: '{{event}}',
|
||||
subject: '{{subject}}',
|
||||
message: '{{message}}',
|
||||
image: '{{image}}',
|
||||
email: '{{notifyuser_email}}',
|
||||
username: '{{notifyuser_username}}',
|
||||
avatar: '{{notifyuser_avatar}}',
|
||||
'{{media}}': {
|
||||
media_type: '{{media_type}}',
|
||||
tmdbId: '{{media_tmdbid}}',
|
||||
imdbId: '{{media_imdbid}}',
|
||||
tvdbId: '{{media_tvdbid}}',
|
||||
status: '{{media_status}}',
|
||||
status4k: '{{media_status4k}}',
|
||||
},
|
||||
'{{extra}}': [],
|
||||
'{{request}}': {
|
||||
request_id: '{{request_id}}',
|
||||
requestedBy_email: '{{requestedBy_email}}',
|
||||
requestedBy_username: '{{requestedBy_username}}',
|
||||
requestedBy_avatar: '{{requestedBy_avatar}}',
|
||||
},
|
||||
'{{issue}}': {
|
||||
issue_id: '{{issue_id}}',
|
||||
issue_type: '{{issue_type}}',
|
||||
issue_status: '{{issue_status}}',
|
||||
reportedBy_email: '{{reportedBy_email}}',
|
||||
reportedBy_username: '{{reportedBy_username}}',
|
||||
reportedBy_avatar: '{{reportedBy_avatar}}',
|
||||
},
|
||||
'{{comment}}': {
|
||||
comment_message: '{{comment_message}}',
|
||||
commentedBy_email: '{{commentedBy_email}}',
|
||||
commentedBy_username: '{{commentedBy_username}}',
|
||||
commentedBy_avatar: '{{commentedBy_avatar}}',
|
||||
},
|
||||
'{{extra}}': [],
|
||||
};
|
||||
|
||||
const messages = defineMessages({
|
||||
|
Reference in New Issue
Block a user