mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
+34
-11
@@ -2,18 +2,22 @@
|
||||
* File Name: email.service.js
|
||||
* Type of Program: Service
|
||||
* Description: Nodemailer-based email service.
|
||||
* Provides:
|
||||
* - sendOTPEmail() → sends a 6-digit OTP verification email
|
||||
* - sendWelcomeEmail() → sent after successful email verification
|
||||
* Author: rgrgogu
|
||||
* Subject + body per type are loaded from the email_templates
|
||||
* table (admin-editable, see controllers/admin/email_templates.controller.js).
|
||||
* The outer layout (header/footer/signature) below is fixed in
|
||||
* code and is NOT admin-editable — only the body content is.
|
||||
* Author: rgrgogu, Kenneth Obsequio (@lash0000)
|
||||
* Date Created: Oct. 6, 2025
|
||||
* Date Modified: Jul. 3, 2026 — templates moved from data/email_body.data.js into the DB
|
||||
***********************************************************************************************************************************************************************
|
||||
* HOW TO USE:
|
||||
* const emailService = require('../services/email.service');
|
||||
* await emailService.sendOTPEmail(user.email, otp);
|
||||
* await emailService.sendEmail({ to: user.email, type: 'OTP', data: { otp } });
|
||||
***********************************************************************************************************************************************************************/
|
||||
const nodemailer = require('nodemailer');
|
||||
const { emailTemplates } = require('../data/email_body.data')
|
||||
const mdl_EmailTemplate = require('../models/email_templates/email_templates.mdl');
|
||||
const { enrichEmailData } = require('../data/email_template_enrichers.data');
|
||||
const { renderTemplate } = require('../utils/renderTemplate.util');
|
||||
|
||||
const port = Number(process.env.SMTP_PORT);
|
||||
|
||||
@@ -31,15 +35,34 @@ const transporter = nodemailer.createTransport({
|
||||
},
|
||||
});
|
||||
|
||||
// Fixed layout — admins cannot change header/footer/signature via the CRUD,
|
||||
// only the body content per template type.
|
||||
const FONT = 'font-family: Arial, sans-serif; font-size: 14px; color: #000;';
|
||||
const wrap = (body) => `
|
||||
<html>
|
||||
<body style="${FONT} line-height: 1.6;">
|
||||
${body.trim()}
|
||||
<br><br>
|
||||
<p style="margin: 0;">Regards,<br>Philproperties IT Team</p>
|
||||
<p style="margin: 0; font-size: 12px; color: #555;">This is an automated message from STARR System. Please do not reply.</p>
|
||||
</body>
|
||||
</html>`.trim();
|
||||
|
||||
const sendEmail = async ({ to, type, data = {} }) => {
|
||||
try {
|
||||
const templateFn = emailTemplates[type];
|
||||
|
||||
if (!templateFn) {
|
||||
const template = await mdl_EmailTemplate.findOne({ where: { type } });
|
||||
if (!template) {
|
||||
throw new Error(`Email template "${type}" not found`);
|
||||
}
|
||||
// Draft content (or a template that's never been sent) never reaches
|
||||
// real mail — only the live subject/html_body columns count as "published".
|
||||
if (!template.subject || !template.html_body) {
|
||||
throw new Error(`Email template "${type}" has no published (sent) version yet`);
|
||||
}
|
||||
|
||||
const { subject, html } = templateFn(data);
|
||||
const enriched = enrichEmailData(type, data);
|
||||
const subject = renderTemplate(template.subject, enriched);
|
||||
const html = wrap(renderTemplate(template.html_body, enriched));
|
||||
|
||||
return await new Promise((resolve, reject) => {
|
||||
transporter.sendMail(
|
||||
@@ -65,4 +88,4 @@ const sendEmail = async ({ to, type, data = {} }) => {
|
||||
|
||||
const ping = () => transporter.verify();
|
||||
|
||||
module.exports = { sendEmail, ping };
|
||||
module.exports = { sendEmail, ping };
|
||||
|
||||
Reference in New Issue
Block a user