diff --git a/.gitignore b/.gitignore index 21243cd7ef8..ff904281765 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ npm-debug.log coverage/ test/encrypted/nodejs-docs-samples.json -dump.rdb \ No newline at end of file +dump.rdb +logs/ +*.iml +.idea/ \ No newline at end of file diff --git a/README.md b/README.md index 7436411c390..a888b12c9a8 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ and applications on [Google App Engine](http://cloud.google.com/nodejs). - Bower - [Source code][bower_1] | [App Engine Tutorial][bower_2] | [Documentation][bower_3] - Grunt - [Source code][grunt_1] | [App Engine Tutorial][grunt_2] | [Live demo][grunt_3] | [Documentation][grunt_4] - Mailgun - [Source code][mailgun_1] | [App Engine Tutorial][mailgun_2] | [Documentation][mailgun_3] +- Sendgrid - [Source code][sendgrid_1] | [App Engine Tutorial][sendgrid_2] | [Documentation][sendgrid_3] - Webpack - [Source code][webpack_1] | [App Engine Tutorial][webpack_2] | [Documentation][webpack_3] ## Google Storage @@ -134,6 +135,10 @@ See [LICENSE](https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/ma [mailgun_2]: https://cloud.google.com/nodejs/resources/tools/mailgun [mailgun_3]: http://www.mailgun.com/ +[sendgrid_1]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/master/appengine/sendgrid +[sendgrid_2]: https://cloud.google.com/nodejs/resources/tools/sendgrid +[sendgrid_3]: http://sendgrid.com/ + [webpack_1]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/master/appengine/webpack [webpack_2]: https://cloud.google.com/nodejs/resources/tools/webpack [webpack_3]: https://webpack.github.io/ diff --git a/appengine/sendgrid/README.md b/appengine/sendgrid/README.md new file mode 100644 index 00000000000..6f05352763b --- /dev/null +++ b/appengine/sendgrid/README.md @@ -0,0 +1,20 @@ +## Express.js + Sendgrid on Google App Engine + +> [Sendgrid][1]: Delivering your transactional and marketing email through one reliable platform. +> +> – sendgrid.com + +This sample application demonstrates how to use [Express.js][2] and +[sendgrid-nodejs][3] to send transactional email on [Google App Engine][4]. + +Read the [Sendgrid on App Engine Tutorial][5] for how to run and deploy this +sample app. + +You can also read the [Sendgrid documentation][6]. + +[1]: https://sendgrid.com/ +[2]: http://expressjs.com +[3]: https://github.com/sendgrid/sendgrid-nodejs +[4]: https://cloud.google.com/appengine +[5]: https://cloud.google.com/nodejs/resources/tools/sendgrid +[6]: https://sendgrid.com/docs diff --git a/appengine/sendgrid/app.js b/appengine/sendgrid/app.js new file mode 100644 index 00000000000..656737bfd19 --- /dev/null +++ b/appengine/sendgrid/app.js @@ -0,0 +1,93 @@ +// Copyright 2015, Google, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var express = require('express'); +var path = require('path'); +var bodyParser = require('body-parser'); + +// [START setup] +var Sendgrid = require('sendgrid')(process.env.SENDGRID_API_KEY); +// [END setup] + +var app = express(); + +// Setup view engine +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'jade'); + +// Parse form data +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); + +// [START index] +app.get('/', function(req, res) { + res.render('index'); +}); +// [END index] + +// [START hello] +app.post('/hello', function(req, res, next) { + Sendgrid.send({ + from: 'no-reply@appengine-sendgrid-demo.com', // From address + to: req.body.email, // To address + subject: 'Hello World!', // Subject + text: 'Sendgrid on Google App Engine with Node.js' // Content + }, function (err) { + if (err) { + return next(err); + } else { + // Render the index route on success + return res.render('index', { + sent: true + }); + } + }); +}); +// [END hello] + +if (module === require.main) { + // [START server] + var server = app.listen( + process.env.PORT || 8080, + '0.0.0.0', + function () { + var address = server.address().address; + var port = server.address().port; + console.log('App listening at http://%s:%s', address, port); + console.log('Press Ctrl+C to quit.'); + } + ); + // [END server] +} else { + exports.app = app; + exports.send = function () { + // [START send] + Sendgrid.send({ + from: 'ANOTHER_EMAIL@ANOTHER_EXAMPLE.COM', // From address + to: 'EMAIL@EXAMPLE.COM', // To address + subject: 'test email from Node.js on a Compute Engine VM', // Subject + text: 'Hello!\n\nThis a test email from Node.js on a VM.' // Content + }, function (err, json) { + if (err) { + console.error(err); + } else { + console.log(json); + } + }); + // [END send] + }; +} + + diff --git a/appengine/sendgrid/app.yaml b/appengine/sendgrid/app.yaml new file mode 100644 index 00000000000..b67a0dc2c01 --- /dev/null +++ b/appengine/sendgrid/app.yaml @@ -0,0 +1,21 @@ +# Copyright 2015, Google, Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# [START app_yaml] +runtime: nodejs +vm: true +env_variables: + SENDGRID_API_KEY: +# [END app_yaml] +skip_files: + - ^(.*/)?.*/node_modules/.*$ diff --git a/appengine/sendgrid/package.json b/appengine/sendgrid/package.json new file mode 100644 index 00000000000..6439b81ecc5 --- /dev/null +++ b/appengine/sendgrid/package.json @@ -0,0 +1,20 @@ +{ + "name": "appengine-sendgrid", + "description": "An example of using Sendgrid in Node.js on Google App Engine.", + "version": "0.0.1", + "private": true, + "license": "Apache Version 2.0", + "engines": { + "node": "~4.2" + }, + "scripts": { + "start": "node app.js", + "deploy": "gcloud preview app deploy app.yaml" + }, + "dependencies": { + "body-parser": "^1.14.1", + "express": "^4.13.3", + "jade": "^1.11.0", + "sendgrid": "^2.0.0" + } +} diff --git a/appengine/sendgrid/views/index.jade b/appengine/sendgrid/views/index.jade new file mode 100644 index 00000000000..bfa6d827121 --- /dev/null +++ b/appengine/sendgrid/views/index.jade @@ -0,0 +1,27 @@ +// Copyright 2015, Google, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +doctype html +html + head + title= title + body + h1 Hello World! + p Express.js + Sendgrid on Google App Engine. + hr + if sent + p Email sent! + else + form(name="hello", action="/hello", method="post") + input(type="email", placeholder="Enter your email to send yourself a Hello World message", name="email", style="width: 50%; margin-right: 15px;") + input(type="submit", value="Send") diff --git a/package.json b/package.json index b0115493a14..381a97518f1 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,10 @@ "deps_datastore": "cd datastore && npm i && cd ../..", "deps_storage": "cd storage && npm i && cd ../..", "deps_express": "cd appengine/express && npm i && cd ../..", + "deps_sendgrid": "cd appengine/sendgrid && npm i && cd ../..", "deps_memcached": "cd appengine/express-memcached-session && npm i && cd ../..", "pretest_geddy": "cd appengine/geddy && npm i geddy; GEDDY_SECRET=config/secrets.json; [[ -f $GEDDY_SECRET ]] || echo '{}' > $GEDDY_SECRET && node node_modules/.bin/geddy gen secret; cd ../..;", - "pretest": "npm run deps_datastore && npm run deps_storage && npm run deps_memcached && npm run deps_express && npm run pretest_geddy", + "pretest": "npm run deps_datastore && npm run deps_storage && npm run deps_memcached && npm run deps_express && npm run deps_sendgrid && npm run pretest_geddy", "test": "npm run jshint && npm run cover" }, "devDependencies": { @@ -39,6 +40,7 @@ "istanbul": "^0.4.0", "jshint": "~2.8.0", "mocha": "^2.2.5", + "proxyquire": "^1.7.3", "request": "^2.65.0", "supertest": "^1.1.0" } diff --git a/test/appengine/all.test.js b/test/appengine/all.test.js index 11d4119a960..182f7566707 100644 --- a/test/appengine/all.test.js +++ b/test/appengine/all.test.js @@ -99,6 +99,12 @@ var sampleTests = [ args: ['server.js'], msg: 'Hello World! Restify.js on Google App Engine.' }, + { + dir: 'sendgrid', + cmd: 'node', + args: ['app.js'], + msg: 'Express.js + Sendgrid on Google App Engine.' + }, { dir: 'webpack', cmd: 'node', diff --git a/test/appengine/sendgrid.test.js b/test/appengine/sendgrid.test.js new file mode 100644 index 00000000000..3d13f73b3ed --- /dev/null +++ b/test/appengine/sendgrid.test.js @@ -0,0 +1,51 @@ +// Copyright 2015, Google, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var assert = require('assert'); +var request = require('supertest'); +var proxyquire = require('proxyquire').noPreserveCache(); + +describe('sendgrid', function () { + it('should return 200 and a "Hello World" message', function (done) { + var app = require('../../appengine/sendgrid/app.js'); + var message = 'Express.js + Sendgrid on Google App Engine'; + + request(app.app) + .get('/') + .expect(200) + .expect(function (res) { + assert( + res.text.indexOf(message) !== -1, + 'Response should contain a "Hello World" message.\n' + + 'Found: ' + res.text + ); + }) + .end(done); + }); + it('should send a message', function () { + var app = proxyquire('../../appengine/sendgrid/app', { + sendgrid: function () { + return { + send: function (options, cb) { + cb(null, true); + } + }; + } + }); + app.send({}, function (err, result) { + assert.ok(result); + }); + }); +});