---
url: /technical/webhooks-mailgun.md
description: >-
  An example webhook process that validates and processes an inbound Mailgun
  email.
---

# Mailgun Example Webhook

This example shows a [webhook](/technical/webhooks)-triggered process that receives an inbound email notification from [Mailgun](https://www.mailgun.com/) and saves any attached files to a Datasource.

Mailgun POSTs the parsed email as form data to the webhook URL. Inside the Process's script, that data is available as a JSON string on [`WEBHOOK.body`](/technical/webhooks.html#the-webhook-object), so `JSON.parse(WEBHOOK.body)` gives back the fields Mailgun sent, including `timestamp`, `token`, `signature`, and any `files`.

Because a webhook URL can be called by anyone who has it, the script should verify the request actually came from Mailgun before acting on it. Mailgun signs every request with a value derived from your account's signing key, the request `timestamp` and the request `token`, hashed with HMAC-SHA256 and hex-encoded (see [Mailgun's webhook security docs](https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/#webhooks)). The signing key is stored as a Process Secret named `MAILGUN_WEBHOOK_SIGN_KEY` and read with [`security.getSecret`](/process-functions/security-getsecret), then compared using [`security.sha256HmacHex`](/process-functions/security-sha256hmachex), which produces the same hex format Mailgun sends in `signature`. If the computed value doesn't match, the script aborts the process with [`script.abort`](/technical/aborting-a-process-programmatically).

Once the payload is verified, the script loops over any `files` on the email and writes each one to the `email_files/` folder of the process's Datasource under its original filename. Mailgun caps the total message size (body plus attachments) at 25MB, so attachments larger than that won't reach the webhook, see [Mailgun's limits documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/limits) for details.

## Setup

1. Create a scriptable process with the script below.
2. [Generate a webhook URL](/technical/webhooks.html#how-to-generate-a-webhook-url) for that process.
3. [Submit a request to the MODLR Team](https://support.modlr.co/request?subject=Set%20up%20Mailgun%20inbound%20email%20webhook\&type=question\&description=Please%20set%20up%20an%20inbox%20address%20that%20forwards%20inbound%20mail%20to%20my%20webhook%20URL%20below%3A%0A%0A) and share the webhook URL with them - they'll set up an inbox address on your behalf that listens for inbound mail and forwards it to your webhook.

```js
const body = JSON.parse(WEBHOOK.body);
const { timestamp, token, signature } = body;
// Example validate payload from Mailgun
const encodedToken = security.sha256HmacHex(security.getSecret("MAILGUN_WEBHOOK_SIGN_KEY"), `${timestamp}${token}`);
if (encodedToken != signature) {
    script.abort('Invalid signature')
    return
}

if (body.files) {
    for (let i = 0; i < body.files.length; i++) {
        const file = body.files[i];
        console.log(file.filename)
        datasource.binarySave(`email_files/${file.filename}`, file.content)
    }
}
```
