mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-19 08:09:45 -06:00
Refactored email service for modernity and clarity
This commit is contained in:
@@ -1,26 +1,24 @@
|
||||
const express = require("express");
|
||||
const helmet = require("helmet");
|
||||
const cors = require("cors");
|
||||
const authRouter = require("./routes/authRoute");
|
||||
const monitorRouter = require("./routes/monitorRoute");
|
||||
const checkRouter = require("./routes/checkRoute");
|
||||
const alertRouter = require("./routes/alertRoute");
|
||||
const { connectDbAndRunServer } = require("./configs/db");
|
||||
require("dotenv").config();
|
||||
const logger = require("./utils/logger");
|
||||
const { verifyJWT } = require("./middleware/verifyJWT");
|
||||
const { handleErrors } = require("./middleware/handleErrors");
|
||||
|
||||
const authRouter = require("./routes/authRoute");
|
||||
const monitorRouter = require("./routes/monitorRoute");
|
||||
const checkRouter = require("./routes/checkRoute");
|
||||
const alertRouter = require("./routes/alertRoute");
|
||||
const pageSpeedCheckRouter = require("./routes/pageSpeedCheckRoute");
|
||||
|
||||
const { connectDbAndRunServer } = require("./configs/db");
|
||||
const queueRouter = require("./routes/queueRoute");
|
||||
const JobQueue = require("./service/jobQueue");
|
||||
const pageSpeedCheckRouter = require("./routes/pageSpeedCheckRoute");
|
||||
const nodemailer = require("nodemailer");
|
||||
|
||||
const emailService = require("./service/emailService");
|
||||
const EmailService = require("./service/emailService");
|
||||
|
||||
// Need to wrap server setup in a function to handle async nature of JobQueue
|
||||
const startApp = async () => {
|
||||
// const { sendEmail } = require('./utils/sendEmail')
|
||||
|
||||
// **************************
|
||||
// Here is where we can swap out DBs easily. Spin up a mongoDB instance and try it out.
|
||||
// Simply comment out the FakeDB and uncomment the MongoDB or vice versa.
|
||||
@@ -42,12 +40,6 @@ const startApp = async () => {
|
||||
? DB_TYPE[process.env.DB_TYPE]()
|
||||
: require("./db/FakeDb");
|
||||
|
||||
/**
|
||||
* NOTES
|
||||
* Email Service will be added
|
||||
* Logger Service will be added (Winston or similar)
|
||||
*/
|
||||
|
||||
const app = express();
|
||||
|
||||
// middlewares
|
||||
@@ -62,11 +54,12 @@ const startApp = async () => {
|
||||
// Make DB accessible anywhere we have a Request object
|
||||
// By adding the DB to the request object, we can access it in any route
|
||||
// Thus we do not need to import it in every route file, and we can easily swap out DBs as there is only one place to change it
|
||||
// Same applies for JobQueue
|
||||
// Same applies for JobQueue and emailService
|
||||
// **************************
|
||||
app.use((req, res, next) => {
|
||||
req.db = db;
|
||||
req.jobQueue = jobQueue;
|
||||
req.emailSerivce = emailSerivce;
|
||||
next();
|
||||
});
|
||||
|
||||
@@ -90,39 +83,21 @@ const startApp = async () => {
|
||||
}
|
||||
});
|
||||
|
||||
// Nodemailer code here
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: process.env.EMAIL_SERVICE_HOST,
|
||||
port: process.env.EMAIL_SERVICE_PORT,
|
||||
auth: {
|
||||
user: process.env.EMAIL_SERVICE_USERNAME,
|
||||
pass: process.env.EMAIL_SERVICE_PASSWORD,
|
||||
},
|
||||
});
|
||||
|
||||
app.use("/api/v1/mail", (req, res) => {
|
||||
console.log("Started");
|
||||
// Replacing varibales
|
||||
const context = { name: "Alex" };
|
||||
|
||||
// Define mail options
|
||||
const mailOptions = {
|
||||
from: "BlueWave Uptime <bluewaveuptime@gmail.com>", // sender address
|
||||
to: "muhammadkhalilzadeh1998@gmailc.com", // list of receivers
|
||||
subject: "Testing template emails", // Subject line
|
||||
html: emailService.sendWelcomeEmail(context), // html body
|
||||
};
|
||||
|
||||
// Send mail with defined transport object
|
||||
transporter.sendMail(mailOptions, (error, info) => {
|
||||
if (error) {
|
||||
return res
|
||||
.status(500)
|
||||
.send({ message: "Error sending email", error: error });
|
||||
}
|
||||
console.log(info);
|
||||
res.status(200).send({ message: "Email sent successfully", info: info });
|
||||
});
|
||||
app.use("/api/v1/mail", async (req, res) => {
|
||||
try {
|
||||
const id = await req.emailSerivce.buildAndSendEmail(
|
||||
"welcomeEmailTemplate",
|
||||
{
|
||||
name: "Alex",
|
||||
},
|
||||
"ajhollid@gmail.com",
|
||||
"Welcome"
|
||||
);
|
||||
res.status(200).json({ success: true, msg: "Email sent", data: id });
|
||||
} catch (error) {
|
||||
logger.error(error.message);
|
||||
return res.status(500).json({ message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -131,8 +106,10 @@ const startApp = async () => {
|
||||
*/
|
||||
app.use(handleErrors);
|
||||
|
||||
// Create services
|
||||
await connectDbAndRunServer(app, db);
|
||||
const jobQueue = await JobQueue.createJobQueue(db);
|
||||
const emailSerivce = new EmailService();
|
||||
|
||||
const cleanup = async () => {
|
||||
console.log("Shutting down gracefully");
|
||||
|
||||
@@ -1,125 +1,59 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const nodemailer = require("nodemailer");
|
||||
const { compile } = require("handlebars");
|
||||
const { mjml2html } = require("mjml");
|
||||
|
||||
// Fetching Templates
|
||||
class EmailService {
|
||||
constructor() {
|
||||
this.loadTemplate = (templateName) => {
|
||||
const templatePath = path.join(
|
||||
__dirname,
|
||||
`../templates/${templateName}.mjml`
|
||||
);
|
||||
const templateContent = fs.readFileSync(templatePath, "utf8");
|
||||
return compile(templateContent);
|
||||
};
|
||||
|
||||
// Welcome Email Template
|
||||
const welcomeEmailTemplatePath = path.join(
|
||||
__dirname,
|
||||
"../templates/welcomeEmail.mjml"
|
||||
);
|
||||
const welcomeEmailTemplateContent = fs.readFileSync(
|
||||
welcomeEmailTemplatePath,
|
||||
"utf8"
|
||||
);
|
||||
const welcomeEmailTemplate = compile(welcomeEmailTemplateContent);
|
||||
// TODO Load less used templates in their respective functions
|
||||
this.templateLookup = {
|
||||
welcomeEmailTemplate: this.loadTemplate("welcomeEmail"),
|
||||
employeeActivationTemplate: this.loadTemplate("employeeActivation"),
|
||||
noIncidentsThisWeekTemplate: this.loadTemplate("noIncidentsThisWeek"),
|
||||
serverIsDownTemplate: this.loadTemplate("serverIsDown"),
|
||||
serverIsUpTemplate: this.loadTemplate("serverIsUp"),
|
||||
passwordResetTemplate: this.loadTemplate("passwordReset"),
|
||||
};
|
||||
|
||||
// Employee Activation Email Template
|
||||
const employeeActivationTemplatePath = path.join(
|
||||
__dirname,
|
||||
"../templates/employeeActivation.mjml"
|
||||
);
|
||||
const employeeActivationTemplateContent = fs.readFileSync(
|
||||
employeeActivationTemplatePath,
|
||||
"utf8"
|
||||
);
|
||||
const employeeActivation = compile(employeeActivationTemplateContent);
|
||||
this.transporter = nodemailer.createTransport({
|
||||
host: process.env.EMAIL_SERVICE_HOST,
|
||||
port: process.env.EMAIL_SERVICE_PORT,
|
||||
secure: true, // Use `true` for port 465, `false` for all other ports
|
||||
auth: {
|
||||
user: process.env.EMAIL_SERVICE_USERNAME,
|
||||
pass: process.env.EMAIL_SERVICE_PASSWORD,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// No Incident This Week Template
|
||||
const noIncidentsThisWeekTemplatePath = path.join(
|
||||
__dirname,
|
||||
"../templates/noIncidentsThisWeek.mjml"
|
||||
);
|
||||
const noIncidentsThisWeekTemplateContent = fs.readFileSync(
|
||||
noIncidentsThisWeekTemplatePath,
|
||||
"utf8"
|
||||
);
|
||||
const noIncidentsThisWeek = compile(noIncidentsThisWeekTemplateContent);
|
||||
buildAndSendEmail = async (template, context, to, subject) => {
|
||||
const buildHtml = (template, context) => {
|
||||
const mjml = this.templateLookup[template](context);
|
||||
const html = mjml2html(mjml);
|
||||
return html;
|
||||
};
|
||||
|
||||
// Server is Down Template
|
||||
const serverIsDownTemplatePath = path.join(
|
||||
__dirname,
|
||||
"../templates/serverIsDown.mjml"
|
||||
);
|
||||
const serverIsDownTemplateContent = fs.readFileSync(
|
||||
serverIsDownTemplatePath,
|
||||
"utf8"
|
||||
);
|
||||
const serverIsDown = compile(serverIsDownTemplateContent);
|
||||
|
||||
// Server is Up Template
|
||||
const serverIsUpTemplatePath = path.join(
|
||||
__dirname,
|
||||
"../templates/serverIsUp.mjml"
|
||||
);
|
||||
const serverIsUpTemplateContent = fs.readFileSync(
|
||||
serverIsUpTemplatePath,
|
||||
"utf8"
|
||||
);
|
||||
const serverIsUp = compile(serverIsUpTemplateContent);
|
||||
|
||||
// Password Reset Template
|
||||
const passwordResetTemplatePath = path.join(
|
||||
__dirname,
|
||||
"../templates/passwordReset.mjml"
|
||||
);
|
||||
const passwordResetTemplateContent = fs.readFileSync(
|
||||
passwordResetTemplatePath,
|
||||
"utf8"
|
||||
);
|
||||
const passwordReset = compile(passwordResetTemplateContent);
|
||||
|
||||
// *** Application specific functions ***
|
||||
|
||||
function sendWelcomeEmail(context) {
|
||||
const mjml = welcomeEmailTemplate(context);
|
||||
const html = mjml2html(mjml);
|
||||
|
||||
return html;
|
||||
const sendEmail = async (to, subject, html) => {
|
||||
const info = await this.transporter.sendMail({
|
||||
to: to,
|
||||
subject: subject,
|
||||
html: html,
|
||||
});
|
||||
return info;
|
||||
};
|
||||
const info = await sendEmail(to, subject, buildHtml(template, context));
|
||||
return info.messageId;
|
||||
};
|
||||
}
|
||||
|
||||
function sendEmployeeActivationEmail(context) {
|
||||
const mjml = employeeActivation(context);
|
||||
const html = mjml2html(mjml);
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function sendNoIncidentsThisWeekEmail(context) {
|
||||
const mjml = noIncidentsThisWeek(context);
|
||||
const html = mjml2html(mjml);
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function sendServerIsDownEmail(context) {
|
||||
const mjml = serverIsDown(context);
|
||||
const html = mjml2html(mjml);
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function sendServerIsUpEmail(context) {
|
||||
const mjml = serverIsUp(context);
|
||||
const html = mjml2html(mjml);
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function sendPasswordResetEmail(context) {
|
||||
const mjml = passwordReset(context);
|
||||
const html = mjml2html(mjml);
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sendWelcomeEmail,
|
||||
sendEmployeeActivationEmail,
|
||||
sendNoIncidentsThisWeekEmail,
|
||||
sendServerIsDownEmail,
|
||||
sendServerIsUpEmail,
|
||||
sendPasswordResetEmail,
|
||||
};
|
||||
module.exports = EmailService;
|
||||
|
||||
Reference in New Issue
Block a user