Notifications refactor (#5151
* Ongoing * refactor * test * Add cleanup task * refactor
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
import * as React from "react";
|
||||
import { NotificationEventType } from "@shared/types";
|
||||
import env from "@server/env";
|
||||
import { Collection, User } from "@server/models";
|
||||
import { Collection, Notification, User } from "@server/models";
|
||||
import NotificationSettingsHelper from "@server/models/helpers/NotificationSettingsHelper";
|
||||
import BaseEmail from "./BaseEmail";
|
||||
import BaseEmail, { EmailProps } from "./BaseEmail";
|
||||
import Body from "./components/Body";
|
||||
import Button from "./components/Button";
|
||||
import EmailTemplate from "./components/EmailLayout";
|
||||
@@ -12,9 +11,9 @@ import Footer from "./components/Footer";
|
||||
import Header from "./components/Header";
|
||||
import Heading from "./components/Heading";
|
||||
|
||||
type InputProps = {
|
||||
to: string;
|
||||
type InputProps = EmailProps & {
|
||||
userId: string;
|
||||
teamUrl: string;
|
||||
collectionId: string;
|
||||
};
|
||||
|
||||
@@ -33,6 +32,20 @@ export default class CollectionCreatedEmail extends BaseEmail<
|
||||
InputProps,
|
||||
BeforeSend
|
||||
> {
|
||||
public constructor(notification: Notification) {
|
||||
super(
|
||||
{
|
||||
to: notification.user.email,
|
||||
userId: notification.userId,
|
||||
collectionId: notification.collectionId,
|
||||
teamUrl: notification.team.url,
|
||||
},
|
||||
{
|
||||
notificationId: notification.id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected async beforeSend({ userId, collectionId }: Props) {
|
||||
const collection = await Collection.scope("withUser").findByPk(
|
||||
collectionId
|
||||
@@ -41,15 +54,10 @@ export default class CollectionCreatedEmail extends BaseEmail<
|
||||
return false;
|
||||
}
|
||||
|
||||
const user = await User.findByPk(userId);
|
||||
if (!user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
collection,
|
||||
unsubscribeUrl: NotificationSettingsHelper.unsubscribeUrl(
|
||||
user,
|
||||
await User.findByPk(userId, { rejectOnEmpty: true }),
|
||||
NotificationEventType.CreateCollection
|
||||
),
|
||||
};
|
||||
@@ -63,17 +71,17 @@ export default class CollectionCreatedEmail extends BaseEmail<
|
||||
return `${collection.user.name} created a collection`;
|
||||
}
|
||||
|
||||
protected renderAsText({ collection }: Props) {
|
||||
protected renderAsText({ teamUrl, collection }: Props) {
|
||||
return `
|
||||
${collection.name}
|
||||
|
||||
${collection.user.name} created the collection "${collection.name}"
|
||||
|
||||
Open Collection: ${env.URL}${collection.url}
|
||||
Open Collection: ${teamUrl}${collection.url}
|
||||
`;
|
||||
}
|
||||
|
||||
protected render({ collection, unsubscribeUrl }: Props) {
|
||||
protected render({ collection, teamUrl, unsubscribeUrl }: Props) {
|
||||
return (
|
||||
<EmailTemplate>
|
||||
<Header />
|
||||
@@ -86,7 +94,7 @@ Open Collection: ${env.URL}${collection.url}
|
||||
</p>
|
||||
<EmptySpace height={10} />
|
||||
<p>
|
||||
<Button href={`${env.URL}${collection.url}`}>
|
||||
<Button href={`${teamUrl}${collection.url}`}>
|
||||
Open Collection
|
||||
</Button>
|
||||
</p>
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import inlineCss from "inline-css";
|
||||
import * as React from "react";
|
||||
import { NotificationEventType } from "@shared/types";
|
||||
import { Day } from "@shared/utils/time";
|
||||
import env from "@server/env";
|
||||
import { Comment, Document, User } from "@server/models";
|
||||
import {
|
||||
Collection,
|
||||
Comment,
|
||||
Document,
|
||||
Notification,
|
||||
User,
|
||||
} from "@server/models";
|
||||
import DocumentHelper from "@server/models/helpers/DocumentHelper";
|
||||
import NotificationSettingsHelper from "@server/models/helpers/NotificationSettingsHelper";
|
||||
import ProsemirrorHelper from "@server/models/helpers/ProsemirrorHelper";
|
||||
import BaseEmail, { EmailProps } from "./BaseEmail";
|
||||
import Body from "./components/Body";
|
||||
import Button from "./components/Button";
|
||||
@@ -18,17 +27,16 @@ type InputProps = EmailProps & {
|
||||
userId: string;
|
||||
documentId: string;
|
||||
actorName: string;
|
||||
isReply: boolean;
|
||||
commentId: string;
|
||||
collectionName: string | undefined;
|
||||
teamUrl: string;
|
||||
content: string;
|
||||
};
|
||||
|
||||
type BeforeSend = {
|
||||
document: Document;
|
||||
collection: Collection;
|
||||
body: string | undefined;
|
||||
isFirstComment: boolean;
|
||||
isReply: boolean;
|
||||
unsubscribeUrl: string;
|
||||
};
|
||||
|
||||
@@ -42,19 +50,35 @@ export default class CommentCreatedEmail extends BaseEmail<
|
||||
InputProps,
|
||||
BeforeSend
|
||||
> {
|
||||
protected async beforeSend({
|
||||
documentId,
|
||||
userId,
|
||||
commentId,
|
||||
content,
|
||||
}: InputProps) {
|
||||
public constructor(notification: Notification) {
|
||||
super(
|
||||
{
|
||||
to: notification.user.email,
|
||||
userId: notification.userId,
|
||||
documentId: notification.documentId,
|
||||
teamUrl: notification.team.url,
|
||||
actorName: notification.actor.name,
|
||||
commentId: notification.commentId,
|
||||
},
|
||||
{
|
||||
notificationId: notification.id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected async beforeSend({ documentId, userId, commentId }: InputProps) {
|
||||
const document = await Document.unscoped().findByPk(documentId);
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const user = await User.findByPk(userId);
|
||||
if (!user) {
|
||||
const collection = await document.$get("collection");
|
||||
if (!collection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const comment = await Comment.findByPk(commentId);
|
||||
if (!comment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -63,11 +87,23 @@ export default class CommentCreatedEmail extends BaseEmail<
|
||||
where: { documentId },
|
||||
order: [["createdAt", "ASC"]],
|
||||
});
|
||||
const isFirstComment = firstComment?.id === commentId;
|
||||
|
||||
// inline all css so that it works in as many email providers as possible.
|
||||
let body;
|
||||
let content = ProsemirrorHelper.toHTML(
|
||||
ProsemirrorHelper.toProsemirror(comment.data),
|
||||
{
|
||||
centered: false,
|
||||
}
|
||||
);
|
||||
|
||||
content = await DocumentHelper.attachmentsToSignedUrls(
|
||||
content,
|
||||
document.teamId,
|
||||
(4 * Day) / 1000
|
||||
);
|
||||
|
||||
if (content) {
|
||||
// inline all css so that it works in as many email providers as possible.
|
||||
body = await inlineCss(content, {
|
||||
url: env.URL,
|
||||
applyStyleTags: true,
|
||||
@@ -76,12 +112,17 @@ export default class CommentCreatedEmail extends BaseEmail<
|
||||
});
|
||||
}
|
||||
|
||||
const isReply = !!comment.parentCommentId;
|
||||
const isFirstComment = firstComment?.id === commentId;
|
||||
|
||||
return {
|
||||
document,
|
||||
collection,
|
||||
isReply,
|
||||
isFirstComment,
|
||||
body,
|
||||
unsubscribeUrl: NotificationSettingsHelper.unsubscribeUrl(
|
||||
user,
|
||||
await User.findByPk(userId, { rejectOnEmpty: true }),
|
||||
NotificationEventType.CreateComment
|
||||
),
|
||||
};
|
||||
@@ -107,12 +148,12 @@ export default class CommentCreatedEmail extends BaseEmail<
|
||||
isReply,
|
||||
document,
|
||||
commentId,
|
||||
collectionName,
|
||||
collection,
|
||||
}: Props): string {
|
||||
return `
|
||||
${actorName} ${isReply ? "replied to a thread in" : "commented on"} "${
|
||||
document.title
|
||||
}"${collectionName ? `in the ${collectionName} collection` : ""}.
|
||||
}"${collection.name ? `in the ${collection.name} collection` : ""}.
|
||||
|
||||
Open Thread: ${teamUrl}${document.url}?commentId=${commentId}
|
||||
`;
|
||||
@@ -122,7 +163,7 @@ Open Thread: ${teamUrl}${document.url}?commentId=${commentId}
|
||||
document,
|
||||
actorName,
|
||||
isReply,
|
||||
collectionName,
|
||||
collection,
|
||||
teamUrl,
|
||||
commentId,
|
||||
unsubscribeUrl,
|
||||
@@ -139,7 +180,7 @@ Open Thread: ${teamUrl}${document.url}?commentId=${commentId}
|
||||
<p>
|
||||
{actorName} {isReply ? "replied to a thread in" : "commented on"}{" "}
|
||||
<a href={link}>{document.title}</a>{" "}
|
||||
{collectionName ? `in the ${collectionName} collection` : ""}.
|
||||
{collection.name ? `in the ${collection.name} collection` : ""}.
|
||||
</p>
|
||||
{body && (
|
||||
<>
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import inlineCss from "inline-css";
|
||||
import * as React from "react";
|
||||
import { NotificationEventType } from "@shared/types";
|
||||
import { Day } from "@shared/utils/time";
|
||||
import env from "@server/env";
|
||||
import { Document, User } from "@server/models";
|
||||
import {
|
||||
Collection,
|
||||
Comment,
|
||||
Document,
|
||||
Notification,
|
||||
User,
|
||||
} from "@server/models";
|
||||
import DocumentHelper from "@server/models/helpers/DocumentHelper";
|
||||
import NotificationSettingsHelper from "@server/models/helpers/NotificationSettingsHelper";
|
||||
import ProsemirrorHelper from "@server/models/helpers/ProsemirrorHelper";
|
||||
import BaseEmail, { EmailProps } from "./BaseEmail";
|
||||
import Body from "./components/Body";
|
||||
import Button from "./components/Button";
|
||||
@@ -19,13 +28,12 @@ type InputProps = EmailProps & {
|
||||
documentId: string;
|
||||
actorName: string;
|
||||
commentId: string;
|
||||
collectionName: string | undefined;
|
||||
teamUrl: string;
|
||||
content: string;
|
||||
};
|
||||
|
||||
type BeforeSend = {
|
||||
document: Document;
|
||||
collection: Collection;
|
||||
body: string | undefined;
|
||||
unsubscribeUrl: string;
|
||||
};
|
||||
@@ -40,20 +48,54 @@ export default class CommentMentionedEmail extends BaseEmail<
|
||||
InputProps,
|
||||
BeforeSend
|
||||
> {
|
||||
protected async beforeSend({ documentId, userId, content }: InputProps) {
|
||||
public constructor(notification: Notification) {
|
||||
super(
|
||||
{
|
||||
to: notification.user.email,
|
||||
userId: notification.userId,
|
||||
documentId: notification.documentId,
|
||||
teamUrl: notification.team.url,
|
||||
actorName: notification.actor.name,
|
||||
commentId: notification.commentId,
|
||||
},
|
||||
{
|
||||
notificationId: notification.id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected async beforeSend({ documentId, commentId, userId }: InputProps) {
|
||||
const document = await Document.unscoped().findByPk(documentId);
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const user = await User.findByPk(userId);
|
||||
if (!user) {
|
||||
const collection = await document.$get("collection");
|
||||
if (!collection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const comment = await Comment.findByPk(commentId);
|
||||
if (!comment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// inline all css so that it works in as many email providers as possible.
|
||||
let body;
|
||||
let content = ProsemirrorHelper.toHTML(
|
||||
ProsemirrorHelper.toProsemirror(comment.data),
|
||||
{
|
||||
centered: false,
|
||||
}
|
||||
);
|
||||
|
||||
content = await DocumentHelper.attachmentsToSignedUrls(
|
||||
content,
|
||||
document.teamId,
|
||||
(4 * Day) / 1000
|
||||
);
|
||||
|
||||
if (content) {
|
||||
// inline all css so that it works in as many email providers as possible.
|
||||
body = await inlineCss(content, {
|
||||
url: env.URL,
|
||||
applyStyleTags: true,
|
||||
@@ -64,10 +106,11 @@ export default class CommentMentionedEmail extends BaseEmail<
|
||||
|
||||
return {
|
||||
document,
|
||||
collection,
|
||||
body,
|
||||
unsubscribeUrl: NotificationSettingsHelper.unsubscribeUrl(
|
||||
user,
|
||||
NotificationEventType.Mentioned
|
||||
await User.findByPk(userId, { rejectOnEmpty: true }),
|
||||
NotificationEventType.MentionedInComment
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -89,11 +132,11 @@ export default class CommentMentionedEmail extends BaseEmail<
|
||||
teamUrl,
|
||||
document,
|
||||
commentId,
|
||||
collectionName,
|
||||
collection,
|
||||
}: Props): string {
|
||||
return `
|
||||
${actorName} mentioned you in a comment on "${document.title}"${
|
||||
collectionName ? `in the ${collectionName} collection` : ""
|
||||
collection.name ? `in the ${collection.name} collection` : ""
|
||||
}.
|
||||
|
||||
Open Thread: ${teamUrl}${document.url}?commentId=${commentId}
|
||||
@@ -102,8 +145,8 @@ Open Thread: ${teamUrl}${document.url}?commentId=${commentId}
|
||||
|
||||
protected render({
|
||||
document,
|
||||
collection,
|
||||
actorName,
|
||||
collectionName,
|
||||
teamUrl,
|
||||
commentId,
|
||||
unsubscribeUrl,
|
||||
@@ -120,7 +163,7 @@ Open Thread: ${teamUrl}${document.url}?commentId=${commentId}
|
||||
<p>
|
||||
{actorName} mentioned you in a comment on{" "}
|
||||
<a href={link}>{document.title}</a>{" "}
|
||||
{collectionName ? `in the ${collectionName} collection` : ""}.
|
||||
{collection.name ? `in the ${collection.name} collection` : ""}.
|
||||
</p>
|
||||
{body && (
|
||||
<>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from "react";
|
||||
import { Document } from "@server/models";
|
||||
import { Document, Notification } from "@server/models";
|
||||
import BaseEmail, { EmailProps } from "./BaseEmail";
|
||||
import Body from "./components/Body";
|
||||
import Button from "./components/Button";
|
||||
@@ -11,7 +11,6 @@ type InputProps = EmailProps & {
|
||||
documentId: string;
|
||||
actorName: string;
|
||||
teamUrl: string;
|
||||
mentionId: string;
|
||||
};
|
||||
|
||||
type BeforeSend = {
|
||||
@@ -27,6 +26,20 @@ export default class DocumentMentionedEmail extends BaseEmail<
|
||||
InputProps,
|
||||
BeforeSend
|
||||
> {
|
||||
public constructor(notification: Notification) {
|
||||
super(
|
||||
{
|
||||
to: notification.user.email,
|
||||
documentId: notification.documentId,
|
||||
teamUrl: notification.team.url,
|
||||
actorName: notification.actor.name,
|
||||
},
|
||||
{
|
||||
notificationId: notification.id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected async beforeSend({ documentId }: InputProps) {
|
||||
const document = await Document.unscoped().findByPk(documentId);
|
||||
if (!document) {
|
||||
@@ -48,23 +61,18 @@ export default class DocumentMentionedEmail extends BaseEmail<
|
||||
return actorName;
|
||||
}
|
||||
|
||||
protected renderAsText({
|
||||
actorName,
|
||||
teamUrl,
|
||||
document,
|
||||
mentionId,
|
||||
}: Props): string {
|
||||
protected renderAsText({ actorName, teamUrl, document }: Props): string {
|
||||
return `
|
||||
You were mentioned
|
||||
|
||||
${actorName} mentioned you in the document “${document.title}”.
|
||||
|
||||
Open Document: ${teamUrl}${document.url}?mentionId=${mentionId}
|
||||
Open Document: ${teamUrl}${document.url}
|
||||
`;
|
||||
}
|
||||
|
||||
protected render({ document, actorName, teamUrl, mentionId }: Props) {
|
||||
const link = `${teamUrl}${document.url}?ref=notification-email&mentionId=${mentionId}`;
|
||||
protected render({ document, actorName, teamUrl }: Props) {
|
||||
const link = `${teamUrl}${document.url}?ref=notification-email`;
|
||||
|
||||
return (
|
||||
<EmailTemplate>
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import inlineCss from "inline-css";
|
||||
import * as React from "react";
|
||||
import { NotificationEventType } from "@shared/types";
|
||||
import { Day } from "@shared/utils/time";
|
||||
import env from "@server/env";
|
||||
import { Document, User } from "@server/models";
|
||||
import {
|
||||
Document,
|
||||
Collection,
|
||||
User,
|
||||
Revision,
|
||||
Notification,
|
||||
} from "@server/models";
|
||||
import DocumentHelper from "@server/models/helpers/DocumentHelper";
|
||||
import NotificationSettingsHelper from "@server/models/helpers/NotificationSettingsHelper";
|
||||
import BaseEmail, { EmailProps } from "./BaseEmail";
|
||||
import Body from "./components/Body";
|
||||
@@ -17,17 +25,17 @@ import Heading from "./components/Heading";
|
||||
type InputProps = EmailProps & {
|
||||
userId: string;
|
||||
documentId: string;
|
||||
revisionId?: string;
|
||||
actorName: string;
|
||||
collectionName: string;
|
||||
eventType:
|
||||
| NotificationEventType.PublishDocument
|
||||
| NotificationEventType.UpdateDocument;
|
||||
teamUrl: string;
|
||||
content?: string;
|
||||
};
|
||||
|
||||
type BeforeSend = {
|
||||
document: Document;
|
||||
collection: Collection;
|
||||
unsubscribeUrl: string;
|
||||
body: string | undefined;
|
||||
};
|
||||
@@ -42,38 +50,72 @@ export default class DocumentPublishedOrUpdatedEmail extends BaseEmail<
|
||||
InputProps,
|
||||
BeforeSend
|
||||
> {
|
||||
public constructor(notification: Notification) {
|
||||
super(
|
||||
{
|
||||
to: notification.user.email,
|
||||
userId: notification.userId,
|
||||
eventType: notification.event as
|
||||
| NotificationEventType.PublishDocument
|
||||
| NotificationEventType.UpdateDocument,
|
||||
revisionId: notification.revisionId,
|
||||
documentId: notification.documentId,
|
||||
teamUrl: notification.team.url,
|
||||
actorName: notification.actor.name,
|
||||
},
|
||||
{
|
||||
notificationId: notification.id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected async beforeSend({
|
||||
documentId,
|
||||
revisionId,
|
||||
eventType,
|
||||
userId,
|
||||
content,
|
||||
}: InputProps) {
|
||||
const document = await Document.unscoped().findByPk(documentId);
|
||||
const document = await Document.unscoped().findByPk(documentId, {
|
||||
includeState: true,
|
||||
});
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const user = await User.findByPk(userId);
|
||||
if (!user) {
|
||||
const collection = await document.$get("collection");
|
||||
if (!collection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// inline all css so that it works in as many email providers as possible.
|
||||
let body;
|
||||
if (content) {
|
||||
body = await inlineCss(content, {
|
||||
url: env.URL,
|
||||
applyStyleTags: true,
|
||||
applyLinkTags: false,
|
||||
removeStyleTags: true,
|
||||
});
|
||||
if (revisionId) {
|
||||
// generate the diff html for the email
|
||||
const revision = await Revision.findByPk(revisionId);
|
||||
|
||||
if (revision) {
|
||||
const before = await revision.previous();
|
||||
const content = await DocumentHelper.toEmailDiff(before, revision, {
|
||||
includeTitle: false,
|
||||
centered: false,
|
||||
signedUrls: (4 * Day) / 1000,
|
||||
});
|
||||
|
||||
// inline all css so that it works in as many email providers as possible.
|
||||
body = await inlineCss(content, {
|
||||
url: env.URL,
|
||||
applyStyleTags: true,
|
||||
applyLinkTags: false,
|
||||
removeStyleTags: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
document,
|
||||
collection,
|
||||
body,
|
||||
unsubscribeUrl: NotificationSettingsHelper.unsubscribeUrl(
|
||||
user,
|
||||
await User.findByPk(userId, { rejectOnEmpty: true }),
|
||||
eventType
|
||||
),
|
||||
};
|
||||
@@ -102,7 +144,7 @@ export default class DocumentPublishedOrUpdatedEmail extends BaseEmail<
|
||||
actorName,
|
||||
teamUrl,
|
||||
document,
|
||||
collectionName,
|
||||
collection,
|
||||
eventType,
|
||||
}: Props): string {
|
||||
const eventName = this.eventName(eventType);
|
||||
@@ -110,7 +152,7 @@ export default class DocumentPublishedOrUpdatedEmail extends BaseEmail<
|
||||
return `
|
||||
"${document.title}" ${eventName}
|
||||
|
||||
${actorName} ${eventName} the document "${document.title}", in the ${collectionName} collection.
|
||||
${actorName} ${eventName} the document "${document.title}", in the ${collection.name} collection.
|
||||
|
||||
Open Document: ${teamUrl}${document.url}
|
||||
`;
|
||||
@@ -119,7 +161,7 @@ Open Document: ${teamUrl}${document.url}
|
||||
protected render({
|
||||
document,
|
||||
actorName,
|
||||
collectionName,
|
||||
collection,
|
||||
eventType,
|
||||
teamUrl,
|
||||
unsubscribeUrl,
|
||||
@@ -138,7 +180,7 @@ Open Document: ${teamUrl}${document.url}
|
||||
</Heading>
|
||||
<p>
|
||||
{actorName} {eventName} the document{" "}
|
||||
<a href={link}>{document.title}</a>, in the {collectionName}{" "}
|
||||
<a href={link}>{document.title}</a>, in the {collection.name}{" "}
|
||||
collection.
|
||||
</p>
|
||||
{body && (
|
||||
|
||||
@@ -26,14 +26,9 @@ type BeforeSendProps = {
|
||||
*/
|
||||
export default class ExportFailureEmail extends BaseEmail<Props> {
|
||||
protected async beforeSend({ userId }: Props) {
|
||||
const user = await User.findByPk(userId);
|
||||
if (!user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
unsubscribeUrl: NotificationSettingsHelper.unsubscribeUrl(
|
||||
user,
|
||||
await User.findByPk(userId, { rejectOnEmpty: true }),
|
||||
NotificationEventType.ExportCompleted
|
||||
),
|
||||
};
|
||||
|
||||
@@ -29,14 +29,9 @@ type BeforeSendProps = {
|
||||
*/
|
||||
export default class ExportSuccessEmail extends BaseEmail<Props> {
|
||||
protected async beforeSend({ userId }: Props) {
|
||||
const user = await User.findByPk(userId);
|
||||
if (!user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
unsubscribeUrl: NotificationSettingsHelper.unsubscribeUrl(
|
||||
user,
|
||||
await User.findByPk(userId, { rejectOnEmpty: true }),
|
||||
NotificationEventType.ExportCompleted
|
||||
),
|
||||
};
|
||||
|
||||
@@ -27,14 +27,9 @@ type BeforeSendProps = {
|
||||
*/
|
||||
export default class InviteAcceptedEmail extends BaseEmail<Props> {
|
||||
protected async beforeSend({ inviterId }: Props) {
|
||||
const inviter = await User.findByPk(inviterId);
|
||||
if (!inviter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
unsubscribeUrl: NotificationSettingsHelper.unsubscribeUrl(
|
||||
inviter,
|
||||
await User.findByPk(inviterId, { rejectOnEmpty: true }),
|
||||
NotificationEventType.InviteAccepted
|
||||
),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user