Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event webhook docker #804

Merged
merged 3 commits into from
Oct 29, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}!`))
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: 'example@test.com',
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: 'example@test.com',
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: 'example@test.com',
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: 'example@test.com',
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: 'example@test.com',
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: 'example@test.com',
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: 'example@test.com',
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: 'example@test.com',
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: 'example@test.com',
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: 'example@test.com',
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: 'example@test.com',
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