Send Email with SendGrid and Mailgen in Node.js
Tags: email, sendgrid, mailgen
Published: 2019-09-11 22:23:30

Often time we do have needs of sending email in our Node.js application. The first option that comes to mind is [Nodemailer](https://nodemailer.com/about/). Nodemailer is a good option except that sometimes it can get quite difficult getting it to work with Gmail SMTP owing to Google's security checks. _This might just be my own opinion and experience_.

[SendGrid](https://www.npmjs.com/package/@sendgrid/mail) is another option for sending emails in Node.js. In my opinion, sending an email with SendGrid is very seamless. Though the service is not completely free, it allows for sending up to 100 emails per day for free.

Another important thing in sending email is generating the email template that complies with email template standard which ensures that it renders correctly on different email clients such as Gmail, Yahoomail, etc. Fortunately, there is an npm package called [Mailgen](https://www.npmjs.com/package/mailgen) which generates a beautiful and standard email template based off of some configurations out of the box.

### Requirements

- SendGrid API Key - To generate a SendGrid API key follow the steps below:
  - Visit [SendGrid](https://sendgrid.com) to create an account
  - Log in to the account created
  - Click on the [settings](https://app.sendgrid.com/settings/api_keys) on the left sidebar
  - Click on the create on the `Create API Key` button to create an API Key.
- A node/Express application.

### Getting Started

To follow along, clone the project used in this tutorial [here](https://github.com/oriechinedu/sendgrid-mailgen-email-node).

### Step 1 - Setup express project

Create a new directory called `sendgrid-email`.

```
mkdir sendgrid-email && cd sendgrid-email
```

Next up, open the project in your favorite text editor and install the following dependencies:

```
npm i express dotenv mailgen @sendgrid/mail
```

Next up, create a file named `index.js` at the root of the project and copy the following code into it:

```javascript
const express = require('express')
const sendMail = require('./mail')
const app = express()

app.use(express.json())

app.get('/', (req, res) => res.send('Hello world!!!'))

app.get('/sendMail', async (req, res) => {
  try {
    const sent = await sendMail()
    if (sent) {
      res.send({ message: 'email sent successfully' })
    }
  } catch (error) {
    throw new Error(error.message)
  }
})

app.listen(3300, () => {
  console.log('server listening at http://localhost:3300')
})
```

_**NB:** Our concern is to set up a simple server top demo the concept in this article and as such no attention is paid to best practices.🙂_

Looking at the snippet above, we added a route `/sendMail` which calls a function `sendMail()` imported from `mail.js`. Let's create the content of `mail.js`.

### Step 2 - Generate email template with Mailgen

Create a file named `mail.js` and copy the following code into it:

```javascript
const MailGen = require('mailgen')
const sgMail = require('@sendgrid/mail')

require('dotenv').config()

const mailGenerator = new MailGen({
  theme: 'salted',
  product: {
    name: 'Awesome App',
    link: 'http://example.com',
    // logo: your app logo url
  },
})

const email = {
  body: {
    name: 'Jon Doe',
    intro: 'Welcome to email verification',
    action: {
      instructions: 'Please click the button below to verify your account',
      button: {
        color: '#33b5e5',
        text: 'Verify account',
        link: 'http://example.com/verify_account',
      },
    },
  },
}

const emailTemplate = mailGenerator.generate(email)
require('fs').writeFileSync('preview.html', emailTemplate, 'utf8')
```

We imported the `Mailgen` module and then created an instance of it called `mailGenerator`. The mailGenerator takes the theme, there are several [themes](https://www.npmjs.com/package/mailgen#more-examples) you can choose from. The `product` object takes `name` which is the name of your application, `link` the application URL and also `logo` which takes the URL of your application logo.

Next up, we configured the email body and then generated the email template. See the [Mailgen docs](https://www.npmjs.com/package/mailgen) for more details on how to configure the email body. This line `require('fs').writeFileSync('preview.html', emailTemplate, 'utf8')` is optional, you add it if you want to preview the HTML file generated by Mailgen.

### Step 3 - Send email using SendGrid

Copy the API Key you created earlier into `.env`, check `.env.example` for a guide.
Next up, copy the snippet below into `mail.js`:

```javascript
const msg = {
  to: 'your-email@example.com',
  from: 'test@example.com',
  subject: 'Test verification email',
  html: emailTemplate,
}

const sendMail = async () => {
  try {
    sgMail.setApiKey(process.env.SENDGRID_API_KEY)
    return sgMail.send(msg)
  } catch (error) {
    throw new Error(error.message)
  }
}

module.exports = sendMail
```
Setting up SendGrid is very easy as you can see above, all you need is to pass the API Key as shown above and then construct the message and send. We passed the `emailTemplate` generated earlier into the SendGrid `msg`. 

Check the [@sendgrid/mail docs](https://www.npmjs.com/package/@sendgrid/mail) for more information on how to configure it.

That is it! Now start the server and head over to Postman and hit the `/sendMail` route.
If everything is alright, you receive an email that looks as shown below:

![Image showing the email sent](https://thepracticaldev.s3.amazonaws.com/i/4c9go3u6n49eyot4dgrn.png).

You can also preview the email template by opening the `preview.html` on the browser.

### Conclusion
So far we have demonstrated how we can create beautiful email template using Mailgen and send the mail using SendGrid. In a bid to keeping it simple, we implemented everything inside the `mail.js`, in practice, you might want to separate it into re-usable modules. For example, you can create a function for generating the email template based on some parameters so that you can easily call it each time you want to send an email.

Let me know if you have any question or contribution. I am open for discussion. Just reach out to me anytime.

_[This was originally published on my blog](https://www.oriechinedu.com/posts/send-email-with-sendgrid-and-mailgen-in-nodejs/)_