From 03a099cf55baf3c4f7bd095baff6fb51234b3c85 Mon Sep 17 00:00:00 2001 From: Ashley Roach Date: Sat, 13 Oct 2018 14:32:54 -0600 Subject: [PATCH 1/3] Add event webhook route to example --- examples/inbound-parse-docker/README.md | 25 ++-- examples/inbound-parse-docker/app.js | 56 +-------- ...ad.txt => example-email-parse-payload.txt} | 0 .../example-event-notification.txt | 97 ++++++++++++++ .../inbound-parse-docker/package-lock.json | 119 ------------------ examples/inbound-parse-docker/package.json | 1 + .../inbound-parse-docker/routes/events.js | 38 ++++++ .../routes/inbound-parse.js | 55 ++++++++ 8 files changed, 214 insertions(+), 177 deletions(-) rename examples/inbound-parse-docker/{example-webhook-payload.txt => example-email-parse-payload.txt} (100%) create mode 100644 examples/inbound-parse-docker/example-event-notification.txt create mode 100644 examples/inbound-parse-docker/routes/events.js create mode 100644 examples/inbound-parse-docker/routes/inbound-parse.js diff --git a/examples/inbound-parse-docker/README.md b/examples/inbound-parse-docker/README.md index 218951b03..56acbf27b 100644 --- a/examples/inbound-parse-docker/README.md +++ b/examples/inbound-parse-docker/README.md @@ -1,6 +1,6 @@ # 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 @@ -8,6 +8,8 @@ This is an example project for using a Docker container as a [SendGrid](https:// * (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) @@ -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. @@ -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 diff --git a/examples/inbound-parse-docker/app.js b/examples/inbound-parse-docker/app.js index 459a55f88..13c1c6f72 100644 --- a/examples/inbound-parse-docker/app.js +++ b/examples/inbound-parse-docker/app.js @@ -1,60 +1,14 @@ const express = require('express') const app = express() -const formidable = require('express-formidable') const port = 3000 -app.use(formidable()) - - +const eventWebhook = require('./routes/events') +const parseWebhook = require('./routes/inbound-parse') app.get('/', (req, res) => res.status(200).json({status: 'ok'})) -app.post('/parse_webhook', (req, res) => { - console.log('---------- START RECEIVED WEBHOOK DATA ----------') - // Email data comes in as a form. Using express-formidable to - // handle the form data. Form fields are available in req.fields - // Below, extracting the from and text. - // You can take this data and do something more interesting with it - // such as sending it to a database. - // Attachments are stored in /tmp based on the default configuration - // of the formidable middleware. - // console.log(req.fields) - console.log() - console.log('HEADERS: ' + req.fields.headers) - console.log() - console.log('DKIM: ' + req.fields.dkim) - // TODO: The server is sending a non JS compliant key name - // console.log() - // console.log('CONTENT-IDS: ' + req.fields.content-ids) - console.log() - console.log('TO: ' + req.fields.to) - console.log() - console.log('HTML: ' + req.fields.html) - console.log() - console.log('FROM: ' + req.fields.from) - console.log() - console.log('SENDER-IP: ' + req.fields.sender_ip) - console.log() - console.log('SPAM-REPORT: ' + req.fields.spam_report) - console.log() - console.log('ENVELOPE: ' + req.fields.envelope) - console.log() - console.log('ATTACHMENTS: ' + req.fields.attachments) - console.log() - console.log('SPAM-SCORE: ' + req.fields.spam_score) - // TODO: The server is sending a non JS compliant key name - // console.log() - // console.log('ATTACHMENT-INFO: ' + req.fields.attachment-info) - console.log() - console.log('CHARSETS: ' + req.fields.charsets) - console.log() - console.log('SPF: ' + req.fields.SPF) - console.log() - console.log('MESSAGE TEXT: ' + req.fields.text) - console.log() - console.log('---------- END RECEIVED WEBHOOK DATA ----------') +app.use('/event_webhook', eventWebhook) +app.use('/parse_webhook', parseWebhook) - res.sendStatus(200) -}) -app.listen(port, () => console.log(`SendGrid Inbound Parse webhook listener started on port ${port}!`)) \ No newline at end of file +app.listen(port, () => console.log(`SendGrid webhook listener started on port ${port}!`)) \ No newline at end of file diff --git a/examples/inbound-parse-docker/example-webhook-payload.txt b/examples/inbound-parse-docker/example-email-parse-payload.txt similarity index 100% rename from examples/inbound-parse-docker/example-webhook-payload.txt rename to examples/inbound-parse-docker/example-email-parse-payload.txt diff --git a/examples/inbound-parse-docker/example-event-notification.txt b/examples/inbound-parse-docker/example-event-notification.txt new file mode 100644 index 000000000..d771409f7 --- /dev/null +++ b/examples/inbound-parse-docker/example-event-notification.txt @@ -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 } ] \ No newline at end of file diff --git a/examples/inbound-parse-docker/package-lock.json b/examples/inbound-parse-docker/package-lock.json index cb49e7cde..f3ee7c31c 100644 --- a/examples/inbound-parse-docker/package-lock.json +++ b/examples/inbound-parse-docker/package-lock.json @@ -4,24 +4,6 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@sendgrid/helpers": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-6.3.0.tgz", - "integrity": "sha512-uTFcmhCDFg/2Uhz+z/cLwyLHH0UsblG49hKwdR7nKbWsGKWv4js7W32FlPdXqy2C/plTJ20vcPLgKM1m3F/MjQ==", - "requires": { - "chalk": "^2.0.1", - "deepmerge": "^2.1.1" - } - }, - "@sendgrid/inbound-mail-parser": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@sendgrid/inbound-mail-parser/-/inbound-mail-parser-6.3.0.tgz", - "integrity": "sha512-4DzcoyHRm9yAYMfeuKpmGpXx7pQHtss865rib6uVCimReSDzjVMslbECWCBb8u2rcfdqvlBZGjqheBU9y95joA==", - "requires": { - "@sendgrid/helpers": "^6.3.0", - "mailparser": "^0.6.1" - } - }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", @@ -31,19 +13,6 @@ "negotiator": "0.6.1" } }, - "addressparser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", - "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -78,29 +47,6 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -129,11 +75,6 @@ "ms": "2.0.0" } }, - "deepmerge": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", - "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==" - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -154,24 +95,11 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -280,11 +208,6 @@ "formidable": "^1.0.17" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, "finalhandler": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", @@ -314,11 +237,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, "http-errors": { "version": "1.6.3", "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -348,17 +266,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" }, - "mailparser": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-0.6.2.tgz", - "integrity": "sha1-A8SGA5vfTfbNO2rcqqxBB9/bwGg=", - "requires": { - "encoding": "^0.1.12", - "mime": "^1.3.4", - "mimelib": "^0.3.0", - "uue": "^3.1.0" - } - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -392,15 +299,6 @@ "mime-db": "~1.36.0" } }, - "mimelib": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.3.1.tgz", - "integrity": "sha1-eHrdJBXYJ6yzr27EvKHqlZZBiFM=", - "requires": { - "addressparser": "~1.0.1", - "encoding": "~0.1.12" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -510,14 +408,6 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, "type-is": { "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", @@ -537,15 +427,6 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, - "uue": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/uue/-/uue-3.1.2.tgz", - "integrity": "sha512-axKLXVqwtdI/czrjG0X8hyV1KLgeWx8F4KvSbvVCnS+RUvsQMGRjx0kfuZDXXqj0LYvVJmx3B9kWlKtEdRrJLg==", - "requires": { - "escape-string-regexp": "~1.0.5", - "extend": "~3.0.0" - } - }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/examples/inbound-parse-docker/package.json b/examples/inbound-parse-docker/package.json index 2258b7322..f863f6082 100644 --- a/examples/inbound-parse-docker/package.json +++ b/examples/inbound-parse-docker/package.json @@ -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" }, diff --git a/examples/inbound-parse-docker/routes/events.js b/examples/inbound-parse-docker/routes/events.js new file mode 100644 index 000000000..2474fcb2d --- /dev/null +++ b/examples/inbound-parse-docker/routes/events.js @@ -0,0 +1,38 @@ +const express = require('express') +const router = express.Router() +const bodyParser = require('body-parser') + +router.use(bodyParser.json()) + +router.post('/', (req, res) => { + + // Modify and extend the business logic applied to the req.body + // array. You could send this to a file, database, or other system + // for storage and analysis. + console.log(req.body) + + let events = req.body + + events.forEach(element => { + console.log() + console.log('---------- EVENT START ----------') + console.log('EMAIL:', element.email) + console.log('TIMESTAMP:', element.timestamp) + // TODO: invalid JSON key name + // console.log('EMAIL:', element.smtp-id) + console.log('EVENT:', element.event) + console.log('CATEGORY:', element.category) + console.log('SG_EVENT_ID:', element.sg_event_id) + console.log('SG_MESSAGE_ID:', element.sg_message_id) + console.log('USERAGENT:', element.useragent) + console.log('IP:', element.ip) + console.log('URL:', element.url) + console.log('ASM_GROUP_ID:', element.asm_group_id) + console.log('---------- EVENT END ----------') + console.log() + }); + + res.sendStatus(200) +}) + +module.exports = router \ No newline at end of file diff --git a/examples/inbound-parse-docker/routes/inbound-parse.js b/examples/inbound-parse-docker/routes/inbound-parse.js new file mode 100644 index 000000000..56298bd08 --- /dev/null +++ b/examples/inbound-parse-docker/routes/inbound-parse.js @@ -0,0 +1,55 @@ +const express = require('express') +const router = express.Router() +const formidable = require('express-formidable') + +router.use(formidable()) + +router.post('/', (req, res) => { + console.log('---------- START RECEIVED WEBHOOK DATA ----------') + // Email data comes in as a form. Using express-formidable to + // handle the form data. Form fields are available in req.fields + // Below, extracting the from and text. + // You can take this data and do something more interesting with it + // such as sending it to a database. + // Attachments are stored in /tmp based on the default configuration + // of the formidable middleware. + // console.log(req.fields) + console.log() + console.log('HEADERS: ' + req.fields.headers) + console.log() + console.log('DKIM: ' + req.fields.dkim) + // TODO: The server is sending a non JS compliant key name + // console.log() + // console.log('CONTENT-IDS: ' + req.fields.content-ids) + console.log() + console.log('TO: ' + req.fields.to) + console.log() + console.log('HTML: ' + req.fields.html) + console.log() + console.log('FROM: ' + req.fields.from) + console.log() + console.log('SENDER-IP: ' + req.fields.sender_ip) + console.log() + console.log('SPAM-REPORT: ' + req.fields.spam_report) + console.log() + console.log('ENVELOPE: ' + req.fields.envelope) + console.log() + console.log('ATTACHMENTS: ' + req.fields.attachments) + console.log() + console.log('SPAM-SCORE: ' + req.fields.spam_score) + // TODO: The server is sending a non JS compliant key name + // console.log() + // console.log('ATTACHMENT-INFO: ' + req.fields.attachment-info) + console.log() + console.log('CHARSETS: ' + req.fields.charsets) + console.log() + console.log('SPF: ' + req.fields.SPF) + console.log() + console.log('MESSAGE TEXT: ' + req.fields.text) + console.log() + console.log('---------- END RECEIVED WEBHOOK DATA ----------') + + res.sendStatus(200) +}) + +module.exports = router \ No newline at end of file From b7d853e638fd046abaa1552449534d52445c4a3b Mon Sep 17 00:00:00 2001 From: Ashley Roach Date: Sat, 13 Oct 2018 14:36:21 -0600 Subject: [PATCH 2/3] Rename parent folder --- examples/{inbound-parse-docker => webhooks-docker}/.dockerignore | 0 examples/{inbound-parse-docker => webhooks-docker}/.gitignore | 0 .../{inbound-parse-docker => webhooks-docker}/CONTRIBUTING.md | 0 examples/{inbound-parse-docker => webhooks-docker}/Dockerfile | 0 examples/{inbound-parse-docker => webhooks-docker}/LICENSE | 0 examples/{inbound-parse-docker => webhooks-docker}/README.md | 0 examples/{inbound-parse-docker => webhooks-docker}/app.js | 0 .../docker-compose.debug.yml | 0 .../{inbound-parse-docker => webhooks-docker}/docker-compose.yml | 0 .../example-email-parse-payload.txt | 0 .../example-event-notification.txt | 0 .../k8s/inbound-parse.yml | 0 .../{inbound-parse-docker => webhooks-docker}/package-lock.json | 0 examples/{inbound-parse-docker => webhooks-docker}/package.json | 0 .../{inbound-parse-docker => webhooks-docker}/routes/events.js | 0 .../routes/inbound-parse.js | 0 16 files changed, 0 insertions(+), 0 deletions(-) rename examples/{inbound-parse-docker => webhooks-docker}/.dockerignore (100%) rename examples/{inbound-parse-docker => webhooks-docker}/.gitignore (100%) rename examples/{inbound-parse-docker => webhooks-docker}/CONTRIBUTING.md (100%) rename examples/{inbound-parse-docker => webhooks-docker}/Dockerfile (100%) rename examples/{inbound-parse-docker => webhooks-docker}/LICENSE (100%) rename examples/{inbound-parse-docker => webhooks-docker}/README.md (100%) rename examples/{inbound-parse-docker => webhooks-docker}/app.js (100%) rename examples/{inbound-parse-docker => webhooks-docker}/docker-compose.debug.yml (100%) rename examples/{inbound-parse-docker => webhooks-docker}/docker-compose.yml (100%) rename examples/{inbound-parse-docker => webhooks-docker}/example-email-parse-payload.txt (100%) rename examples/{inbound-parse-docker => webhooks-docker}/example-event-notification.txt (100%) rename examples/{inbound-parse-docker => webhooks-docker}/k8s/inbound-parse.yml (100%) rename examples/{inbound-parse-docker => webhooks-docker}/package-lock.json (100%) rename examples/{inbound-parse-docker => webhooks-docker}/package.json (100%) rename examples/{inbound-parse-docker => webhooks-docker}/routes/events.js (100%) rename examples/{inbound-parse-docker => webhooks-docker}/routes/inbound-parse.js (100%) diff --git a/examples/inbound-parse-docker/.dockerignore b/examples/webhooks-docker/.dockerignore similarity index 100% rename from examples/inbound-parse-docker/.dockerignore rename to examples/webhooks-docker/.dockerignore diff --git a/examples/inbound-parse-docker/.gitignore b/examples/webhooks-docker/.gitignore similarity index 100% rename from examples/inbound-parse-docker/.gitignore rename to examples/webhooks-docker/.gitignore diff --git a/examples/inbound-parse-docker/CONTRIBUTING.md b/examples/webhooks-docker/CONTRIBUTING.md similarity index 100% rename from examples/inbound-parse-docker/CONTRIBUTING.md rename to examples/webhooks-docker/CONTRIBUTING.md diff --git a/examples/inbound-parse-docker/Dockerfile b/examples/webhooks-docker/Dockerfile similarity index 100% rename from examples/inbound-parse-docker/Dockerfile rename to examples/webhooks-docker/Dockerfile diff --git a/examples/inbound-parse-docker/LICENSE b/examples/webhooks-docker/LICENSE similarity index 100% rename from examples/inbound-parse-docker/LICENSE rename to examples/webhooks-docker/LICENSE diff --git a/examples/inbound-parse-docker/README.md b/examples/webhooks-docker/README.md similarity index 100% rename from examples/inbound-parse-docker/README.md rename to examples/webhooks-docker/README.md diff --git a/examples/inbound-parse-docker/app.js b/examples/webhooks-docker/app.js similarity index 100% rename from examples/inbound-parse-docker/app.js rename to examples/webhooks-docker/app.js diff --git a/examples/inbound-parse-docker/docker-compose.debug.yml b/examples/webhooks-docker/docker-compose.debug.yml similarity index 100% rename from examples/inbound-parse-docker/docker-compose.debug.yml rename to examples/webhooks-docker/docker-compose.debug.yml diff --git a/examples/inbound-parse-docker/docker-compose.yml b/examples/webhooks-docker/docker-compose.yml similarity index 100% rename from examples/inbound-parse-docker/docker-compose.yml rename to examples/webhooks-docker/docker-compose.yml diff --git a/examples/inbound-parse-docker/example-email-parse-payload.txt b/examples/webhooks-docker/example-email-parse-payload.txt similarity index 100% rename from examples/inbound-parse-docker/example-email-parse-payload.txt rename to examples/webhooks-docker/example-email-parse-payload.txt diff --git a/examples/inbound-parse-docker/example-event-notification.txt b/examples/webhooks-docker/example-event-notification.txt similarity index 100% rename from examples/inbound-parse-docker/example-event-notification.txt rename to examples/webhooks-docker/example-event-notification.txt diff --git a/examples/inbound-parse-docker/k8s/inbound-parse.yml b/examples/webhooks-docker/k8s/inbound-parse.yml similarity index 100% rename from examples/inbound-parse-docker/k8s/inbound-parse.yml rename to examples/webhooks-docker/k8s/inbound-parse.yml diff --git a/examples/inbound-parse-docker/package-lock.json b/examples/webhooks-docker/package-lock.json similarity index 100% rename from examples/inbound-parse-docker/package-lock.json rename to examples/webhooks-docker/package-lock.json diff --git a/examples/inbound-parse-docker/package.json b/examples/webhooks-docker/package.json similarity index 100% rename from examples/inbound-parse-docker/package.json rename to examples/webhooks-docker/package.json diff --git a/examples/inbound-parse-docker/routes/events.js b/examples/webhooks-docker/routes/events.js similarity index 100% rename from examples/inbound-parse-docker/routes/events.js rename to examples/webhooks-docker/routes/events.js diff --git a/examples/inbound-parse-docker/routes/inbound-parse.js b/examples/webhooks-docker/routes/inbound-parse.js similarity index 100% rename from examples/inbound-parse-docker/routes/inbound-parse.js rename to examples/webhooks-docker/routes/inbound-parse.js From 35b073c7475a8d7a1a3d797af616ad00109c3a0f Mon Sep 17 00:00:00 2001 From: Ashley Roach Date: Mon, 29 Oct 2018 10:15:41 -0600 Subject: [PATCH 3/3] Fix logging of fields --- examples/webhooks-docker/routes/inbound-parse.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/webhooks-docker/routes/inbound-parse.js b/examples/webhooks-docker/routes/inbound-parse.js index 56298bd08..075a2dd99 100644 --- a/examples/webhooks-docker/routes/inbound-parse.js +++ b/examples/webhooks-docker/routes/inbound-parse.js @@ -18,9 +18,8 @@ router.post('/', (req, res) => { console.log('HEADERS: ' + req.fields.headers) console.log() console.log('DKIM: ' + req.fields.dkim) - // TODO: The server is sending a non JS compliant key name - // console.log() - // console.log('CONTENT-IDS: ' + req.fields.content-ids) + console.log() + console.log('CONTENT-IDS: ' + req.fields["content-ids"]) console.log() console.log('TO: ' + req.fields.to) console.log() @@ -37,9 +36,8 @@ router.post('/', (req, res) => { console.log('ATTACHMENTS: ' + req.fields.attachments) console.log() console.log('SPAM-SCORE: ' + req.fields.spam_score) - // TODO: The server is sending a non JS compliant key name - // console.log() - // console.log('ATTACHMENT-INFO: ' + req.fields.attachment-info) + console.log() + console.log('ATTACHMENT-INFO: ' + req.fields["attachment-info"]) console.log() console.log('CHARSETS: ' + req.fields.charsets) console.log()