From b2c5b90af7ca580bd6e1c7e54c3943be5e41c401 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 26 Jan 2017 14:20:06 +0000 Subject: [PATCH 1/8] Remove README --- README.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index a288919b..00000000 --- a/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[![Ably](https://s3.amazonaws.com/files.ably.io/logo-with-type.png)](https://www.ably.io) - ---- - -# Tutorials repository - -This repository contains the working code for many of the [Ably tutorials](https://www.ably.io/tutorials). - -See [https://www.ably.io/tutorials](https://www.ably.io/tutorials) for a complete list of Ably tutorials. The source code for each tutorial exists as a branch in this repo, see [a complete list of branches in this repo](https://github.com/ably/tutorials/branches). - -To find out more Ably and our realtime data delivery platform, visit [https://www.ably.io](https://www.ably.io) From 16e78e453c6d83d727b27d739e4b6a67e24ceb4d Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Fri, 22 Jul 2016 02:27:15 +0100 Subject: [PATCH 2/8] Step 2 - Install Ably --- package.json | 16 ++++++++++++++++ server.js | 7 +++++++ 2 files changed, 23 insertions(+) create mode 100644 package.json create mode 100644 server.js diff --git a/package.json b/package.json new file mode 100644 index 00000000..23bb41ba --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "ably-tutorials", + "author": "Ably ", + "description": "Node.js Reactor Queue and Wolfram Alpha tutorial", + "repository": "https://github.com/ably/tutorials", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + }, + "scripts": { + "start": "node ./server.js" + }, + "dependencies": { + "ably": ">=0.9.0-beta" + } +} diff --git a/server.js b/server.js new file mode 100644 index 00000000..bfe6406c --- /dev/null +++ b/server.js @@ -0,0 +1,7 @@ +const Ably = require('ably'); + +const ApiKey = 'INSERT-YOUR-API-KEY-HERE'; /* Add your API key here */ +if (ApiKey.indexOf('INSERT') === 0) { throw('Cannot run without an API key. Add your key to server.js'); } + +/* Instance the Ably library */ +const rest = new Ably.Rest({ key: ApiKey }); From b21c89a1daff6499b57538749c40af32c24370f4 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 26 Jan 2017 15:16:38 +0000 Subject: [PATCH 3/8] Step 3 - Setup server & placeholder HTML app --- package.json | 3 +- public/app.js | 6 ++++ public/index.html | 23 +++++++++++++++ public/style.css | 74 +++++++++++++++++++++++++++++++++++++++++++++++ server.js | 11 +++++++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 public/app.js create mode 100644 public/index.html create mode 100644 public/style.css diff --git a/package.json b/package.json index 23bb41ba..9d4cafa2 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "start": "node ./server.js" }, "dependencies": { - "ably": ">=0.9.0-beta" + "ably": ">=0.9.0-beta", + "express": ">=4.14.0" } } diff --git a/public/app.js b/public/app.js new file mode 100644 index 00000000..9330e19b --- /dev/null +++ b/public/app.js @@ -0,0 +1,6 @@ +$(function() { + var $askButton = $('#ask-btn'); + $askButton.on('click', function() { + alert("Not yet implemented"); + }); +}); diff --git a/public/index.html b/public/index.html new file mode 100644 index 00000000..1bb44cfb --- /dev/null +++ b/public/index.html @@ -0,0 +1,23 @@ + + + Ably Reactor Queue and Wolfram Alpha demo + + + + + +

Wolfram Alpha

+
+

Questions

+ + +

+ Pressing this button will publish a message to a channel, which will in turn using an Ably Reactor Queue rule to republish the message into a queue. The node.js worker server will then consume this message in real time, send the question to Wolfram Alpha using its REST API, and publish the answer back to the client using an Ably channel. +

+
+
+

Answers

+
+
+ + diff --git a/public/style.css b/public/style.css new file mode 100644 index 00000000..542f9227 --- /dev/null +++ b/public/style.css @@ -0,0 +1,74 @@ +body { + font-family: Arial, Helvetica, sans-serif; + font-size: 0.85em; +} + +h2 { + font-size: 1.2em; +} + +.col { + width: 50%; + float: left; + box-sizing: border-box; + padding: 0 1em; +} + +textarea#question { + width: 100%; + height: 4em; + margin-bottom: 1em; +} + +img { + box-shadow: 0 0 0.5em #bbb; + margin-bottom: 1.5em; +} + +#status { + color: orange; + padding-left: 1em; +} + +button { + -moz-box-shadow: 0px 1px 0px 0px #fff6af; + -webkit-box-shadow: 0px 1px 0px 0px #fff6af; + box-shadow: 0px 1px 0px 0px #fff6af; + background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ffec64), color-stop(1, #ffab23)); + background:-moz-linear-gradient(top, #ffec64 5%, #ffab23 100%); + background:-webkit-linear-gradient(top, #ffec64 5%, #ffab23 100%); + background:-o-linear-gradient(top, #ffec64 5%, #ffab23 100%); + background:-ms-linear-gradient(top, #ffec64 5%, #ffab23 100%); + background:linear-gradient(to bottom, #ffec64 5%, #ffab23 100%); + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffec64', endColorstr='#ffab23',GradientType=0); + background-color:#ffec64; + -moz-border-radius:6px; + -webkit-border-radius:6px; + border-radius:6px; + border:1px solid #ffaa22; + display:inline-block; + cursor:pointer; + color:#333333; + font-family:Arial; + font-size:15px; + font-weight:bold; + padding:6px 24px; + text-decoration:none; + text-shadow:0px 1px 0px #ffee66; +} + +button:hover { + background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ffab23), color-stop(1, #ffec64)); + background:-moz-linear-gradient(top, #ffab23 5%, #ffec64 100%); + background:-webkit-linear-gradient(top, #ffab23 5%, #ffec64 100%); + background:-o-linear-gradient(top, #ffab23 5%, #ffec64 100%); + background:-ms-linear-gradient(top, #ffab23 5%, #ffec64 100%); + background:linear-gradient(to bottom, #ffab23 5%, #ffec64 100%); + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffab23', endColorstr='#ffec64',GradientType=0); + background-color:#ffab23; +} + +button:active { + position:relative; + top:1px; +} diff --git a/server.js b/server.js index bfe6406c..0797e259 100644 --- a/server.js +++ b/server.js @@ -1,7 +1,18 @@ const Ably = require('ably'); +const Express = require('express'); +const ServerPort = 3000; const ApiKey = 'INSERT-YOUR-API-KEY-HERE'; /* Add your API key here */ if (ApiKey.indexOf('INSERT') === 0) { throw('Cannot run without an API key. Add your key to server.js'); } /* Instance the Ably library */ const rest = new Ably.Rest({ key: ApiKey }); + +/* Start a web server */ +const app = Express(); + +/* Server static HTML files from /public folder */ +app.use(Express.static('public')); +app.listen(3000); + +console.log('Web server listening on port', ServerPort); From 7e067354f85126a927af41ccf948fed214722483 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 26 Jan 2017 15:37:53 +0000 Subject: [PATCH 4/8] Step 4 - Plug in Ably client-side, update UI, auth --- public/app.js | 47 +++++++++++++++++++++++++++++++++++++++++++++-- public/index.html | 3 ++- public/style.css | 22 +++++++++++++++++++++- server.js | 12 ++++++++++++ 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/public/app.js b/public/app.js index 9330e19b..5c906d7f 100644 --- a/public/app.js +++ b/public/app.js @@ -1,6 +1,49 @@ $(function() { - var $askButton = $('#ask-btn'); + /* Set up realtime library and authenticate using token issued from server */ + var ably = new Ably.Realtime({ authUrl: '/auth' }); + var answersChannel = ably.channels.get('wolfram:answers'); + var questionsChannel = ably.channels.get('wolfram:questions'); + + var $answers = $('#answers'), + $status = $('#status'), + $askButton = $('#ask-btn'), + $question = $('#question'); + + /* Subscribe to answers published on this channel */ + answersChannel.subscribe(function(message) { + var $question = $('
').text(message.data.question); + var $answer = $('
').text(message.data.answer); + var $stat = $('
').text("Wolfram took " + message.data.wolframTime + "ms"); + $answers.prepend($('
').append($stat).append($question).append($answer)); + }); + $askButton.on('click', function() { - alert("Not yet implemented"); + var question = $question.val(); + if (question.replace(' ') != '') { + /* Publish question to the Ably channel so that the queue worker receives it via queues */ + questionsChannel.publish('question', question, function(err) { + if (err) { + showStatus('Failed to publish question!'); + $question.val(question); + return; + } + clearStatus(); + }); + showStatus('Sending question...'); + $question.val(''); + } }); + + ably.connection.on('connecting', function() { showStatus('Connecting to Ably...'); }); + ably.connection.on('connected', function() { clearStatus(); }); + ably.connection.on('disconnected', function() { showStatus('Disconnected from Ably...'); }); + ably.connection.on('suspended', function() { showStatus('Disconnected from Ably for a while...'); }); + + function showStatus(text) { + $status.text(text).show(); + } + + function clearStatus() { + $status.fadeOut(750); + } }); diff --git a/public/index.html b/public/index.html index 1bb44cfb..e7e34210 100644 --- a/public/index.html +++ b/public/index.html @@ -3,6 +3,7 @@ Ably Reactor Queue and Wolfram Alpha demo + @@ -17,7 +18,7 @@

Questions

Answers

-
+
diff --git a/public/style.css b/public/style.css index 542f9227..af116c57 100644 --- a/public/style.css +++ b/public/style.css @@ -20,11 +20,31 @@ textarea#question { margin-bottom: 1em; } -img { +#answers > div { box-shadow: 0 0 0.5em #bbb; margin-bottom: 1.5em; } +#answers > div .question { + color: orange; + font-style: italic; + padding: 5px; + float: left; +} + +#answers > div .stat { + color: #999; + font-size: 0.8em; + float: right; + padding: 5px; +} + +#answers > div .answer { + font-weight: bold; + padding: 5px; + clear: both; +} + #status { color: orange; padding-left: 1em; diff --git a/server.js b/server.js index 0797e259..ff23d760 100644 --- a/server.js +++ b/server.js @@ -11,6 +11,18 @@ const rest = new Ably.Rest({ key: ApiKey }); /* Start a web server */ const app = Express(); +/* Issue token requests to browser clients sending a request to the /auth endpoint */ +app.get('/auth', function (req, res) { + rest.auth.createTokenRequest(function(err, tokenRequest) { + if (err) { + res.status(500).send('Error requesting token: ' + JSON.stringify(err)); + } else { + res.setHeader('Content-Type', 'application/json'); + res.send(JSON.stringify(tokenRequest)); + } + }); +}); + /* Server static HTML files from /public folder */ app.use(Express.static('public')); app.listen(3000); From 772c7502c4f0f105a1ebfff0cdb897f2b6b217ac Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 26 Jan 2017 16:30:23 +0000 Subject: [PATCH 5/8] Step 6 - Add queue worker --- package.json | 1 + server.js | 5 ++++- worker.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 worker.js diff --git a/package.json b/package.json index 9d4cafa2..bfb88ef4 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "ably": ">=0.9.0-beta", + "amqplib": "^0.4", "express": ">=4.14.0" } } diff --git a/server.js b/server.js index ff23d760..d0edf775 100644 --- a/server.js +++ b/server.js @@ -1,6 +1,7 @@ const Ably = require('ably'); const Express = require('express'); const ServerPort = 3000; +const worker = require('./worker'); const ApiKey = 'INSERT-YOUR-API-KEY-HERE'; /* Add your API key here */ if (ApiKey.indexOf('INSERT') === 0) { throw('Cannot run without an API key. Add your key to server.js'); } @@ -27,4 +28,6 @@ app.get('/auth', function (req, res) { app.use(Express.static('public')); app.listen(3000); -console.log('Web server listening on port', ServerPort); +worker.start(ApiKey, 'wolfram:answers', 'wolfram', 'us-east-1-a-queue.ably.io:5671/shared'); + +console.log('Open the Wolfram demo in your browser: https://localhost:' + ServerPort + '/'); diff --git a/worker.js b/worker.js new file mode 100644 index 00000000..c568ec45 --- /dev/null +++ b/worker.js @@ -0,0 +1,52 @@ +'use strict'; + +const amqp = require('amqplib/callback_api'); +const Ably = require('ably'); + +/* Start the worker that consumes from the AMQP QUEUE */ +exports.start = function(apiKey, answersChannelName, queueName, queueEndpoint) { + const appId = apiKey.split('.')[0]; + const queue = appId + ":" + queueName; + const endpoint = queueEndpoint; + const url = 'amqps://' + apiKey + '@' + endpoint; + const rest = new Ably.Rest({ key: apiKey }); + const answersChannel = rest.channels.get(answersChannelName); + + /* Connect to Ably queue */ + amqp.connect(url, (err, conn) => { + if (err) { + console.error('worker:', 'Queue error!', err); + return; + } + console.log('worker:', 'Connected to AMQP endpoint', endpoint); + + /* Create a communication channel */ + conn.createChannel((err, ch) => { + if (err) { + console.error('worker:', 'Queue error!', err); + return; + } + console.log('worker:', 'Waiting for messages'); + + /* Wait for messages published to the Ably Reactor queue */ + ch.consume(queue, (item) => { + const decodedEnvelope = JSON.parse(item.content); + + const messages = Ably.Realtime.Message.fromEncodedArray(decodedEnvelope.messages); + messages.forEach(function(message) { + console.log('worker:', 'Received question', message.data, ' - about to ask Wolfram'); + answersChannel.publish('answer', 'Placeholder until Wolfram connected', function(err) { + if (err) { + console.error('worker:', 'Failed to publish question', message.data, ' - err:', JSON.stringify(err)); + } + }) + }); + + /* Remove message from queue */ + ch.ack(item); + }); + }); + + conn.on('error', function(err) { console.error('worker:', 'Connection error!', err); }); + }); +}; From 404d37e6d406cb568c9c192edcfccd70a2d0dad1 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 26 Jan 2017 16:59:12 +0000 Subject: [PATCH 6/8] Step 7 - Connect the worker to Wolfram Alpha --- package.json | 3 ++- server.js | 7 +++++-- worker.js | 40 +++++++++++++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index bfb88ef4..e85c1219 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dependencies": { "ably": ">=0.9.0-beta", "amqplib": "^0.4", - "express": ">=4.14.0" + "express": ">=4.14.0", + "request": ">=2.79.0" } } diff --git a/server.js b/server.js index d0edf775..66262d25 100644 --- a/server.js +++ b/server.js @@ -4,7 +4,10 @@ const ServerPort = 3000; const worker = require('./worker'); const ApiKey = 'INSERT-YOUR-API-KEY-HERE'; /* Add your API key here */ -if (ApiKey.indexOf('INSERT') === 0) { throw('Cannot run without an API key. Add your key to server.js'); } +if (ApiKey.indexOf('INSERT') === 0) { throw('Cannot run without an Ably API key. Add your key to server.js'); } + +const WolframAppId = 'INSERT-YOUR-WOLFRAM-API-KEY-HERE'; /* Add your Wolfram AppID here */ +if (WolframAppId.indexOf('INSERT') === 0) { throw('Cannot run without a Wolfram API key. Add your key to server.js'); } /* Instance the Ably library */ const rest = new Ably.Rest({ key: ApiKey }); @@ -28,6 +31,6 @@ app.get('/auth', function (req, res) { app.use(Express.static('public')); app.listen(3000); -worker.start(ApiKey, 'wolfram:answers', 'wolfram', 'us-east-1-a-queue.ably.io:5671/shared'); +worker.start(ApiKey, WolframAppId, 'wolfram:answers', 'wolfram', 'us-east-1-a-queue.ably.io:5671/shared'); console.log('Open the Wolfram demo in your browser: https://localhost:' + ServerPort + '/'); diff --git a/worker.js b/worker.js index c568ec45..77fb8695 100644 --- a/worker.js +++ b/worker.js @@ -2,9 +2,38 @@ const amqp = require('amqplib/callback_api'); const Ably = require('ably'); +const request = require('request'); +const querystring = require("querystring"); +const WolframEndpoint = 'http://api.wolframalpha.com/v1/result'; + +/* Send question over HTTP to Wolfram to find the answer */ +function getAnswerAndPublish(ablyChannel, wolframUrl, question) { + console.log('worker:', 'Received question', question, ' - about to ask Wolfram'); + var timeNow = Date.now(); + request(wolframUrl, function (error, response, body) { + var timePassed = Date.now() - timeNow; + if (!error && response.statusCode == 200) { + publishAnswer(ablyChannel, question, body, timePassed) + } else { + if (body) { + publishAnswer(ablyChannel, question, "Wolfram couldn't compute: " + body, timePassed); + } else { + publishAnswer(ablyChannel, question, "Wolfram error: " + JSON.stringify(error), timePassed); + } + } + }); +} + +function publishAnswer(ablyChannel, question, answer, wolframTime) { + ablyChannel.publish('answer', { question: question, answer: answer, wolframTime: wolframTime }, function(err) { + if (err) { + console.error('worker:', 'Failed to publish question', question, ' - err:', JSON.stringify(err)); + } + }) +} /* Start the worker that consumes from the AMQP QUEUE */ -exports.start = function(apiKey, answersChannelName, queueName, queueEndpoint) { +exports.start = function(apiKey, wolframApiKey, answersChannelName, queueName, queueEndpoint) { const appId = apiKey.split('.')[0]; const queue = appId + ":" + queueName; const endpoint = queueEndpoint; @@ -34,12 +63,9 @@ exports.start = function(apiKey, answersChannelName, queueName, queueEndpoint) { const messages = Ably.Realtime.Message.fromEncodedArray(decodedEnvelope.messages); messages.forEach(function(message) { - console.log('worker:', 'Received question', message.data, ' - about to ask Wolfram'); - answersChannel.publish('answer', 'Placeholder until Wolfram connected', function(err) { - if (err) { - console.error('worker:', 'Failed to publish question', message.data, ' - err:', JSON.stringify(err)); - } - }) + var question = message.data; + var url = WolframEndpoint + '?' + querystring.stringify({ appid: wolframApiKey, i: question}); + getAnswerAndPublish(answersChannel, url, question); }); /* Remove message from queue */ From cadc080727057e145664dd9c807cca8f21dad610 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 26 Jan 2017 17:27:10 +0000 Subject: [PATCH 7/8] Deploy with Heroku button support --- LICENSE | 15 +++++++++++++++ Procfile | 1 + README.md | 38 ++++++++++++++++++++++++++++++++++++++ app.json | 13 +++++++++++++ server.js | 16 +++++++++++----- 5 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 LICENSE create mode 100644 Procfile create mode 100644 README.md create mode 100644 app.json diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..a127f3d2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +Copyright (c) 2017 Ably + +Copyright 2016 Ably Real-time Ltd + +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. diff --git a/Procfile b/Procfile new file mode 100644 index 00000000..489b2700 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: node server.js diff --git a/README.md b/README.md new file mode 100644 index 00000000..47769aef --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# [Ably](https://www.ably.io) Ably Reactor Queue and Wolfram Alpha demo + +Ably is a hugely scalable, superfast and secure hosted real-time messaging service for web-enabled devices. [Find out more about Ably](https://www.ably.io). + +This demo uses realtime pub/sub to publish questions and subscribe to answers, and uses the [Ably Reactor Queues](https://www.ably.io/reactor) to subscribe to realtime data from a worker server over AMQP. When the worker receives a question, it sends the request to Wolfram Alpha to get the answer, and publishes the answer on a channel so that the browser receives it. + +Want to try this demo now? Deploy to Heroku for free: + +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/ably/tutorials/tree/queue-wolfram-alpha-nodejs) + +# Setting up the demo on Heroku + +Once the app has been deployed to Heroku using the button above, there a few quick steps needed to get this demo running: + +* [Sign up for a free Developer AppId with Wolfram Alpha](http://developer.wolframalpha.com/) +* Configure an environment variable with the Wolfram AppId (replace `[your wolfram app id]` with the AppId from the previous step): `heroku config:set WOLFRAM_APP_ID=[your wolfram app id] --app [heroku app name you assigned for this demo]` +* Log in to your Ably dashboard `heroku addons:open ably --app [heroku app name you assigned for this demo]` +* Set up a queue (in the Queues tab) with the name `wolfram` in the `US East (Virgina)` area. +* Set up a queue rule (button to add rules is further down the page within the Queues tab) with the following: + * Queue - choose the `wolfram` queue you just set up + * Source - choose "Message" + * Channel Filter - enter `"^wolfram:questions"` to ensure that all questions published to the `wolfram:questions` channel are republished into the `wolfram` queue + +You are now ready to run the demo: `heroku open --app [heroku app name you assigned for this demo]` + +# Ably Reactor + +The Ably Reactor provides Queues to consume realtime data, Events to trigger server-side code or functions in respons to realtime data, and Firehose to stream events to other queue or streaming services. + +[Find out more about the Ably Reactor](https://www.ably.io/reactor) + +# Questions + +Please visit http://support.ably.io/ for access to our knowledgebase and to ask for any assistance. + +# License + +Copyright (c) 2017 Ably Real-time Ltd, Licensed under the Apache License, Version 2.0. Refer to [LICENSE](./LICENSE) for the license terms. diff --git a/app.json b/app.json new file mode 100644 index 00000000..32fd9cd8 --- /dev/null +++ b/app.json @@ -0,0 +1,13 @@ +{ + "name": "Ably Wolfram Queue demo", + "description": "A simple demo to demonstrate using Ably Reactor Queues with Wolfram Alpha", + "repository": "https://github.com/ably/tutorials/tree/queue-wolfram-alpha-nodejs", + "logo": "https://files.ably.io/logo-70x70.png", + "keywords": ["Ably", "AMQP", "Wolfram Alpha", "realtime"], + "success_url": "https://github.com/ably/tutorials/blob/queue-wolfram-alpha-nodejs/README.md#setting-up-the-demo-on-heroku", + "addons": [ + { + "plan": "ably:test" + } + ] +} diff --git a/server.js b/server.js index 66262d25..4f7fc781 100644 --- a/server.js +++ b/server.js @@ -1,13 +1,13 @@ const Ably = require('ably'); const Express = require('express'); -const ServerPort = 3000; +const ServerPort = process.env.PORT || 3000; const worker = require('./worker'); -const ApiKey = 'INSERT-YOUR-API-KEY-HERE'; /* Add your API key here */ +const ApiKey = process.env.ABLY_API_KEY || 'INSERT-YOUR-API-KEY-HERE'; /* Add your API key here */ if (ApiKey.indexOf('INSERT') === 0) { throw('Cannot run without an Ably API key. Add your key to server.js'); } -const WolframAppId = 'INSERT-YOUR-WOLFRAM-API-KEY-HERE'; /* Add your Wolfram AppID here */ -if (WolframAppId.indexOf('INSERT') === 0) { throw('Cannot run without a Wolfram API key. Add your key to server.js'); } +const WolframAppId = process.env.WOLFRAM_APP_ID || 'INSERT-YOUR-WOLFRAM-APP-ID-HERE'; /* Add your Wolfram AppID here */ +if (WolframAppId.indexOf('INSERT') === 0) { console.warn('Cannot run without a Wolfram AppID. Add your AppID to server.js'); } /* Instance the Ably library */ const rest = new Ably.Rest({ key: ApiKey }); @@ -27,9 +27,15 @@ app.get('/auth', function (req, res) { }); }); +if (WolframAppId.indexOf('INSERT') === 0) { + app.get('/', function (req, res) { + res.status(500).send('WolframAppId is not set. You need to configure an environment variable WOLFRAM_APP_ID'); + }); +} + /* Server static HTML files from /public folder */ app.use(Express.static('public')); -app.listen(3000); +app.listen(ServerPort); worker.start(ApiKey, WolframAppId, 'wolfram:answers', 'wolfram', 'us-east-1-a-queue.ably.io:5671/shared'); From c6873f0670c56416112fad6c96fd279de4c206aa Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 26 Jan 2017 17:39:33 +0000 Subject: [PATCH 8/8] Heroku post install instructions --- app.json | 2 +- public/post-install.html | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 public/post-install.html diff --git a/app.json b/app.json index 32fd9cd8..4731bebf 100644 --- a/app.json +++ b/app.json @@ -4,7 +4,7 @@ "repository": "https://github.com/ably/tutorials/tree/queue-wolfram-alpha-nodejs", "logo": "https://files.ably.io/logo-70x70.png", "keywords": ["Ably", "AMQP", "Wolfram Alpha", "realtime"], - "success_url": "https://github.com/ably/tutorials/blob/queue-wolfram-alpha-nodejs/README.md#setting-up-the-demo-on-heroku", + "success_url": "/post-install.html", "addons": [ { "plan": "ably:test" diff --git a/public/post-install.html b/public/post-install.html new file mode 100644 index 00000000..d000038b --- /dev/null +++ b/public/post-install.html @@ -0,0 +1,40 @@ + + + Ably Reactor Queue and Wolfram Alpha demo + + + + +

Finalizing the setup of this demo

+ +

Great, the app is now installed! However we need to you to follow few quick steps to get this demo running:

+ +
    +
  • Sign up for a free Developer AppId with Wolfram Alpha
  • +
  • Configure an environment variable with the Wolfram AppId (replace [your wolfram app id] with the AppId from the previous step): heroku config:set WOLFRAM_APP_ID=[your wolfram app id] --app [heroku app name you assigned for this demo]
  • +
  • Log in to your Ably dashboard: heroku addons:open ably --app [heroku app name you assigned for this demo]
  • +
  • Set up a queue (in the Queues tab) with the name wolfram in the US East (Virgina) area.
  • +
  • Set up a queue rule (button to add rules is further down the page within the Queues tab) with the following: + +
      +
    • Queue - choose the wolfram queue you just set up
    • +
    • Source - choose "Message"
    • +
    • Channel Filter - enter "^wolfram:questions" to ensure that all questions published to the wolfram:questions channel are published into the wolfram queue
    • +
    +
  • +
+ +

All done!

+ +

+ View the Reactor Queue and Wolfram Alpha Demo » +

+ + + +