refactoring

This commit is contained in:
Emily
2025-03-03 19:31:35 +01:00
parent 76e5e07f79
commit 63fa3995c5
70 changed files with 2928 additions and 418 deletions

View File

@@ -4,7 +4,8 @@
"description": "",
"main": "index.js",
"scripts": {
"compile": "tsc"
"compile": "tsc",
"workspace:deploy": "ts-node ../scripts/email/deploy.ts"
},
"keywords": [],
"author": "Emily",

1737
email/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,64 @@
import { TransactionalEmailsApi, SendSmtpEmail } from '@getbrevo/brevo';
import { TransactionalEmailsApi, SendSmtpEmail, ContactsApi } from '@getbrevo/brevo';
import * as TEMPLATE from './templates'
export class EmailService {
private static apiInstance = new TransactionalEmailsApi();
private static apiContacts = new ContactsApi();
static init(apiKey: string) {
this.apiInstance.setApiKey(0, apiKey);
this.apiContacts.setApiKey(0, apiKey);
}
static async sendInviteEmail(target: string, projectName: string, link: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "⚡ Invite";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "help@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.PROJECT_INVITE_EMAIL
.replace(/\[Project Name\]/, projectName)
.replace(/\[Link\]/, link)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async sendInviteEmailNoAccount(target: string, projectName: string, link: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "⚡ Invite - No account";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "help@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.PROJECT_INVITE_EMAIL_NO_ACCOUNT
.replace(/\[Project Name\]/, projectName)
.replace(/\[Link\]/, link)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async createContact(email: string) {
try {
await this.apiContacts.createContact({ email });
await this.apiContacts.addContactToList(12, { emails: [email] })
} catch (ex) {
console.error('ERROR ADDING CONTACT', ex);
return false;
}
}
static async sendLimitEmail50(target: string, projectName: string) {

View File

@@ -38,6 +38,36 @@ app.use((req, res, next) => {
next();
});
app.post('/send/invite', express.json(), async (req, res) => {
try {
const { target, projectName, link } = req.body;
const ok = await EmailService.sendInviteEmail(target, projectName, link);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/invite/noaccount', express.json(), async (req, res) => {
try {
const { target, projectName, link } = req.body;
const ok = await EmailService.sendInviteEmailNoAccount(target, projectName, link);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/brevolist/add', express.json(), async (req, res) => {
try {
const { email } = req.body;
const ok = await EmailService.createContact(email);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/confirm', express.json(), async (req, res) => {
try {
const { target, link } = req.body;

View File

@@ -7,7 +7,8 @@ import { ANOMALY_VISITS_EVENTS_EMAIL } from '../../templates/AnomalyUsageEmail';
import { ANOMALY_DOMAIN_EMAIL } from '../../templates/AnomalyDomainEmail';
import { CONFIRM_EMAIL } from '../../templates/ConfirmEmail';
import { RESET_PASSWORD_EMAIL } from '../../templates/ResetPasswordEmail';
import { PROJECT_INVITE_EMAIL } from '../../templates/ProjectInviteEmail';
import { PROJECT_INVITE_EMAIL_NO_ACCOUNT } from '../../templates/ProjectInviteEmailNoAccount';
export {
@@ -19,5 +20,7 @@ export {
ANOMALY_VISITS_EVENTS_EMAIL,
ANOMALY_DOMAIN_EMAIL,
CONFIRM_EMAIL,
RESET_PASSWORD_EMAIL
RESET_PASSWORD_EMAIL,
PROJECT_INVITE_EMAIL,
PROJECT_INVITE_EMAIL_NO_ACCOUNT
}

View File

@@ -0,0 +1,21 @@
export const PROJECT_INVITE_EMAIL = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thank You for Upgrading Your Litlyx Plan!</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<!-- Email Content -->
<p>Invited by <strong>[Project Name]</strong> on <strong>Litlyx</strong></p>
<p>Best regards,</p>
<p>Antonio,</p>
<p>CEO @ Litlyx</p>
</body>
</html>`

View File

@@ -0,0 +1,21 @@
export const PROJECT_INVITE_EMAIL_NO_ACCOUNT = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thank You for Upgrading Your Litlyx Plan!</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<!-- Email Content -->
<p>Invited by <strong>[Project Name]</strong> on <strong>Litlyx</strong> NO_ACCOUNT</p>
<p>Best regards,</p>
<p>Antonio,</p>
<p>CEO @ Litlyx</p>
</body>
</html>`