- allow mail from address override
- queue cloud emails
This commit is contained in:
Philipinho
2025-04-07 19:07:10 +01:00
parent 233536314f
commit 06270ff747
6 changed files with 35 additions and 58 deletions

View File

@ -2,6 +2,7 @@ import {
BadRequestException,
ForbiddenException,
Injectable,
Logger,
NotFoundException,
} from '@nestjs/common';
import { CreateWorkspaceDto } from '../dto/create-workspace.dto';
@ -32,6 +33,8 @@ import { Queue } from 'bullmq';
@Injectable()
export class WorkspaceService {
private readonly logger = new Logger(WorkspaceService.name);
constructor(
private workspaceRepo: WorkspaceRepo,
private spaceService: SpaceService,
@ -205,6 +208,7 @@ export class WorkspaceService {
);
if (this.environmentService.isCloud() && trialEndAt) {
try {
const delay = trialEndAt.getTime() - Date.now();
await this.billingQueue.add(
@ -212,6 +216,15 @@ export class WorkspaceService {
{ workspaceId: createdWorkspace.id },
{ delay },
);
await this.billingQueue.add(
QueueJob.WELCOME_EMAIL,
{ userId: user.id },
{ delay: 60 * 1000 }, // 1m
);
} catch (err) {
this.logger.error(err);
}
}
return createdWorkspace;

View File

@ -19,18 +19,27 @@ export class MailService {
async sendEmail(message: MailMessage): Promise<void> {
if (message.template) {
// in case this method is used directly. we do not send the tsx template from queue
message.html = await render(message.template, { pretty: true });
message.html = await render(message.template, {
pretty: true,
});
message.text = await render(message.template, { plainText: true });
}
const sender = `${this.environmentService.getMailFromName()} <${this.environmentService.getMailFromAddress()}> `;
let from = this.environmentService.getMailFromAddress();
if (message.from) {
from = message.from;
}
const sender = `${this.environmentService.getMailFromName()} <${from}> `;
await this.mailDriver.sendMail({ from: sender, ...message });
}
async sendToQueue(message: MailMessage): Promise<void> {
if (message.template) {
// transform the React object because it gets lost when sent via the queue
message.html = await render(message.template, { pretty: true });
message.html = await render(message.template, {
pretty: true,
});
message.text = await render(message.template, {
plainText: true,
});

View File

@ -14,6 +14,7 @@ export enum QueueJob {
PAGE_BACKLINKS = 'page-backlinks',
STRIPE_SEATS_SYNC = 'sync-stripe-seats',
TRIAL_ENDED = 'trial-ended',
WELCOME_EMAIL = 'welcome-email',
FIRST_PAYMENT_EMAIL = 'first-payment-email',
}

View File

@ -1,46 +0,0 @@
import { Section, Text, Button } from '@react-email/components';
import * as React from 'react';
import { button, content, paragraph } from '@docmost/transactional/css/styles';
import { MailBody } from '@docmost/transactional/partials/partials';
interface Props {
billingLink: string;
workspaceName: string;
}
export const TrialEndedEmail = ({ billingLink, workspaceName }: Props) => {
return (
<MailBody>
<Section style={content}>
<Text style={paragraph}>Hi there,</Text>
<Text style={paragraph}>
Your Docmost 7-day free trial for {workspaceName} has come to an end.
</Text>
<Text style={paragraph}>
To continue using Docmost for your wiki and documentation, please
upgrade to a premium plan.
</Text>
</Section>
<Section
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: '15px',
paddingBottom: '15px',
}}
>
<Button href={billingLink} style={button}>
Upgrade now
</Button>
</Section>
<Section style={content}>
<Text style={paragraph}>
PS: If you would like to extend your trial, please reply this email.
</Text>
</Section>
</MailBody>
);
};
export default TrialEndedEmail;

View File

@ -14,7 +14,7 @@
"client:dev": "nx run client:dev",
"server:dev": "nx run server:start:dev",
"server:start": "nx run server:start:prod",
"email:dev": "nx run @docmost/transactional:dev",
"email:dev": "nx run server:email:dev",
"dev": "pnpm concurrently -n \"frontend,backend\" -c \"cyan,green\" \"pnpm run client:dev\" \"pnpm run server:dev\""
},
"dependencies": {