ses-mail-protector
Version:
Node.js library for AWS SES email sending with bounce & complaint handling using MongoDB.
150 lines (134 loc) • 4.16 kB
JavaScript
console.log(
"Logs_1 in index.js : process.env.DATABASE_TYPE : ",
process.env.DATABASE_TYPE
);
require("dotenv").config();
// console.log("Logs in index.js : ", process.env);
console.log(
"Logs in index.js : process.env.DATABASE_TYPE : ",
process.env.DATABASE_TYPE
);
process.env.DATABASE_TYPE = process.env.DATABASE_TYPE || "mongodb";
if (process.env.DATABASE_TYPE === "mongodb") {
const { connectMongoDB } = require("./connetions/mongoDB.js");
connectMongoDB();
} else if (process.env.DATABASE_TYPE === "sqldb") {
require("./connetions/sqlDB.js");
} else {
throw new Error(
"❌ DATABASE_TYPE environment variable must be either 'mongodb' or 'sqldb'"
);
}
const ses = require("./sesClient.js");
const { SendEmailCommand } = require("./sesClient.js");
const { isSuppressed, addToSuppression } = require("./suppressionService.js");
const {
handleSnsNotification,
checkAwsSuppression,
} = require("./snsHandler.js");
const { validateEmailId, validateEmailContent } = require("./validation.js");
// Send email safely
async function sendEmail({ to, subject, body, from }) {
console.log("sendEmail ::: to::: ::: ", to);
console.log("sendEmail ::: subject::: ::: ", subject);
console.log("sendEmail ::: body::: ::: ", body);
console.log("sendEmail ::: from::: ::: ", from);
let validateRes = await validateEmailId(to);
console.log("sendEmail ::: 1::: ::: ");
if (!validateRes.valid) {
return {
success: false,
reason: "validation-failed",
errors: validateRes.error,
data: null,
};
}
validateRes = await validateEmailId(from);
console.log("sendEmail ::: 2::: ::: ");
if (!validateRes.valid) {
return {
success: false,
reason: "validation-failed",
errors: validateRes.error,
data: null,
};
}
console.log("sendEmail ::: 3::: ::: ");
if (!subject || !body) {
throw new Error("Email subject and body cannot be empty.");
}
console.log("sendEmail ::: 4::: ::: ", to);
const local = await isSuppressed(to);
if (local) {
console.log(`[LOCAL SUPPRESSION] Skipping send to ${to}`);
return {
success: false,
reason: "local-suppressed",
errors: local,
data: null,
};
}
console.log("sendEmail ::: 5::: ::: ", to);
const awsCheck = await checkAwsSuppression(to);
if (awsCheck) {
console.log(`[AWS SUPPRESSION] Skipping send to ${to} :: `, awsCheck);
await addToSuppression(to, "aws-suppressed", awsCheck, "AWS suppression");
return {
success: false,
reason: "aws-suppressed",
errors: awsCheck,
data: null,
};
}
console.log("sendEmail ::: 6::: ::: ");
// ✅ Validate content before sending
const validation = await validateEmailContent({ subject, body });
console.log("sendEmail ::: 65::: ::: ", validation);
if (!validation.valid) {
console.warn(
`❌ Email content validation failed for ${to}:`,
validation.errors
);
return {
success: false,
reason: "validation-failed",
errors: validation.errors,
data: null,
};
}
console.log("sendEmail ::: 7::: ::: ", SendEmailCommand);
const command = new SendEmailCommand({
Destination: { ToAddresses: [to] },
Content: {
Simple: {
Subject: { Data: subject },
Body: { Html: { Data: body } },
},
},
FromEmailAddress: from || process.env.SES_FROM_ADDRESS,
});
console.log("sendEmail ::: 8::: ::: ");
try {
const res = await ses.send(command);
console.log(`📩 Email sent to ${to} - MessageId: ${res.MessageId}`);
return {
success: true,
reason: null,
errors: null,
data: res,
};
} catch (err) {
console.error("❌ Send failed:", err);
if (err.name === "MessageRejected") {
await addToSuppression(to, "bounce", { error: err }, "MessageRejected");
}
throw err;
}
}
module.exports = {
sendEmail,
isSuppressed,
addToSuppression,
handleSnsNotification,
checkAwsSuppression,
};