Setting up Node.js Email Server with Nodemailer and Mailtrap
Tags: javascript, node, nodemailer, webdev
Published: 2023-03-22 01:15:27

## Introduction

The email service is one of the services common to every software application. Emails are used to communicate pieces of information mostly about downtime, updates and verification of activities by the user in a software application. 
In this tutorial, we will be demonstrating how to set up an email server in a Node.js application using Nodemailer and Mailtrap. First of all, let us learn the basics!

### Nodemailer

[**Nodemailer**](https://nodemailer.com/about/) is a module for Node.js applications that allows easy-as-cake email sending. The project started back in 2010 when there was no better option for sending email messages, today it is still the solution most Node.js users turn to by default. Underneath the hood, Nodemailer uses the Node.js core module `net` to create a connection to the SMTP server specified in the transport object. Once a connection is established, Nodemailer uses the SMTP protocol to send email messages by sending various commands and responses over the connection. 

Here's a simplified example of how Nodemailer sends an email message:

- Create a transport object that defines the SMTP server, authentication credentials, and other options.
- Create a message object that defines the email message, including the sender, recipient, subject, and body.
- Use the `transporter.sendMail()` method to send the message, passing in the message object and a callback function to handle any errors or responses.
- Nodemailer uses the transport object to establish a connection to the SMTP server and send the message using the SMTP protocol. If the message is sent successfully, Nodemailer returns a response object containing information about the message, like the message ID and the response from the SMTP server.

Overall, Nodemailer provides a simple and powerful interface for sending email messages in Node.js, taking away the complexities of the SMTP protocol and allowing developers to focus on the content and delivery of their messages.

### Mailtrap

[**Mailtrap**](https://mailtrap.io/home) is a service that provides a mock SMTP server for testing and development purposes. It allows developers to test their email-sending functionality without actually sending emails to real recipients. Mailtrap works by creating a temporary SMTP server that is accessible through a unique hostname and port number. When an email is sent to the Mailtrap server, it is intercepted and stored in your Mailtrap inbox instead of being sent to the intended recipient. Mailtrap also provides a web interface that allows you to view and manage your test email messages, as well as features like email forwarding and spam testing.

Here are the following steps to enable Mailtrap to work with Nodemailer:

- Sign up for a Mailtrap account and create a new inbox.
- Retrieve your SMTP credentials from the Mailtrap inbox settings.
- Configure Nodemailer to use the Mailtrap SMTP server by creating a transport object with the SMTP settings from Mailtrap.
- Use the `transporter.sendMail()` method to send email messages, just like you would with any other SMTP server.
- Check your Mailtrap inbox to see the test email message. The message will be displayed in the inbox with its headers and content, allowing you to verify that it was sent correctly.

Overall, Mailtrap is a useful tool for testing and debugging email functionality in a safe and controlled environment. By using Mailtrap with Nodemailer, developers can test their email-sending functionality without the risk of accidentally sending test emails to real recipients or getting blocked by spam filters.

## Setting up the Email Server

Now that we’ve had the basics out of the way, let us delve into a more interesting part: we will be setting up the email server using Node.js. The process follows this form;

### Creating Mailtrap Account
- Go to the Mailtrap website and sign up. When the sign up is completed, you will see a screen like the one below.
![mailtrap-setup1](https://paper-attachments.dropboxusercontent.com/s_E8E39712494A865AA598A0DEBBEA08A4CC861250A5102F3611AB033F22A8496A_1679381917108_image.png)

- Click on Email Testing to get your secret credentials. Select Nodemailer as an integration option and you will get a screen like the one below.
![mailtrap-setup2](https://paper-attachments.dropboxusercontent.com/s_E8E39712494A865AA598A0DEBBEA08A4CC861250A5102F3611AB033F22A8496A_1679382150125_image.png)

- At this point, you’d have to save the keys, it would be needed to set up the application later.
## Setup Node.js Project

To set up our Node.js server, we need to create a project folder that will contain our application. For this tutorial, we will call the folder `node-email-server`. 

- To begin, we will run the following commands from our terminal.

```js
    cd desktop && mkdir node-email-server
    cd node-email-server
    code .    /** this is to open the folder in our code editor (VSCode) */
```

- In the root folder, run the following command to install the packages we will be using 

```js
    npm install nodemon nodemailer dotenv cors express mailgen
```
Nodemon—automatically restarts the node application when file changes in the directory are detected.
Cors—for providing an Express middleware that can be used to enable [**CORS**](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) with various options.
Express—Node.js web application framework that provides a robust set of features for web and mobile applications.
Mailgen—Node.js package that generates clean, responsive HTML e-mails for sending transactional mail.


- Create a `.env` file in the root folder—this is where we will store the Mailtrap keys we generated earlier. 

```js
    EMAIL=<sender's email address>
    USER=<mailtrap user key>
    PASSWORD=<mailtrap password>
```

- We will proceed to create the server file, in our case, it is the `index.js` file. Add the following code to the server file

```js
    import express from 'express';
    import cors from 'cors';
    import dotenv from 'dotenv';
    import nodemailer from 'nodemailer';
    import Mailgen from 'mailgen';
    
    dotenv.config()   // configure our app to use env variables
    const app = express();
    /** middlewares */
    app.use(express.json());
    app.use(cors());
    app.disable('x-powered-by'); // less hackers know about our stack
    
    const port = process.env.PORT || 8080;
    /** HTTP GET Request */
    app.get('/', (req, res) => {
        res.status(201).json("Health Check PASS");
    });
    
    
    // create reusable transporter object using the default SMTP transport
    const transporter = nodemailer.createTransport({
        host: 'smtp.mailtrap.io',
        port: 2525,
        auth: {
            user: process.env.USER, // generated mailtrap user
            pass: process.env.PASSWORD, // generated mailtrap password
        }
    });
    // generate email body using Mailgen
    const MailGenerator = new Mailgen({
        theme: "default",
        product : {
            name: "Test Email",
            link: 'https://mailgen.js/'
        }
    })
    // define a route for sending emails
    app.post('/send-email', (req, res) => {
        // get the recipient's email address, name and message from the request body
        const { to, name, message } = req.body;
        // body of the email
        const email = {
            body : {
                name: name,
                intro : message || 'Welcome to Test Mail! We\'re very excited to have you on board.',
                outro: 'Need help, or have questions? Just reply to this email, we\'d love to help.'
            }
        }
        const emailBody = MailGenerator.generate(email);
        // send mail with defined transport object
        const mailOptions = {
            from: process.env.EMAIL,
            to: to,
            subject: 'Test Email',
            html: emailBody
        };
        transporter.sendMail(mailOptions, (error, info) => {
            if (error) {
                console.log(error);
                res.status(500).send('Error sending email');
            } else {
                console.log('Email sent: ' + info.response);
                res.send('Email sent successfully');
            }
        });
    });
    // start the server
    app.listen(port, () => {
        console.log(`Server started on port ${port}`);
    });
   ``` 

Firstly, we imported the packages we will be needing and created an app instance using `express`. We defined our middleware and port. The interesting parts are:

- The email transport instance was created with `nodemailer` and using the SMTP details that `mailtrap` provided us
- The function `MailGenerator`  which we used to generate clean, responsive HTML e-mails.
- The route which houses those logics we need for sending email requests to the server whenever the `send-email` endpoint is called.
- Finally, we started the server and let the app listen to the defined port which we will use to access and test our email API.

## Testing our Email Server

This is my favourite part of the whole process, testing our endpoint to see if our application actually works. For this tutorial, we will be using [Postman](https://www.postman.com/) a HTTP client used to test, debug or document API. You can set up Postman as a desktop application or use it as a web app without installing it on your local machine. Check [here](https://learning.postman.com/docs/getting-started/installation-and-updates/) for more details on how to set it up with any option you want.

### Making a request

Our app is running on `http://localhost:8080` so our endpoint is exposed to this url: `http://localhost:8080/send-email` We will send a `POST` request to the endpoint with three parameters in the body of the request which are: `to`, the email address of the recipient of the mail, `name`, the name of the recipient and `message`, which is optional if we do not want to overwrite the default message in our application. Here is what our Postman request and response will look like.

![postman-test](https://paper-attachments.dropboxusercontent.com/s_E8E39712494A865AA598A0DEBBEA08A4CC861250A5102F3611AB033F22A8496A_1679384294508_image.png)


If we check our Mailtrap account, we will see the mail we just sent and viola! our app works as expected. Here is what mine looks like.

![mailtrap-inbox](https://paper-attachments.dropboxusercontent.com/s_E8E39712494A865AA598A0DEBBEA08A4CC861250A5102F3611AB033F22A8496A_1679384589678_image.png)

## Conclusion

We have learnt how to use Nodemailer and Mailtrap to set up a Node.js email server and also how these technologies work behind the scene. The code repository for this project can be found [here](https://github.com/DesmondSanctity/node-email-server).
Note that Nodemailer works with other SMTP providers like Gmail, Hotmail, MailGun, SendGrid, SendinBlue, etc. The list of supported services can be found [here](https://nodemailer.com/smtp/well-known/) too. 

If you enjoyed the article, feel free to leave a comment, give it a shout-out and share it with others. Bueno!