Don't get burned by email
Tags: javascript, tutorial, api, startup
Published: 2021-07-27 12:13:38

When we noticed [Gary Bernhardt's tweet](https://twitter.com/garybernhardt/status/1390461076974735363) about the major outage of [SendGrid services](https://status.sendgrid.com/incidents/bj70jkn55zv8) we realized, we could get burned as well and looked at how [Superface](https://superface.ai/) could help.

This tutorial will help you to send transactional emails with the maximum reliability using [Superface OneSDK](https://github.com/superfaceai/one-sdk-js).

By the end of the tutorial, you’ll have an email integration that:

- automatically fails over and recovers between multiple email providers using circuit breaker pattern
- gives you clear insights into your email usage across all providers
- notifies you when things go wrong and actively suggests improvements

## Providers and setup

The simplest step you can do to improve your application is to use two providers with failover.

For the purpose of this tutorial, we will use [example.com](http://example.com/) as a sender domain and [hello@example.com](mailto:hello@example.com) as a sender email address. We’ll configure SendGrid to be the primary and Postmark the secondary email provider. Feel free to use your own domains & providers of choice (although currently only Sendgrid, Postmark, Mailgun & Mandrill by Mailchimp are supported).

You need to do two things, to be able to send emails:

1. Verify domain or configure single email address
2. Get API Key to access provider APIs

- **SendGrid**: [How to verify domain](https://docs.sendgrid.com/ui/account-and-settings/how-to-set-up-domain-authentication), [How to get API Key](https://docs.sendgrid.com/ui/account-and-settings/api-keys)
- **Postmark**: [How to verify domain](https://postmarkapp.com/support/article/1046-how-do-i-verify-a-domain), [How to get API Key](https://postmarkapp.com/videos/an-introduction-to-postmark-servers)
- **Mandrill** (by Mailchimp): [How to verify domain](https://mailchimp.com/developer/transactional/docs/authentication-delivery/#authentication), [How to get API Key](https://mailchimp.com/developer/transactional/guides/quick-start/#generate-your-api-key)
- **Mailgun**: [How to verify domain](https://documentation.mailgun.com/en/latest/user_manual.html#verifying-your-domain), [How to get API Key](https://documentation.mailgun.com/en/latest/api-intro.html#base-url)

The last step is to [Create Superface account](https://superface.ai/create-account?invitation=resilient_email). It will give you access to details about [send-email](http://superface.ai/communication/send-email) capability, and to your project monitoring, which we will use later.

## Use OneSDK in your application

You can use any of your NodeJS projects or simply clone our [tutorial repository](https://github.com/superfaceai/resilient-email-tutorial).

If you use our tutorial repository, get started with installing dependencies and start the application,

```shell
# Install dependencies
$ npm install

# Start application
$ npm start
```

then open [http://localhost:3000](http://localhost:3000), you should see

![Running App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iashx6zm3ntm2yxq5tle.png)

### Add send-email capability and configure providers

The easiest way to add use cases is to use [Superface CLI](https://github.com/superfaceai/cli). Its interactive install will guide you through the setup, and will automatically install OneSDK that does the hard work of integrating for you. 

The goal is to have two providers (SendGrid and Postmark) with failover and configure `SendEmail` usecase to use [circuit-breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) as failover policy.

```shell
$ npx @superfaceai/cli install communication/send-email -i
```

After finishing the interactive install, you should see a new folder called `superface`. It is a place where all configuration and metadata for OneSDK lives. Also, `package.json` and `package-lock.json` will be updated because CLI added `@superfaceai/one-sdk` as a new dependency.

### Send email

Now it is time to send emails. It should be implemented in `routes/index.js` file.

First you need to import `SuperfaceClient` from `@superfaceai/one-sdk` package

```js
const { SuperfaceClient } = require('@superfaceai/one-sdk');
```

The email will be sent when POST request is received *(Look for TODO: Implement Send Hello email comment).*

Replace the comment and next line with following code

```js
// Create OneSDK instance
const sdk = new SuperfaceClient();

// Load installed profile
const profile = await sdk.getProfile('communication/send-email');

// Use the profile to SendEmail
const to = req.body.to;
const result = await profile.getUseCase('SendEmail').perform({
  to,
  from: 'hello@example.com',
  subject: 'Superface Resilient Email Tutorial',
  text: `Hello ${to} from Superface Tutorial`,
});

// Get and show data
let data;
try {
  data = result.unwrap();
} catch (error) {
  console.error('Send Email Failed: ', error);
  data = { error: 'Uups..' };
}
```

## Try it

Now it is time to run it and try if it works.

Start application with

```shell
$ npm start
```

Open [http://localhost:3000](http://localhost:3000), fill in your email address, and hit `Send Hello`, you should get the message-id as result and receive the email.

![Send with SendGrid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mom0psz7xyxq2spu87pe.png)

### Testing failover

Now let's check how failover works.

You don't want to wait for the next outage, to see if failover works. To emulate the unavailability of SendGrid API, you can point [api.sendgrid.com](http://api.sendgrid.com) to [localhost](http://localhost) in `/etc/hosts`. If you configured a different primary provider, use its respective API base URL.

For unix systems open `/etc/hosts` with sudo

```shell
$ sudo nano /etc/hosts
Password:
```

and enter this line at the end

```txt
127.0.0.1 api.sendgrid.com
```

result should be similar to

```txt
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1	localhost
255.255.255.255	broadcasthost
::1             localhost

127.0.0.1 api.sendgrid.com
```

Now go back to running the application and send a hello to yourself again

![Send with Postmark](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98qhddi8jr43i083s8yz.png)

It looks the same as before, but there is a small change. The message-id has a different structure. And it is because the email was sent with Postmark instead of unavailable SendGrid.

You can also try how OneSDK will recover, by removing [api.sendgrid.com](http://api.sendgrid.com) entry added to `/etc/hosts`. It must be at least 30 seconds from failover to secondary, to get tried primary provider again.et

## Dashboard

If you configured OneSDK with SDK Token, you should also receive an email notification about failover. It contains information such as when the failover happened and the reason.

![Failover email notification](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/69b309s63zxc7kpyqjqq.png)

If you check the [dashboard](https://superface.ai/dashboard), you can see what profiles and providers your application is using, the number of performs, and when the last failover happened.

![Project insights](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2m318kpuv7ogwkit1d4c.png)

## Conclusion

Emails are important in applications we build, without them users are not able to sign in, or worse customers will not receive bought train tickets. Here is how you can make it super resilient with the least effort. 

The best part? You can get this level of resiliency and ease of use for any use case out there! Check out [Superface](https://superface.ai) and [how it works](https://superface.ai/how-it-works).