Skip to content

Commit

Permalink
feat: add more template
Browse files Browse the repository at this point in the history
  • Loading branch information
darkskygit committed Jan 7, 2025
1 parent 9c183a7 commit 22e3138
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 296 deletions.
82 changes: 17 additions & 65 deletions packages/backend/server/src/base/mailer/mail.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import {
renderSetPasswordMail,
renderSignInMail,
renderSignUpMail,
renderTeamExpireRemindMail,
renderTeamMemberRemovedMail,
renderTeamOwnershipTransferredMail,
renderTeamReviewApproveMail,
renderTeamReviewDeclineMail,
renderTeamReviewRequestMail,
Expand All @@ -24,7 +27,6 @@ import { URLHelper } from '../helpers';
import { metrics } from '../metrics';
import type { MailerService, Options } from './mailer';
import { MAILER_SERVICE } from './mailer';
import { emailTemplate } from './template';

type Workspace = {
id: string;
Expand Down Expand Up @@ -273,25 +275,19 @@ export class MailService {
}

async sendOwnershipTransferredEmail(to: string, ws: Workspace) {
const { name: workspaceName } = ws;
const title = `Your ownership of ${workspaceName} has been transferred`;

const html = emailTemplate({
title: 'Ownership transferred',
content: `You have transferred ownership of ${workspaceName}. You are now a admin in this workspace.`,
const { workspaceName, attachments } = this.extractWorkspaceInfo(ws);
const { html, subject } = await renderTeamOwnershipTransferredMail({
workspaceName,
});
return this.sendMail({ to, subject: title, html });
return this.sendMail({ to, subject, html, attachments });
}

async sendMemberRemovedEmail(to: string, ws: Workspace) {
const { name: workspaceName } = ws;
const title = `You have been removed from ${workspaceName}`;

const html = emailTemplate({
title: 'Workspace access removed',
content: `You have been removed from {workspace name}. You no longer have access to this workspace.`,
const { workspaceName, attachments } = this.extractWorkspaceInfo(ws);
const { html, subject } = await renderTeamMemberRemovedMail({
workspaceName,
});
return this.sendMail({ to, subject: title, html });
return this.sendMail({ to, subject, html, attachments });
}

async sendWorkspaceExpireRemindEmail(
Expand All @@ -307,56 +303,12 @@ export class MailService {
expirationDate,
deletionDate,
} = ws;
const baseContent: {
subject: string;
title: string;
content: string;
button?: { buttonContent: string; buttonUrl: string };
} = {
subject: `[Action Required] Your ${workspaceName} team workspace is expiring soon`,
title: 'Team workspace expiring soon',
content: `Your ${workspaceName} team workspace will expire on ${expirationDate}. After expiration, you won't be able to sync or collaborate with team members. Please renew your subscription to continue using all team features.`,
button: {
buttonContent: 'Go to Billing',
// TODO(@darkskygit): use real billing path
buttonUrl: this.url.link(`/workspace/${workspaceId}/billing`),
},
};

if (deletionDate) {
if (deletionDate < new Date()) {
// in 24 hours
if (deletionDate.getTime() - Date.now() < 24 * 60 * 60 * 1000) {
baseContent.subject = `[Action Required] Final warning: Your ${workspaceName} data will be deleted in 24 hours`;
baseContent.title = 'Urgent: Last chance to prevent data loss';
baseContent.content = `Your ${workspaceName} team workspace data will be permanently deleted in 24 hours on ${deletionDate}. To prevent data loss, please take immediate action:
<li>Renew your subscription to restore team features</li>
<li>Export your workspace data from Workspace Settings > Export Workspace</li>`;
} else {
baseContent.subject = `[Action Required] Important: Your ${workspaceName} data will be deleted soon`;
baseContent.title = 'Take action to prevent data loss';
baseContent.content = `Your ${workspaceName} team workspace expired on ${expirationDate}. All workspace data will be permanently deleted on ${deletionDate} (180 days after expiration). To prevent data loss, please either:
<li>Renew your subscription to restore team features</li>
<li>Export your workspace data from Workspace Settings > Export Workspace</li>`;
}
} else {
baseContent.subject = `Data deletion completed for ${workspaceName}`;
baseContent.title = 'Workspace data deleted';
baseContent.content = `All data in ${workspaceName} has been permanently deleted as the workspace remained expired for 180 days. This action cannot be undone.
Thank you for your support of AFFiNE. We hope to see you again in the future.`;
baseContent.button = undefined;
}
} else if (expirationDate < new Date()) {
baseContent.subject = `Your ${workspaceName} team workspace has expired`;
baseContent.title = 'Team workspace expired';
baseContent.content = `Your ${workspaceName} team workspace expired on ${expirationDate}. Your workspace can't sync or collaborate with team members. Please renew your subscription to restore all team features.`;
}

const html = emailTemplate({
title: baseContent.title,
content: baseContent.content,
...baseContent.button,
const { html, subject } = await renderTeamExpireRemindMail({
url: this.url.link(`/workspace/${workspaceId}/billing`),
workspaceName,
expirationDate,
deletionDate,
});
return this.sendMail({ to, subject: baseContent.subject, html });
return this.sendMail({ to, subject, html });
}
}
221 changes: 0 additions & 221 deletions packages/backend/server/src/base/mailer/template.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function ChangeEmailNotification(
return (
<EmailTemplate
title="Verify your current email for AFFiNE"
content={`As per your request, we have changed your email. Please make sure you're using ${props.to} when you log in the next time.`}
content={`As per your request, we have changed your email. Please make sure you're using ${props.to || 'your new email'} when you log in the next time.`}
/>
);
}
41 changes: 41 additions & 0 deletions packages/backend/server/src/mail-templates/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ import ChangePassword, { type ChangePasswordProps } from './password-change';
import SetPassword, { type SetPasswordProps } from './password-set';
import SignIn, { type SignInProps } from './sign-in';
import SignUp, { type SignUpProps } from './sign-up';
import TeamExpireRemind, {
getTeamWorkspaceExpireContent,
type TeamExpireRemindProps,
} from './team-expire-remind';
import TeamMemberRemoved, {
type TeamMemberRemovedProps,
} from './team-member-removed';
import TeamOwnershipTransferred, {
type TeamOwnershipTransferredProps,
} from './team-ownership-transferred';
import TeamReviewApprove, {
type TeamReviewApproveProps,
} from './team-review-approve';
Expand Down Expand Up @@ -196,3 +206,34 @@ export const renderTeamRoleChangedMail = async (
html: await render(<TeamRoleChanged {...props} />),
};
};

export const renderTeamOwnershipTransferredMail = async (
props: TeamOwnershipTransferredProps
): Promise<EmailContent> => {
const { workspaceName } = props;
return {
subject: `Your ownership of ${workspaceName} has been transferred`,
html: await render(<TeamOwnershipTransferred {...props} />),
};
};

export const renderTeamMemberRemovedMail = async (
props: TeamMemberRemovedProps
): Promise<EmailContent> => {
const { workspaceName } = props;
return {
subject: `Your ownership of ${workspaceName} has been transferred`,
html: await render(<TeamMemberRemoved {...props} />),
};
};

export const renderTeamExpireRemindMail = async (
props: TeamExpireRemindProps
): Promise<EmailContent> => {
const { subject, button } = getTeamWorkspaceExpireContent(props);
return {
subject,
html: await render(<TeamExpireRemind {...props} />),
...button,
};
};
Loading

0 comments on commit 22e3138

Please sign in to comment.