269 lines
7.4 KiB
JavaScript
269 lines
7.4 KiB
JavaScript
const path = require("path");
|
|
require("dotenv").config({
|
|
path: path.resolve(
|
|
process.cwd(),
|
|
`.env.${process.env.NODE_ENV || "development"}`
|
|
),
|
|
});
|
|
const axios = require("axios");
|
|
let nodemailer = require("nodemailer");
|
|
let aws = require("@aws-sdk/client-ses");
|
|
let { defaultProvider } = require("@aws-sdk/credential-provider-node");
|
|
|
|
const logger = require("../utils/logger");
|
|
const client = require("../graphql-client/graphql-client").client;
|
|
const queries = require("../graphql-client/queries");
|
|
|
|
const ses = new aws.SES({
|
|
// The key apiVersion is no longer supported in v3, and can be removed.
|
|
// @deprecated The client uses the "latest" apiVersion.
|
|
apiVersion: "latest",
|
|
|
|
region: "us-east-2",
|
|
});
|
|
|
|
let transporter = nodemailer.createTransport({
|
|
SES: { ses, aws },
|
|
});
|
|
|
|
exports.sendServerEmail = async function ({ subject, text }) {
|
|
if (process.env.NODE_ENV === undefined) return;
|
|
try {
|
|
transporter.sendMail(
|
|
{
|
|
from: `Rome Online API - ${process.env.NODE_ENV} <noreply@romeonline.io>`,
|
|
to: ["patrick@imexsystems.ca"],
|
|
subject: subject,
|
|
text: text,
|
|
ses: {
|
|
// optional extra arguments for SendRawEmail
|
|
Tags: [
|
|
{
|
|
Name: "tag_name",
|
|
Value: "tag_value",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
(err, info) => {
|
|
console.log(err || info);
|
|
}
|
|
);
|
|
} catch (error) {
|
|
console.log(error);
|
|
logger.log("server-email-failure", "error", null, null, error);
|
|
}
|
|
};
|
|
exports.sendTaskEmail = async function ({ to, subject, text, attachments }) {
|
|
try {
|
|
transporter.sendMail(
|
|
{
|
|
from: `Rome Online <noreply@romeonline.io>`,
|
|
to: to,
|
|
subject: subject,
|
|
text: text,
|
|
attachments: attachments || null,
|
|
},
|
|
(err, info) => {
|
|
console.log(err || info);
|
|
}
|
|
);
|
|
} catch (error) {
|
|
console.log(error);
|
|
logger.log("server-email-failure", "error", null, null, error);
|
|
}
|
|
};
|
|
|
|
exports.sendEmail = async (req, res) => {
|
|
logger.log("send-email", "DEBUG", req.user.email, null, {
|
|
from: `${req.body.from.name} <${req.body.from.address}>`,
|
|
replyTo: req.body.ReplyTo.Email,
|
|
to: req.body.to,
|
|
cc: req.body.cc,
|
|
subject: req.body.subject,
|
|
});
|
|
|
|
let downloadedMedia = [];
|
|
if (req.body.media && req.body.media.length > 0) {
|
|
downloadedMedia = await Promise.all(
|
|
req.body.media.map((m) => {
|
|
try {
|
|
return getImage(m);
|
|
} catch (error) {
|
|
logger.log("send-email-error", "ERROR", req.user.email, null, {
|
|
from: `${req.body.from.name} <${req.body.from.address}>`,
|
|
replyTo: req.body.ReplyTo.Email,
|
|
to: req.body.to,
|
|
cc: req.body.cc,
|
|
subject: req.body.subject,
|
|
error,
|
|
});
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
transporter.sendMail(
|
|
{
|
|
from: `${req.body.from.name} <${req.body.from.address}>`,
|
|
replyTo: req.body.ReplyTo.Email,
|
|
to: req.body.to,
|
|
cc: req.body.cc,
|
|
subject: req.body.subject,
|
|
attachments:
|
|
[
|
|
...((req.body.attachments &&
|
|
req.body.attachments.map((a) => {
|
|
return {
|
|
filename: a.filename,
|
|
path: a.path,
|
|
};
|
|
})) ||
|
|
[]),
|
|
...downloadedMedia.map((a) => {
|
|
return {
|
|
path: a,
|
|
};
|
|
}),
|
|
] || null,
|
|
html: req.body.html,
|
|
ses: {
|
|
// optional extra arguments for SendRawEmail
|
|
Tags: [
|
|
{
|
|
Name: "tag_name",
|
|
Value: "tag_value",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
(err, info) => {
|
|
console.log(err || info);
|
|
if (info) {
|
|
logger.log("send-email-success", "DEBUG", req.user.email, null, {
|
|
from: `${req.body.from.name} <${req.body.from.address}>`,
|
|
replyTo: req.body.ReplyTo.Email,
|
|
to: req.body.to,
|
|
cc: req.body.cc,
|
|
subject: req.body.subject,
|
|
// info,
|
|
});
|
|
logEmail(req, {
|
|
to: req.body.to,
|
|
cc: req.body.cc,
|
|
subject: req.body.subject,
|
|
messageId: info.response,
|
|
});
|
|
res.json({
|
|
success: true, //response: info
|
|
});
|
|
} else {
|
|
logger.log("send-email-failure", "ERROR", req.user.email, null, {
|
|
from: `${req.body.from.name} <${req.body.from.address}>`,
|
|
replyTo: req.body.ReplyTo.Email,
|
|
to: req.body.to,
|
|
cc: req.body.cc,
|
|
subject: req.body.subject,
|
|
error: err,
|
|
});
|
|
logEmail(req, {
|
|
to: req.body.to,
|
|
cc: req.body.cc,
|
|
subject: req.body.subject,
|
|
bodyshopid: req.body.bodyshopid,
|
|
});
|
|
res.status(500).json({ success: false, error: err });
|
|
}
|
|
}
|
|
);
|
|
};
|
|
|
|
async function getImage(imageUrl) {
|
|
let image = await axios.get(imageUrl, { responseType: "arraybuffer" });
|
|
let raw = Buffer.from(image.data).toString("base64");
|
|
return "data:" + image.headers["content-type"] + ";base64," + raw;
|
|
}
|
|
|
|
async function logEmail(req, email) {
|
|
try {
|
|
const insertresult = await client.request(queries.INSERT_EMAIL_AUDIT, {
|
|
email: {
|
|
to: email.to,
|
|
cc: email.cc,
|
|
subject: email.subject,
|
|
bodyshopid: req.body.bodyshopid,
|
|
useremail: req.user.email,
|
|
contents: req.body.html,
|
|
jobid: req.body.jobid,
|
|
sesmessageid: email.messageId,
|
|
status: "Sent",
|
|
},
|
|
});
|
|
console.log(insertresult);
|
|
} catch (error) {
|
|
logger.log("email-log-error", "error", req.user.email, null, {
|
|
from: `${req.body.from.name} <${req.body.from.address}>`,
|
|
to: req.body.to,
|
|
cc: req.body.cc,
|
|
subject: req.body.subject,
|
|
// info,
|
|
});
|
|
}
|
|
}
|
|
|
|
exports.emailBounce = async function (req, res, next) {
|
|
try {
|
|
const body = JSON.parse(req.body);
|
|
if (body.Type === "SubscriptionConfirmation") {
|
|
logger.log("SNS-message", "DEBUG", "api", null, {
|
|
body: req.body,
|
|
});
|
|
}
|
|
const message = JSON.parse(body.Message);
|
|
if (message.notificationType === "Bounce") {
|
|
let replyTo, subject, messageId;
|
|
message.mail.headers.forEach((header) => {
|
|
if (header.name === "Reply-To") {
|
|
replyTo = header.value;
|
|
} else if (header.name === "Subject") {
|
|
subject = header.value;
|
|
}
|
|
});
|
|
messageId = message.mail.messageId;
|
|
if (replyTo === "noreply@romeonline.io") {
|
|
res.sendStatus(200);
|
|
return;
|
|
}
|
|
//If it's bounced, log it as bounced in audit log. Send an email to the user.
|
|
const result = await client.request(queries.UPDATE_EMAIL_AUDIT, {
|
|
sesid: messageId,
|
|
status: "Bounced",
|
|
context: message.bounce?.bouncedRecipients,
|
|
});
|
|
transporter.sendMail(
|
|
{
|
|
from: `Rome Online <noreply@romeonline.io>`,
|
|
to: replyTo,
|
|
subject: `Rome Online Bounced Email - RE: ${subject}`,
|
|
text: `Rome Online has tried to deliver an email with the subject: ${subject} to the intended recipients but encountered an error.
|
|
|
|
${body.bounce?.bouncedRecipients.map(
|
|
(r) =>
|
|
`Recipient: ${r.emailAddress} | Status: ${r.action} | Code: ${r.diagnosticCode}
|
|
`
|
|
)}
|
|
`,
|
|
},
|
|
(err, info) => {
|
|
console.log("***", err || info);
|
|
}
|
|
);
|
|
}
|
|
} catch (error) {
|
|
logger.log("sns-error", "ERROR", "api", null, {
|
|
error: JSON.stringify(error),
|
|
});
|
|
}
|
|
res.sendStatus(200);
|
|
};
|