330 lines
11 KiB
JavaScript
330 lines
11 KiB
JavaScript
// helper module to send emails with nodemailer
|
||
|
||
const fs = require("fs");
|
||
const path = require('path');
|
||
const { MailtrapClient } = require("mailtrap");
|
||
const nodemailer = require("nodemailer");
|
||
const CON = require("./const");
|
||
const CAL = require("./calendar");
|
||
const Handlebars = require('handlebars');
|
||
|
||
// const { google } = require("googleapis");
|
||
// const OAuth2 = google.auth.OAuth2;
|
||
|
||
const { Shift, Publisher, PrismaClient } = require("@prisma/client");
|
||
const { env } = require("../../next.config");
|
||
|
||
// const TOKEN = process.env.TOKEN || "a7d7147a530235029d74a4c2f228e6ad";
|
||
// const SENDER_EMAIL = "sofia@mwitnessing.com";
|
||
// const sender = { name: "Специално Свидетелстване София", email: SENDER_EMAIL };
|
||
// const client = new MailtrapClient({ token: TOKEN });
|
||
|
||
let mailtrapTestClient = null;
|
||
// const mailtrapTestClient = new MailtrapClient({
|
||
// username: '8ec69527ff2104',//not working now
|
||
// password: 'c7bc05f171c96c'
|
||
// });
|
||
|
||
//MAILTRAP
|
||
var transporterMT = nodemailer.createTransport({
|
||
host: process.env.MAILTRAP_HOST || "sandbox.smtp.mailtrap.io",
|
||
port: 2525,
|
||
auth: {
|
||
user: process.env.MAILTRAP_USER,
|
||
pass: process.env.MAILTRAP_PASS
|
||
}
|
||
});
|
||
|
||
//PROD GMAIL
|
||
// const oauth2Client = new OAuth2(
|
||
// process.env.CLIENT_ID,
|
||
// process.env.CLIENT_SECRET,
|
||
// "https://developers.google.com/oauthplayground"
|
||
// );
|
||
// var transporterGmail = nodemailer.createTransport({
|
||
// service: "gmail",
|
||
// auth: {
|
||
// type: "OAuth2",
|
||
// user: process.env.GMAIL_USER,
|
||
// clientId: process.env.CLIENT_ID,
|
||
// clientSecret: process.env.CLIENT_SECRET,
|
||
// refreshToken: process.env.REFRESH_TOKEN,
|
||
// accessToken: process.env.ACCESS_TOKEN
|
||
// }
|
||
// });
|
||
//--------------
|
||
var transporter = nodemailer.createTransport({
|
||
service: "gmail",
|
||
auth: {
|
||
user: process.env.EMAIL_GMAIL_USERNAME,
|
||
pass: process.env.EMAIL_GMAIL_APP_PASS
|
||
}
|
||
});
|
||
|
||
|
||
//PROD MAILERSEND
|
||
// var transporter = nodemailer.createTransport({
|
||
// host: process.env.MAILERSEND_SERVER,
|
||
// port: process.env.MAILERSEND_PORT,
|
||
// auth: {
|
||
// user: process.env.MAILERSEND_USER,
|
||
// pass: process.env.MAILERSEND_PASS
|
||
// }
|
||
// });
|
||
|
||
var transporterBulk = nodemailer.createTransport({
|
||
host: "bulk.smtp.mailtrap.io",
|
||
port: 587,
|
||
auth: {
|
||
user: "api",
|
||
pass: "1cfe82e747b8dc3390ed08bb16e0f48d"
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
// ------------------ Email sending ------------------
|
||
var lastResult = null;
|
||
function setResult(result) {
|
||
lastResult = result;
|
||
}
|
||
exports.GetLastResult = function () {
|
||
return lastResult;
|
||
};
|
||
|
||
function normalizeEmailAddresses(to) {
|
||
let emails = [];
|
||
|
||
if (typeof to === 'string') {
|
||
// Handle CSV string by splitting into an array
|
||
if (to.includes(',')) emails = to.split(/\s*,\s*/);
|
||
else emails = [to]; // Handle single email string
|
||
} else if (Array.isArray(to)) {
|
||
emails = to.map(item => {
|
||
if (typeof item === 'string') return item;
|
||
if (item.name && item.email) return `"${item.name}" <${item.email}>`;
|
||
return JSON.stringify(item); // Handle unexpected object format
|
||
});
|
||
} else if (typeof to === 'object' && to.email) {
|
||
// Handle single object
|
||
emails = [`"${to.name}" <${to.email}>`];
|
||
} else {
|
||
// Fallback for other types
|
||
emails = [String(to)];
|
||
}
|
||
|
||
return emails; // Always returns an array
|
||
}
|
||
|
||
|
||
exports.SendEmail = async function (to, subject, text, html, attachments = []) {
|
||
let sender = '"Специално Свидетелстване София - тест" <demo@mwitnessing.com>';
|
||
const emailAddresses = normalizeEmailAddresses(to)
|
||
|
||
const message = {
|
||
from: sender,
|
||
to: emailAddresses,
|
||
subject,
|
||
text,
|
||
html,
|
||
attachments
|
||
};
|
||
|
||
if (mailtrapTestClient !== null) {
|
||
// Assuming mailtrapTestClient is correctly set up to send emails
|
||
await mailtrapTestClient
|
||
.send(message)
|
||
.then(console.log)
|
||
.catch(console.error);
|
||
|
||
} else {
|
||
|
||
let result = await transporter
|
||
.sendMail(message)
|
||
.then(console.log)
|
||
.catch(console.error);
|
||
return result;
|
||
}
|
||
|
||
};
|
||
|
||
exports.SendEmailHandlebars = async function (to, templateName, model, attachments = []) {
|
||
try {
|
||
// Ensure the sender and mailtrapTestClient are correctly defined or imported
|
||
|
||
// Load and compile the main template
|
||
const mainTemplateSource = fs.readFileSync(path.join(process.cwd(), 'src', 'templates', 'emails', 'main.hbs'), 'utf8');
|
||
const mainTemplate = Handlebars.compile(mainTemplateSource);
|
||
|
||
// Dynamically load and compile the specified template
|
||
const templateSource = fs.readFileSync(path.join(process.cwd(), 'src', 'templates', 'emails', `${templateName}.hbs`), 'utf8');
|
||
|
||
// Extract subject and optional text version from the template source
|
||
const subjectMatch = templateSource.match(/{{!--\s*Subject:\s*(.*?)\s*--}}/);
|
||
const textMatch = templateSource.match(/{{!--\s*Text:\s*([\s\S]*?)\s*--}}/);
|
||
|
||
let subject = subjectMatch ? subjectMatch[1].trim() : 'ССС: Известие';
|
||
let textVersion = textMatch ? textMatch[1].trim() : null;
|
||
|
||
// Remove the subject and text annotations from the template source
|
||
const cleanTemplateSource = templateSource.replace(/{{!-- Subject: .* --}}/, '').replace(/{{!-- Text: [\s\S]*? --}}/, '');
|
||
// const cleanTemplateSource = templateSource
|
||
// .replace(/{{!--\s*Subject:.*?--}}\s*/, '')
|
||
// .replace(/{{!--\s*Text:.*?--}}\s*/, '');
|
||
// Compile the cleaned template
|
||
const template = Handlebars.compile(cleanTemplateSource);
|
||
|
||
// Render the specified template with the provided model
|
||
const templateHtml = template(model);
|
||
|
||
// Render the main template, inserting the specific template HTML
|
||
const html = mainTemplate({ body: templateHtml });
|
||
|
||
// Generate a plain text version if not explicitly provided
|
||
let text = textVersion || html.replace(/<[^>]*>?/gm, ''); // Simple regex to strip HTML tags. Might need refinement.
|
||
subject = Handlebars.compile(subject)(model);
|
||
text = Handlebars.compile(text)(model);
|
||
|
||
let results = this.SendEmail(to, subject, text, html, attachments);
|
||
return results;
|
||
|
||
} catch (error) {
|
||
console.error(error);
|
||
return new Error('Error sending email');
|
||
}
|
||
};
|
||
|
||
|
||
exports.SendEmail_NewShifts = async function (publisher, shifts) {
|
||
if (shifts.length === 0) return;
|
||
|
||
var date = new Date(shifts[0].startTime);
|
||
|
||
// Generate ICS calendar links for all shifts
|
||
const icsLink = CAL.GenerateICS(shifts);
|
||
|
||
// Prepare the shifts string
|
||
const shiftStr = shifts.map((s) => {
|
||
return `${CON.weekdaysBG[s.startTime.getDay()]} ${CON.GetDateFormat(s.startTime)} at ${s.cartEvent.location.name} from ${CON.GetTimeFormat(s.startTime)} to ${CON.GetTimeFormat(s.endTime)}`;
|
||
}).join("<br>");
|
||
|
||
// Define the model for the Handlebars template
|
||
const model = {
|
||
publisherFirstName: publisher.firstName,
|
||
publisherLastName: publisher.lastName,
|
||
month: CON.monthNamesBG[date.getMonth()],
|
||
shifts: shiftStr,
|
||
sentDate: new Date().toLocaleDateString() // Assuming you want to include the sent date in the email
|
||
};
|
||
|
||
await exports.SendEmailHandlebars(publisher.email, "newShifts", model,
|
||
[{
|
||
filename: "calendar.ics",
|
||
content: icsLink,
|
||
contentType: 'text/calendar' // Ensure this is correctly set for the ICS file
|
||
}]
|
||
).then(console.log).catch(console.error);
|
||
};
|
||
|
||
|
||
|
||
|
||
//----------------------- OLD -----------------------------
|
||
|
||
// exports.SendEmail_NewShifts = async function (publisher, shifts) {
|
||
// if (shifts.length == 0) return;
|
||
|
||
// var date = new Date(shifts[0].startTime);
|
||
|
||
// //generate ICS calendar links for all shifts
|
||
// const icsLink = CAL.GenerateICS(shifts);
|
||
|
||
// const shftStr = shifts
|
||
// .map((s) => {
|
||
// return ` ${CON.weekdaysBG[s.startTime.getDay()]
|
||
// } ${CON.GetDateFormat(s.startTime)} ${s.cartEvent.location.name
|
||
// } ${CON.GetTimeFormat(s.startTime)} - ${CON.GetTimeFormat(
|
||
// s.endTime
|
||
// )}`;
|
||
// })
|
||
// .join("\n");
|
||
|
||
// await client.send({
|
||
// from: sender,
|
||
// to: [
|
||
// {
|
||
// email: "dobromir.popov@gmail.com",//publisher.email,
|
||
// name: publisher.firstName + " " + publisher.lastName,
|
||
// },
|
||
// ],
|
||
// subject: "[CCC]: вашите смени през " + CON.monthNamesBG[date.getMonth()],
|
||
// text:
|
||
// "Здравейте, " + publisher.firstName + " " + publisher.lastName + "!\n\n" +
|
||
// "Ти регистриран да получавате известия за нови смени на количка.\n" +
|
||
// `За месец ${CON.monthNamesBG[date.getMonth()]} имате следните смени:\n` +
|
||
// ` ${shftStr} \n\n\n` +
|
||
// "Поздрави,\n" +
|
||
// "Специално Свидетелстване София",
|
||
// attachments: [
|
||
// {
|
||
// filename: "calendar.ics",
|
||
// content_id: "calendar.ics",
|
||
// disposition: "inline",
|
||
// content: icsLink,
|
||
// },
|
||
// ],
|
||
// })
|
||
// .then(console.log, console.error, setResult);
|
||
// };
|
||
|
||
|
||
// // https://mailtrap.io/blog/sending-emails-with-nodemailer/
|
||
// exports.SendEmail_Example = async function (to) {
|
||
// const welcomeImage = fs.readFileSync(
|
||
// path.join(CON.contentPath, "welcome.png")
|
||
// );
|
||
|
||
// await client
|
||
// .send({
|
||
// category: "test",
|
||
// custom_variables: {
|
||
// hello: "world",
|
||
// year: 2022,
|
||
// anticipated: true,
|
||
// },
|
||
// from: sender,
|
||
// to: [{ email: to }],
|
||
// subject: "Hello from Mailtrap!",
|
||
// html: `<!doctype html>
|
||
// <html>
|
||
// <head>
|
||
// <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
// </head>
|
||
// <body style="font-family: sans-serif;">
|
||
// <div style="display: block; margin: auto; max-width: 600px;" class="main">
|
||
// <h1 style="font-size: 18px; font-weight: bold; margin-top: 20px">Congrats for sending test email with Mailtrap!</h1>
|
||
// <p>Inspect it using the tabs you see above and learn how this email can be improved.</p>
|
||
// <img alt="Inspect with Tabs" src="cid:welcome.png" style="width: 100%;">
|
||
// <p>Now send your email using our fake SMTP server and integration of your choice!</p>
|
||
// <p>Good luck! Hope it works.</p>
|
||
// </div>
|
||
// <!-- Example of invalid for email html/css, will be detected by Mailtrap: -->
|
||
// <style>
|
||
// .main { background-color: white; }
|
||
// a:hover { border-left-width: 1em; min-height: 2em; }
|
||
// </style>
|
||
// </body>
|
||
// </html>`,
|
||
// attachments: [
|
||
// {
|
||
// filename: "welcome.png",
|
||
// content_id: "welcome.png",
|
||
// disposition: "inline",
|
||
// content: welcomeImage,
|
||
// },
|
||
// ],
|
||
// })
|
||
// .then(console.log, console.error, setResult);
|
||
// };
|