Mailgun REST API integration from serverless node.js
Tags: node, api, serverless, webdev
Published: 2023-01-14 20:59:24

In this Mailgun integration example we'll show how easy it is to create and deploy a complete serverless backend that integrates with the [Mailgun SaaS](https://mailgun.com) API for sending email messages to your users. 

This article is also available at [codehooks.io](https://codehooks.io/docs/examples/mailgun-integration-example).

Before you begin, you need to create a new Codehooks project, if you don't have one already.

## Create a new serverless backend project
```bash
# create a new Codehooks project
coho create mailgunexample

# navigate into the directory for the new project
cd mailgunexample

# install dependent npm packages
npm i codehooks-js form-data node-fetch --save
```

## 4 simple steps to integrate with the Mailgun REST API
1. Get your Mailgun API credentials
2. Create secrets in your serverless backend
3. Create the REST API for sending email
4. Deploy your serverless backend

## 1. Get your Mailgun API credentials
Navigate to your account security setting [directly here](https://app.mailgun.com/app/account/security/api_keys). Help information [is available here](https://help.mailgun.com/hc/en-us/articles/203380100-Where-Can-I-Find-My-API-Key-and-SMTP-Credentials-).

You'll need two secret keys from your Mailgun account: `MAILGUN_APIKEY` and `MAILGUN_DOMAIN`

After locating and inspecting your API-key and domain, protect their content by adding them as encrypted secret environment variables to your serverless backend.

## 2. Create secrets in your serverless backend
It's easy to [add secrets](https://codehooks.io/docs/application-secrets) as environment variables using the CLI command `set-env`.
The example below shows how to create the two secrets we need to access the Mailgun REST API:

```bash
coho set-env "MAILGUN_APIKEY" "XXXXXXXXXXX" --encrypted
coho set-env "MAILGUN_DOMAIN" "example.com" --encrypted 
```

Once the secrets have been added to the serverless runtime we can access them as regular system variables, e.g `process.env.MAILGUN_APIKEY`.


## 3. Create the REST API for sending email

The code example below shows a complete serverless backend application.
The application exposes a REST API endpoint with a `POST` function that calls the Mailgun REST API to send an email to the `body.email` address. We also use the built-in [serverless NoSQL database](https://codehooks.io/docs/nosql-database-api) to store a log of all sent emails.

```js
/*
* Mailgun integration example.
*/
import {app, Datastore} from 'codehooks-js';
import FormData from 'form-data';
import fetch from 'node-fetch';

// Mailgun REST API endpoint address
const MAILGUN_URL = 'api.eu.mailgun.net'; // or api.mailgun.net for US customers

// REST API for sending email to list of recipients
app.post('/sendmail', async function (req, res) {
  // pick from post
  const {email, name} = req.body;
  // create an email as form data
  const form = new FormData();
  form.append('from', 'jones@codehooks.io');
  form.append('to', email);
  form.append('subject', 'Testing Mailgun with Codehooks');
  form.append('text', `Hello ${name}, hope you are ok. Lets meet soon.`);
  // Mailgun api endpoint
  const url = `https://${MAILGUN_URL}/v3/${process.env.MAILGUN_DOMAIN}/messages`;
  // Mailgun credentials must be base64 encoded for Basic authentication
  const credentials = Buffer.from(`api:${process.env.MAILGUN_APIKEY}`).toString('base64');
  // POST REST API with the email form data
  const resp = await fetch(url, {
    method: 'POST',
    headers: {
      "Authorization": `Basic ${credentials}`
    },
    body: form
  });
  // handle response errors or OK data
  if (resp.status <= 201) {
    // Success, return Mailgun response to the REST API client
    const output = await resp.json();
    console.log("Success", output);
    // insert log to the NoSQL database
    const db = await Datastore.open();    
    const doc = await db.insertOne('maillog', {email, name, output});  
    return res.status(201).json(output);
  } else {
    console.error(rest.status, resp.statusText);
    // pass the Mailgun error to the REST API client
    return res.status(resp.status).json({error: resp.statusText});
  }    
})

// bind to serverless runtime
export default app.init();
```

## 4. Deploy your serverless backend

I just love to deploy serverless backends to the Codehooks.io cloud service, it's so easy and instant.

From the project directory run the CLI command for deployment:

```bash
coho deploy

# example output
Project: mailgunexample-8jto  Space: dev
Deployed Codehook successfully! 🙌 
```

The serverless backend API is now live and available for traffic in the cloud. It you run the CLI command [`coho info --examples`](https://codehooks.io/docs/cli#info) you will see your backend endpoint address and some curl examples to get you started with testing.

## Testing your Mailgun integration

[Postman](https://www.postman.com/api-platform/api-testing/), [Thunder](https://marketplace.visualstudio.com/items?itemName=rangav.vscode-thunder-client) or [curl](https://curl.se) are great tools for API development and testing. In this example we'll keep it simple and use curl to test our new serverless API.

```bash
curl --location --request POST 'https://mailgunexample-8jto.api.codehooks.io/dev/sendmail' \
--header 'x-apikey: bb00d714-c4f2-4df7-9ecb-ad2ce4b29362' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "Jane",
    "email": "jones@restdb.io"
}'

# Mailgun response on success
{"id":"<20230114154601.5d0bb6cd74064224@example.com>","message":"Queued. Thank you."}
```
:::tip
Use the [CLI command](https://codehooks.io/docs/cli#logs) `coho logs` to see errors and generally what's going on inside of your runtime application.
:::

Now that our API has processed some traffic, we can [query the NoSQL database](https://codehooks.io/docs/cli#query) to see what data has been written into the sendmail log collection.

```bash
coho query maillog --pretty

# Database output
{
  email: 'jones@restdb.io',
  name: 'Jane',
  output: {
    id: '<20230114161849.9231a6192d685842@mg.codehooks.io>',
    message: 'Queued. Thank you.'
  },
  _id: '185b1139873-p6yxdvkww5jz31'
}
...
```

Voilá, we have a complete serverless backend for sending emails via the Mailgun REST API, including a full database log of all requests and results.


A more advanced example covering bulk sending, email templates, data import and worker queues can be found in [this blog post](/blog/mailgun-integration).

The full source code from this Mailgun integration example is available at [GitHub](https://github.com/RestDB/codehooks-io-examples/tree/main/mailgunexample).

Happy coding!