Created
October 30, 2020 18:12
-
-
Save bunnyhawk/9faf7e203ba2dd726e4e7bc543a34070 to your computer and use it in GitHub Desktop.
aws nodemailer handler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
// Express is our server here. It will host any routes we need to leverage (in this case, just the one) | |
const express = require("express"); | |
const sls = require("serverless-http"); // Serverless wrapper | |
const bodyParser = require("body-parser"); // Middleware that parses our incoming requests | |
const Busboy = require("busboy"); // Busboy is used to parse HTML data from our form | |
const nodemailer = require("nodemailer"); | |
const { Logger } = require("lambda-logger-node"); // Optional: Provides cleaner error logging in AWS | |
const app = express(); // Kick off the server | |
const logger = Logger(); // Start a logger to better understand errors | |
// Setting up our server and making sure it's ready to handle outside (non-CORS) incoming requests | |
app.use(bodyParser.urlencoded({ extended: true })); | |
app.use(bodyParser.json()); | |
app.use(bodyParser.raw()); | |
app.use(function (req, res, next) { | |
res.header("Access-Control-Allow-Origin", "*"); | |
res.header("Access-Control-Allow-Credentials", true); | |
res.header( | |
"Access-Control-Allow-Headers", | |
"x-www-form-urlencoded, Origin, X-Requested-With, Content-Type, Accept, Authorization, *" | |
); | |
next(); | |
}); | |
// This is our POST route that the form will leverage | |
app.post("/send-mail", async (req, res, next) => { | |
const result = { | |
files: [], | |
}; | |
// Initial headers for our request | |
var busboy = new Busboy({ | |
headers: { | |
...req.headers, | |
"content-type": | |
req.headers["Content-Type"] || req.headers["content-type"], | |
}, | |
}); | |
// Busboy is watching for attached files and setting up our object(s) to pass along | |
busboy.on("file", function (fieldname, file, filename, encoding, mimetype) { | |
let currentFile = { | |
filename, | |
encoding, | |
contentType: mimetype, | |
data: [], | |
}; | |
// Building a data array from the incoming stream | |
file.on("data", function (data) { | |
currentFile.data.push(data); | |
}); | |
// Once finished, concat the data in to a single Buffer object | |
file.on("end", function () { | |
currentFile.data = Buffer.concat(currentFile.data); | |
result.files.push(currentFile); | |
}); | |
}); | |
// Busboy is watching for the remaining fields and building a result map | |
busboy.on("field", function (fieldname, value) { | |
try { | |
result[fieldname] = JSON.parse(value); | |
} catch (err) { | |
result[fieldname] = value; | |
} | |
}); | |
// Once data is handled, kick off the transport message | |
busboy.on("finish", function () { | |
main(); | |
}); | |
req.pipe(busboy); | |
function main() { | |
let transporter = nodemailer.createTransport({ | |
host: "smtp.gmail.com", // Notes on this below | |
port: 587, | |
secure: false, // true for 465, false for other ports | |
auth: { | |
user: "example@gmail.com", | |
pass: process.env.MAIL_ACCESS, // Passed in via the YAML | |
}, | |
}); | |
// Build the message | |
const message = { | |
from: '"Mike" <example@gmail.com>', // sender address | |
to: "receiver@gmail.com", // list of receivers | |
subject: "Honor A Loved One: Submission", | |
text: "A submission for consideration on the COVID Memorial", // plain text body | |
html: `<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
</head> | |
<body> | |
<h1>Honor A Loved One: Submission</h1> | |
<p>THE DECEASED</p> | |
<ul> | |
<li>First Name: ${result.firstName}</li> | |
<li>Last Name: ${result.lastName}</li> | |
<li>Age: ${result.age}</li> | |
<li>Location: ${result.location}</li> | |
<li>What were they like?: ${result.about}</li> | |
</ul> | |
<p>SUBMITTER</p> | |
<ul> | |
<li>Name: ${result.submitName}</li> | |
<li>Relation: ${result.submitRelation}</li> | |
<li>Email: ${result.email}</li> | |
</ul> | |
</body> | |
</html>`, | |
attachments: result.files.map((file, index) => ({ | |
filename: file.filename, | |
content: new Buffer.from(file.data, "binary"), | |
contentType: file.contentType, | |
})), | |
}; | |
// Send it out! | |
transporter.sendMail(message, function (err, info) { | |
if (err) { | |
logger.error(err); | |
} else { | |
res.status(200).send("Submit is a success"); | |
} | |
}); | |
} | |
}); | |
// Matches up with in our YAML as functions: -> covidApi: -> handler: | |
module.exports.covidApi = sls(app); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment