├── .env.example ├── .gitignore ├── Procfile ├── README.md ├── app.js ├── app.json ├── click-to-cloud.json ├── package.json ├── readme ├── inbound1.png ├── inbound2.png └── inbound3.png ├── routes ├── home.js ├── inbound.js └── index.js └── sendgrid-parse-api-example.png /.env.example: -------------------------------------------------------------------------------- 1 | SENDGRID_USERNAME=yourusername 2 | SENDGRID_PASSWORD=yourpassword 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env* 3 | !.env.example 4 | config.json 5 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node app.js 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sendgrid-parse-api-example 2 | 3 | ![](https://raw.githubusercontent.com/sendgrid/sendgrid-parse-api-example/master/sendgrid-parse-api-example.png) 4 | 5 | Example application using the SendGrid Parse API. 6 | 7 | This application demonstrates how to use SendGrid's Parse API. Additionally, it acts as a boilerplate of code that you can adjust to your own needs. It comes with complete instructions for getting the SendGrid Parse API working. 8 | 9 | ## Getting Started 10 | 11 | You will need [an account on SendGrid](https://sendgrid.com/user/signup). 12 | 13 | ### Production 14 | 15 | #### 1. Deploy to Heroku 16 | 17 | Click this button to deploy to Heroku. 18 | 19 | [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) 20 | 21 | #### 2. Check for 200 OK 22 | 23 | Then you should be able to run the following - receiving a success 200 response. 24 | 25 | ``` 26 | $ curl -I -X POST http://your-heroku-subdomain.herokuapp.com/inbound 27 | ``` 28 | 29 | #### 3. Set SendGrid Parse Settings 30 | 31 | Next, setup your [SendGrid Parsing Incoming Emails setting](http://sendgrid.com/developer/reply) like the following but with a hostname of your own and the url you deployed this app to. (You'll notice I actually made my hostname a subdomain `m.carve.io`. You can do the same or the more standard root of your domain.) 32 | 33 | ![](https://raw.github.com/sendgrid/sendgrid-parse-api-example/master/readme/inbound1.png) 34 | 35 | #### 4. Configure Your MX Records 36 | 37 | Now you have to configure an MX record on the hostname you set above. It should look something like the following. 38 | 39 | ![](https://raw.github.com/sendgrid/sendgrid-parse-api-example/master/readme/inbound2.png) 40 | 41 | Now wait a couple hours to 48 hours. (It can take up to 48 hours for MX records to propagate around the world.) 42 | 43 | #### 5. Send an Email 44 | 45 | Send an email to `inbound@the-hostname-you-setup.com` and this app will now parse it. 46 | 47 | It will deliver an email back to you with an attachment containing the content of the webhook data. The contents will look something [like this](https://gist.github.com/scottmotte/6642578/raw/d66d703abdd45addec9e8ff7aa92214db7dda326/gistfile1.txt). 48 | 49 | #### 6. Adjust the code 50 | 51 | You can now adjust the code in [routes/inbound.js](https://github.com/sendgrid/sendgrid-parse-api-example/blob/master/routes/inbound.js) to do whatever logic you require. 52 | 53 | ### Development 54 | 55 | #### 1. Set ENV vars 56 | 57 | ``` 58 | $ mv .env.example .env 59 | ``` 60 | 61 | Change the contents of .env to your username and password. 62 | 63 | ``` 64 | SENDGRID_USERNAME=your_sendgrid_username 65 | SENDGRID_PASSWORD=your_sendgrid_password 66 | ``` 67 | 68 | #### 2. Run App 69 | 70 | ``` 71 | $ npm install 72 | $ node app.js 73 | ``` 74 | 75 | #### 3. Setup ngrok 76 | 77 | Detailed [install instructions here](https://ngrok.com/). 78 | 79 | ``` 80 | $ wget https://dl.ngrok.com/darwin_amd64/ngrok.zip 81 | $ unzip ngrok.zip -d /usr/local/bin 82 | $ ngrok 3000 83 | ``` 84 | 85 | Note the url the `ngrok` command gives you. 86 | 87 | #### 4. Set SendGrid Parse Settings 88 | 89 | Next, setup your [SendGrid Parsing Incoming Emails setting](http://sendgrid.com/developer/reply) like the following but with a hostname of your own and the url granted to you from the `ngrok` command above plus the /inbound path. 90 | 91 | ![](https://raw.github.com/sendgrid/sendgrid-parse-api-example/master/readme/inbound3.png) 92 | 93 | #### 5. Configure Your MX Records 94 | 95 | Now you have to configure an MX record on the hostname you set above. It should look something like the following. 96 | 97 | ![](https://raw.github.com/sendgrid/sendgrid-parse-api-example/master/readme/inbound2.png) 98 | 99 | Wait 1-48 hours. (It can take up to 48 hours for MX records to propagate around the world.) 100 | 101 | #### 6. Send an Email 102 | 103 | Send an email to `inbound@the-hostname-you-setup.com` and this app will now parse it. 104 | 105 | It will deliver an email back to you with an attachment containing the content of the webhook data. The contents will look something [like this](https://gist.github.com/scottmotte/6642578/raw/d66d703abdd45addec9e8ff7aa92214db7dda326/gistfile1.txt). 106 | 107 | 108 | 109 | ## Alternatives 110 | 111 | If you just need a quick way to inspect the payload contents of the Parse API webhook, I recommend using one of the following. You'll still have to setup your MX records. 112 | 113 | * [RequestBin](http://requestb.in/) 114 | * [HookDebug](hookdebug.sendgrid.com) 115 | 116 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var dotenv = require('dotenv')(); 2 | dotenv.load(); 3 | 4 | var e = module.exports; 5 | e.ENV = process.env.NODE_ENV || 'development'; 6 | 7 | var sendgrid_username = process.env.SENDGRID_USERNAME; 8 | var sendgrid_password = process.env.SENDGRID_PASSWORD; 9 | sendgrid = require('sendgrid')(sendgrid_username, sendgrid_password); 10 | 11 | var port = parseInt(process.env.PORT) || 3000; 12 | var Hapi = require('hapi'); 13 | server = new Hapi.Server(+port, '0.0.0.0', { cors: true }); 14 | 15 | require('./routes'); 16 | 17 | server.start(function() { 18 | console.log('Server started at: ' + server.info.uri); 19 | }); 20 | 21 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sendgrid-parse-api-example", 3 | "description": "Example application using the SendGrid Parse API.", 4 | "keywords": [ 5 | "sendgrid", 6 | "sendgridparse", 7 | "inbound", 8 | "email", 9 | "parse" 10 | ], 11 | "website": "https://github.com/sendgrid/sendgrid-parse-api-example", 12 | "repository": "https://github.com/sendgrid/sendgrid-parse-api-example", 13 | "logo": "https://raw.githubusercontent.com/sendgrid/sendgrid-parse-api-example/master/sendgrid-parse-api-example.png", 14 | "env": { 15 | "SENDGRID_USERNAME": { 16 | "description": "Your SendGrid username.", 17 | "required": true 18 | }, 19 | "SENDGRID_PASSWORD": { 20 | "description": "Your SendGrid password.", 21 | "required": true 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /click-to-cloud.json: -------------------------------------------------------------------------------- 1 | { 2 | "heroku": [ 3 | "heroku create", 4 | "heroku addons:add sendgrid", 5 | "git push heroku master" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sendgrid-parse-api-example", 3 | "version": "0.0.1", 4 | "engines": { 5 | "node": "0.10.x", 6 | "npm": "1.2.x" 7 | }, 8 | "main": "app.js", 9 | "description": "Example application using the SendGrid Parse API.", 10 | "dependencies": { 11 | "dotenv": "0.0.3", 12 | "hapi": "1.6.2", 13 | "request": "2.21.0", 14 | "sendgrid": "0.3.0-rc.1.8" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /readme/inbound1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sendgrid/sendgrid-parse-api-example/fdf5f8e9336befc26a159547a01f4333d4aa09e5/readme/inbound1.png -------------------------------------------------------------------------------- /readme/inbound2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sendgrid/sendgrid-parse-api-example/fdf5f8e9336befc26a159547a01f4333d4aa09e5/readme/inbound2.png -------------------------------------------------------------------------------- /readme/inbound3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sendgrid/sendgrid-parse-api-example/fdf5f8e9336befc26a159547a01f4333d4aa09e5/readme/inbound3.png -------------------------------------------------------------------------------- /routes/home.js: -------------------------------------------------------------------------------- 1 | var home = { 2 | handler: function (request) { 3 | request.reply({ success: true, message: 'You are using sendgrid-parse-api-example. See README for instructions.' }); 4 | } 5 | }; 6 | 7 | server.addRoute({ 8 | method : 'GET', 9 | path : '/', 10 | config : home 11 | }); 12 | -------------------------------------------------------------------------------- /routes/inbound.js: -------------------------------------------------------------------------------- 1 | var inbound = { 2 | handler: function (request) { 3 | var envelope; 4 | var to; 5 | var payload = request.payload; 6 | 7 | console.log(payload); 8 | 9 | if (payload.envelope) { envelope = JSON.parse(payload.envelope) }; 10 | if (envelope) { to = envelope.from; } 11 | 12 | var Email = sendgrid.Email; 13 | var email = new Email({ 14 | to: to, 15 | from: "hi@sendgrid-parse-api-example.com", 16 | subject: "[sendgrid-parse-api-example] Inbound Payload", 17 | text: "A payload was just delivered via SendGrid's Inbound Parse API. It should be attached." 18 | }); 19 | 20 | email.addFile({ 21 | filename: 'payload.txt', 22 | content: new Buffer(JSON.stringify(payload)) 23 | }); 24 | 25 | sendgrid.send(email, function(err, json) { 26 | if (err) { 27 | console.error(err); 28 | request.reply({ success: false, error: {message: err.message} }); 29 | } else { 30 | request.reply({ success: true }); 31 | } 32 | }); 33 | } 34 | }; 35 | 36 | server.addRoute({ 37 | method : 'POST', 38 | path : '/inbound', 39 | config : inbound 40 | }); 41 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | require('./home'); 2 | require('./inbound'); 3 | -------------------------------------------------------------------------------- /sendgrid-parse-api-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sendgrid/sendgrid-parse-api-example/fdf5f8e9336befc26a159547a01f4333d4aa09e5/sendgrid-parse-api-example.png --------------------------------------------------------------------------------