# Node.js Emailing Made Easy: A Beginner's Guide to Nodemailer

## *STEP 0*: *Creating an empty Nodejs repository*

Go to your desired directory and run the below command to setup an empty directory with **package.json**

```bash
npm init -y
```

## *STEP 1: Creating a server*

To create an express server we have to install [express](https://www.npmjs.com/package/express)

### *STEP 1.1: Installing Express*

```bash
npm i express
```

the above command will install the express library to your project.

### *STEP 1.2: Setting up the server*

Create a new javascript file - you can name it anything, for the sake of simplicity let's call it **server.js** A node server can be set up by just three lines of code as :

```javascript
const express = require("express");
const app = express();

app.listen(3000, () => {
    console.log(`App is up and running at port 3000`);
})
```

### *STEP 1.3: Install and configure dotenv*

we will be using some high confidentiality passwords/keys in the project, so it will be beneficial to not save them as such in the project but to create a non-versioned file and store them in that.

to have this kind of feature we have to install [dotenv](https://www.npmjs.com/package/dotenv)

```javascript
npm i dotenv
```

after that create a **.env** file in your project and for now, add the value of PORT there, we will use the value of port from there.

**.env** will look something like this, it stores data in key-value format.

```bash
PORT=3000
```

now to use this value of PORT from **.env**, we have to configure dotenv in the **server.js** file and use the value.

```javascript
const express = require("express");
// This line is setting up the .env so that we can use it in our code
require("dotenv").config();

const app = express();
const port = process.env.PORT // This is how we can use it

app.listen(port, () => {
    console.log(`App is up and running at port ${port}`);
})
```

## *STEP 2*: *Creating an API to send email*

Now we have to create an **app.js** file where our API logic will reside, and we will call it from **server.js**

so **app.js** will look something like this -

```javascript
// Method created by name of sendEmail
const sendEmail = (req, res) => {
    res.json({"Hello": "World"});
}

// Exporting it so that other files can use it
module.exports = {
    sendEmail: sendEmail
}
```

Now we will create a route inside **server.js** as -

```javascript
const express = require("express");
require("dotenv").config();

// Method is imported from app.js so that it can be used
const {sendEmail} = require("./app");

const app = express();
const port = process.env.PORT

// This line adds a middleware function to the Express app that will // be executed for every incoming HTTP request. This middleware 
// function parses the request body of a JSON type, and adds a body 
// property to the request object with the parsed JSON data.
app.use(express.json());

// A POST API which calls sendEmail method upon it's call
app.post("/send-email", sendEmail)

app.listen(port, () => {
    console.log(`App is up and running at ${port}`);
})
```

## *STEP 3*: *Installing and configuring Nodemailer*

Now, to be able to send emails, we have to generate an app password and install [nodemailer](https://www.npmjs.com/package/nodemailer).

### ***STEP 3.1: Generating the app password***

Open Gmail and click on the profile icon

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681409561197/78d5d25e-2091-4f82-9c74-11f5c78891b4.png align="center")

After that click on Manage Account

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681409586401/ec75a853-04ea-45a4-9fc3-730281ec4dba.png align="center")

After that click on Security

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681409611581/2831c781-a1a4-4f81-8b04-8de61f1e1840.png align="center")

Now, make sure you have 2-step verification active on your account, after that scroll down and click on the 2-step verification option

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681409708559/dc5528f2-d397-4554-a55f-3fffe935d083.png align="center")

scroll down and click on App Passwords

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681409696792/31ae6a2c-53c8-4d29-82ad-367fcf2bbe33.png align="center")

On the Select app dropdown click on Other

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681409729312/d4d558de-03db-4827-ab29-9f6a1c06e46e.png align="center")

Name your app

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681409765379/6d0b7e37-e20d-438a-b22c-64b43aff7767.png align="center")

Now, your app password is generated, note this down and it will be used to send the email

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681409790339/a416a008-cfbc-41c1-90d8-8f90d0c2cc95.png align="center")

Now, add the email and the generated app password to your **.env** file, from which we can use it.

```bash
PORT=3000

EMAIL=youcancallmezenitsu@gmail.com
PASSWORD=***************
```

### ***STEP 3.2: Installing Nodemailer***

Now, we need a library through which we can send an email, so we will be using [nodemailer](https://www.npmjs.com/package/nodemailer) for that, we can install it as :

```bash
npm i nodemailer
```

### ***STEP 3.3: Configuring Nodemailer***

To use [nodemailer](https://www.npmjs.com/package/nodemailer) for sending emails, we have to create a transport object using which we can send emails.

After creating the object, and making the required changes in API, **app.js** will look something like this -

```javascript
const nodemailer = require("nodemailer");

// creating the transport object, which will be used to send emails
const transporter = nodemailer.createTransport({
    service: "gmail",
    auth: {
        // email from which email has to be send
        user: process.env.EMAIL, 
        // app password which was generated
        pass: process.env.PASSWORD,
    }
})

// sendEmail method will have three parameters in body - 
// 1. to : email of person to whom email has to be sent
// 2. subject : subject of email to be sent
// 3. text : the actual message body

// note: the message body can also contain HTML, which then be 
// rendered as HTML in email
const sendEmail = async (req, res) => {
    const {to, subject, text} = req.body

    // the send email logic is wrapped in try...catch, so as to 
    // catch the error if there are any
    try {
        await transporter.sendMail({
            from: process.env.EMAIL,
            to: to,
            subject: subject,
            html: text 
        })
        res.status(200).json({message: "email sent successfully"})
    } catch(e) {
        console.log(`Error in sending email ${e}`)
        res.status(500).json({message: e})
    }
}

module.exports = {
    sendEmail: sendEmail
}
```

## *STEP 4*: *Time to test*

Now, we will be calling the API from the postman and will see whether an email is received or not.

I have created a sample payload for the email, it can be modified as per specific use case.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681503220255/438861bd-8cf9-4f8d-ad09-5f261a4c2f85.png align="center")

The Response is - "*email sent successfully"*

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681503289067/ce5e586b-113f-4c5a-90ed-4b2c28a9549f.png align="center")

Now, on checking the mail

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681503378848/62df1573-0765-4ace-9794-d555d9a82660.png align="center")

And since I had sent the text in form HTML, so I received the email in formatted form

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681503435633/16d2a08b-f0ba-4bbf-919d-d04b28fd8f06.png align="center")

**Note**: It is not healthy and good practice to always send the whole HTML or a big text in API, rather what can be done is we can create an HTML file locally and can make it dynamic by using variables.

*Thanks for scrolling!*

![](https://media.giphy.com/media/j0kP7fOkKQlYsXTO2r/giphy.gif align="center")
