Skip to content

Commit

Permalink
Merge pull request #804 from aroach/event-webhook-docker
Browse files Browse the repository at this point in the history
Event webhook docker
  • Loading branch information
thinkingserious authored Oct 29, 2018
2 parents 0bdab10 + 35b073c commit 57b4e7b
Show file tree
Hide file tree
Showing 16 changed files with 176 additions and 141 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Introduction

This is an example project for using a Docker container as a [SendGrid](https://sendgrid.com) [inbound parse email](https://sendgrid.com/docs/for-developers/parsing-email/setting-up-the-inbound-parse-webhook/) webhooks.
This is an example project for using a Docker container as a [SendGrid](https://sendgrid.com) [inbound parse email](https://sendgrid.com/docs/for-developers/parsing-email/setting-up-the-inbound-parse-webhook/) webhooks and [event webhooks](https://sendgrid.com/docs/for-developers/tracking-events/getting-started-event-webhook/)

# Prerequisites

* [Docker CE 18](https://www.docker.com/get-started)
* (Optional for development) A local Kubernetes installation
* SendGrid Account with inbound parse enabled to send form data (default)
* [Setup Inbound Parse Webhook](https://sendgrid.com/docs/for-developers/parsing-email/setting-up-the-inbound-parse-webhook/)
* SendGrid Account with event webhooks enabled
* [Getting Started with Event Webhook](https://sendgrid.com/docs/for-developers/tracking-events/getting-started-event-webhook/)
* [Ngrok](https://ngrok.com/) or Internet accessible URL

# Usage Locally (aka for Development)
Expand All @@ -19,20 +21,25 @@ This is an example project for using a Docker container as a [SendGrid](https://
* `rm -rf sendgrid-nodejs/`
* Build the container: `docker-compose build`
* Run the container: `docker-compose up`
* (Optional to save your self both commands above) Build & Run the container: `docker-compose build && docker-compose up`
* (Optional to save your self both commands above) Build & Run the container: `docker-compose up --build`
* Run ngrok: `ngrok http 3000`
* Create an entry in the [Settings > Inbound Parse](https://app.sendgrid.com/settings/parse) with the ngrok URL. Use the `https` ngrok entry.
* Send an email to your inbound parse email address.
* For inbound parse:
* Create an entry in the [Settings > Inbound Parse](https://app.sendgrid.com/settings/parse) with the ngrok URL. Use the `https` ngrok entry.
* Send an email to your inbound parse email address.
* For event webhook
* Configure the [Settings > Mail Settings > Event Notification](https://app.sendgrid.com/settings/mail_settings)

NOTE: ngrok has a "replay" feature so you don't have to keep sending emails to yourself. You can access that when ngrok is running at [http://127.0.0.1:4040/inspect/http](http://127.0.0.1:4040/inspect/http)

# Modifying the application

At the moment, the `app.js` only prints data to the console. You can extend this project by adding more business logic to the `/parse_webhook` route.
At the moment, the `app.js` only prints data to the console. You can extend this project by adding more business logic to the `/parse_webhook` or `/event_webhook` routes, contained in the [routes/inbound-parse.js](routes/inbound-parse.js) and [routes/events.js](routes/events.js).

## A note on processing events

This project uses the [express-formidable](https://github.com/utatti/express-formidable) middleware to process the form data sent by SendGrid's Inbound Parse Webhook.

### Inbound Parse Webhook

The [routes/inbound-parse.js](routes/inbound-parse.js) route uses the [express-formidable](https://github.com/utatti/express-formidable) middleware to process the form data sent by SendGrid's Inbound Parse Webhook.

The events are available in the `/parse_webhook` route in the `req.fields` object. The [app.js](app.js) contains logging statements for the elements that are available to you. It may be useful to review the [example-webhook-payload.txt](example-webhook-payload.txt) for what the form data looks like when extending this application.

Expand All @@ -46,6 +53,10 @@ app.use(formidable({
});
```
### Events Webhook
The [routes/events.js](routes/events.js) route receives data in JSON format.
Additionally, the [docker-compose](docker-compose.yml) has a volume mapping commented out if you'd prefer to store them in persistent storage outside of the container.
# Deployment to Kubernetes
Expand Down
14 changes: 14 additions & 0 deletions examples/webhooks-docker/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const express = require('express')
const app = express()
const port = 3000

const eventWebhook = require('./routes/events')
const parseWebhook = require('./routes/inbound-parse')

app.get('/', (req, res) => res.status(200).json({status: 'ok'}))

app.use('/event_webhook', eventWebhook)
app.use('/parse_webhook', parseWebhook)


app.listen(port, () => console.log(`SendGrid webhook listener started on port ${port}!`))
File renamed without changes.
97 changes: 97 additions & 0 deletions examples/webhooks-docker/example-event-notification.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
[ { email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'processed',
category: 'cat facts',
sg_event_id: '3VQNwQVlOAoGt_mNmMf7Uw==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0' },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'deferred',
category: 'cat facts',
sg_event_id: 'Ge2kc923E-UtbFcT6uJCtw==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
response: '400 try again later',
attempt: '5' },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'delivered',
category: 'cat facts',
sg_event_id: 'WexDVCfDCkJ22oAzZDiiYw==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
response: '250 OK' },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'open',
category: 'cat facts',
sg_event_id: 'mSJ9e9BP2yLTzvStpKhcgw==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
useragent: 'Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
ip: '255.255.255.255' },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'click',
category: 'cat facts',
sg_event_id: 'WMOHWv9ZJxMG0-YhbdoTPA==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
useragent: 'Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
ip: '255.255.255.255',
url: 'http://www.sendgrid.com/' },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'bounce',
category: 'cat facts',
sg_event_id: 'wMeZZPhZvsPgUP23YyDFKA==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
reason: '500 unknown recipient',
status: '5.0.0' },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'dropped',
category: 'cat facts',
sg_event_id: 'tIulrwSK8TW4_o1JC79pMg==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
reason: 'Bounced Address',
status: '5.0.0' },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'spamreport',
category: 'cat facts',
sg_event_id: 'fRCOMWprw3XpGSyNSFjybw==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0' },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'unsubscribe',
category: 'cat facts',
sg_event_id: 'hZdan0mTcEueyH0RM-LT8w==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0' },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'group_unsubscribe',
category: 'cat facts',
sg_event_id: 'bleyaOwyAFHJnkQedbujGw==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
useragent: 'Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
ip: '255.255.255.255',
url: 'http://www.sendgrid.com/',
asm_group_id: 10 },
{ email: '[email protected]',
timestamp: 1539462305,
'smtp-id': '<14c5d75ce93.dfd.64b469@ismtpd-555>',
event: 'group_resubscribe',
category: 'cat facts',
sg_event_id: 'nYfQZaZgb0ircWsDYc21Kw==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
useragent: 'Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
ip: '255.255.255.255',
url: 'http://www.sendgrid.com/',
asm_group_id: 10 } ]

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "A containter to capture webhook data from SendGrid inbound parse",
"main": "app.js",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.3",
"express-formidable": "^1.0.0"
},
Expand Down
Loading

0 comments on commit 57b4e7b

Please sign in to comment.