The Proper Way To Send Email — NodeJs & AWS

Eren Yatkin
3 min readFeb 4, 2021

Hi internet, I hope you are having a wonderful day. Today is a beautiful day in Istanbul. Sun is up and brightens our hearts. Lately I have been stopped to being productive because current lockdown affected me in the worst way.

But today all of a sudden, sun dropped the will of helping others into my heart again and I decided to write about recent feature that I added into the boilerplate.

https://www.freepik.com/free-photo/email-network-communication-perforated-paper-letter_3216861.htm

Astronied.com The Gamification API uses the boilerplate to provide seamless service and would be appreciated if you support it!

At some point we are all encounter that the same problem which is sending e-mail. There tons of 3rd party tools that does this for you but today we are going to implement our solution.

Let’s see what we need!

  • AWS Account
  • NodeJs 12.0.0^
  • E-mail Account
  • Nodemailer
  • Aws-Sdk

If you have prepared everything above, we can start right away!

Do not forget to join my journey and follow me on;

Twitch — Solo entrepreneur, building Astronied.com

Twitter — Solo entrepreneur, building Astronied.com

First thing is first; let’s create a NodeJs application. If you pass -y Npm will skip the form things and create package.json for us.

npm init -y

Then we need to install packages. Do not forget to pass --save otherwise packages will not be saved in package.json

npm install --save nodemailer aws-sdk

Let’s create a file called mailer.js and add some basics like below.

touch mailer.js

const awsSdk = require('aws-sdk');
const nodeMailer = require('nodemailer');
let mailClient;module.exports.init = () => {};
module.exports.getClient = () => {};

Okay, init() will there to help us to create an nodemailer instance and getClient() will help us to use that instance whenever we want.

With this design I would like to use different providers or platforms to send e-mails. I have Yandex Enterprise and AWS SeS. Dynamically switching back and froth between them would be really nice feature. To do so;

I have created two function to create an nodemailer instance with different options. initMailer() will create a SMTP transport with given server configuration and initSes() will create a AWS SeS transport, therefore we updated the configuration and created an SeS() instance via Aws-Sdk then pass it to the Nodemailer.

function initSes() {    awsSdk.config.update({
accessKeyId: '**************',
secretAccessKey: '************',
region: '***************',
ses: {
apiVersion: '2010-12-01',
},
});
mailClient = nodeMailer.createTransport({
ses: new awsSdk.SES(),
});
}function initMailer() { mailClient = nodeMailer.createTransport({
host: 'smtp.yandex.ru',
port: 465,
auth: {
user: '************',
pass: '**************',
},
dkim: {
domainName: "example.com",
keySelector: "2017",
privateKey: "***************",
},
tls: {
// do not fail on invalid certs
rejectUnauthorized: false,
},
});
}

module.exports.init = () => {
if (process.env.USE_SES) {
initSes();
} else {
initMailer();
}
};

Well here we have fully working e-mail client for our backend project. Simple steps to take but creates strong foundation.

Let’s make sure it’ s working properly.

touch index.js

const { getClient } = require('./mailer');module.exports.sendEmail = ({ subject, emailBody, receiver }) => mailerLoader.getClient()
.sendMail({
from: `"Boilerplate 🚀" <${example@mail.com}>`,
to: receiver,
subject,
// html: emailBody,
// text: emailBody,
});

As you see we can send create content like HTML or plain text and send them via e-mail from our backend.

So we reach to the end and to sum up.

This configuration opens up plenty of use cases, you can switch between transports or you can use both of them at the same time. Well of course you can always add new transports and easily send e-mails.

If you have any questions or recommendations let me know in the comments. Your feedbacks are so important and priceless so feel free to share!

Bonus

I would like to add a nice to have for our use! You can easily verify the intance with the configuration you provided. Just call the verify and see what’s going on.

mailClient.verify((error, success) => {
if (error) {
logger.error('SMTP Mail transport is failed', {
error });
} else {
logger.info('SMTP Mail transport is verified', { success });
}
});

--

--

Eren Yatkin

Fullstack software developer who wants to share his knowledge across the universe