Skip to content

Commit 66516c3

Browse files
committed
Merge pull request #7 from mintuz/express
ExpressJS action
2 parents 82ed900 + cf0b9c9 commit 66516c3

File tree

7 files changed

+230
-19
lines changed

7 files changed

+230
-19
lines changed

Diff for: README.md

+83-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# BB8 Commander
2-
A Node CLI Tool for Sphero BB8 Robot.
2+
A Node CLI Tool for Sphero BB8 Robot using the [Sphero Javascript SDK](http://sdk.sphero.com/community-apis/javascript-sdk/)
33

44
![BB8 Rolling like he's owning](http://i.imgur.com/00sZIf3.gif)
55

@@ -20,6 +20,88 @@ Not yet on npm so you'll have to do it the good'ol fasioned way with a cheeky gi
2020
* `node index.js disco` - Command to turn your BB8 Unit into a shining disco ball in the night
2121
* `node index.js weather --city="manchester" --country="uk" --api-key="ABCD"` - Command to turn your BB8 Unit into your very own weather reporter, uses OpenWeather so be sure to get your own API key
2222
* `node index.js tweet --hash-tag="bb8" --delay=5000` - Command to search twitter and run the first hashtag it finds as a command. Eg a tweet "#disco #bb8" would run the `disco` command --consumer-key xxx --consumer-secret xxx --access-token-key xxx --access-token-secret xxx
23+
* `node index.js express --port=4000` - Command to run an express server which has a single POST endpoint which you can send a JSON object to. See below for more details.
24+
25+
### Express Server
26+
27+
Having the ability to run an Express server to issue commands to the BB8 unit opens up a bunch of possibilities. One of the main benefits of having an Express server is that you can integrate into [IFTTT](https://ifttt.com/) and at that point, you have entered the Internet of things.
28+
29+
To get started is really easy, all you need to do is run `node index.js express --port=4000` adn once your BB8 is connected, an Express server will be started.
30+
31+
You can then send commands directly to it via a POST request. It supports any SpheroSDK command as well as custom commands we have created. See below for some examples.
32+
33+
### Native Commands
34+
35+
With native commands, the response body will include information the BB8 exposes once that command has been executed. Read the Sphero documentation on what data it returns. http://sdk.sphero.com/community-apis/javascript-sdk/
36+
37+
#### Running the `color` command
38+
39+
Post Request - localhost:3000/
40+
41+
Request Body
42+
43+
```
44+
{
45+
"mode":"sphero",
46+
"command":"color",
47+
"value": "yellow"
48+
}
49+
```
50+
51+
#### Running the `roll` command
52+
53+
Post Request - localhost:3000/
54+
55+
Request Body
56+
57+
```
58+
{
59+
"mode":"sphero",
60+
"command":"roll",
61+
"value": [130, 50]
62+
}
63+
```
64+
65+
With this request, we are passing an array and that's because the roll command in Sphero SDK requires multiple parameters. This is just a simple way to pass those values to that command.
66+
67+
### Custom Commands
68+
69+
#### Running the `disco` command
70+
71+
Post Request - localhost:3000/
72+
73+
Request Body
74+
75+
```
76+
{
77+
"mode":"custom",
78+
"command":"disco"
79+
}
80+
```
81+
82+
#### Running the `tweet` command
83+
84+
POST Request - localhost:3000/
85+
86+
Request Body
87+
88+
```
89+
{
90+
"mode":"custom",
91+
"command":"tweet",
92+
"value": {
93+
"delay": 30,
94+
"consumerKey": "YOUR_CONSUMER_KEY",
95+
"consumerSecret": "YOUR_CONSUMER_SECRET",
96+
"accessTokenKey": "YOUR_ACCESS_TOKEN_KEY",
97+
"accessTokenSecret": "YOUR_ACCESS_TOKEN_SECRET"
98+
}
99+
}
100+
```
101+
102+
Obviously you wouldn’t pass your OAuth information like this (BB8 Commander supports environment variables for secure data) but the important thing to note here is, anything that can be passed to the CLI tool can also be passed into the express server endpoint.
103+
104+
A suite difference between native commands and custom commands is that native commands that require multiple parameters will be passed as an array whilst custom commands will be objects. The reason for this is custom commands are key value pairs due to them sharing the same code as the CLI tool.
23105

24106
# Contributors
25107
* [@mintuz](http://twitter.com/mintuz)

Diff for: commands/express.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
var bb8 = require('../libs/bb8-instance')(),
2+
config = require('../libs/bb8-instance').config,
3+
expressInstance = require('../libs/express'),
4+
executeCustomCommand = require('../libs/execute-command'),
5+
_ = require('lodash');
6+
7+
var callbackFactory = function(res){
8+
return function(err, data){
9+
if(!err) {
10+
res.send({data: data});
11+
} else {
12+
res.send({error: err});
13+
}
14+
};
15+
};
16+
17+
var spheroCommandExecuter = function(bb8, requestBody, res) {
18+
19+
if(_.isString(requestBody.value)) {
20+
21+
bb8[requestBody.action](requestBody.value, callbackFactory(res));
22+
23+
} else if(_.isArray(requestBody.value)) {
24+
25+
requestBody.value.push(callbackFactory(res));
26+
27+
bb8[requestBody.action].apply(this, requestBody.value);
28+
29+
} else {
30+
31+
bb8[requestBody.action](callbackFactory(res));
32+
33+
}
34+
35+
};
36+
37+
var customCommandExecuter = function(bb8, requestBody, res){
38+
39+
if(_.isString(requestBody.value) || _.isObject(requestBody.value)) {
40+
41+
executeCustomCommand.alreadyConnectedSingleValue(bb8, requestBody.action, requestBody.value);
42+
43+
} else if(_.isArray(requestBody.value)) {
44+
45+
executeCustomCommand.alreadyConnectedMultipleValues(bb8, requestBody.action, requestBody.value);
46+
47+
} else {
48+
49+
executeCustomCommand.alreadyConnectedSingleValue(bb8, requestBody.action, {});
50+
51+
}
52+
53+
res.send('Command Executed - ' + requestBody.action);
54+
55+
};
56+
57+
module.exports = function(bb8, options) {
58+
59+
expressInstance(function (req, res) {
60+
61+
var requestBody = req.body;
62+
63+
if(requestBody.action && requestBody.mode === 'sphero') {
64+
65+
spheroCommandExecuter(bb8, req.body, res);
66+
67+
} else if(requestBody.action && requestBody.mode === 'custom') {
68+
69+
customCommandExecuter(bb8, req.body, res);
70+
71+
} else {
72+
73+
res.send('Command is invalid');
74+
75+
}
76+
77+
}, options);
78+
};

Diff for: commands/tweet.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function getLatestStatus(tweets) {
2222
}
2323

2424
var executeTwitterCommand = function (bb8, options) {
25-
25+
2626
var twitter = TwitterClient(options),
2727
hashTag = options.hashTag || 'bb8code';
2828

Diff for: index.js

+16-17
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
var program = require('commander');
2-
var packageFile = require('./package.json');
3-
var bb8 = require('./libs/bb8-instance')();
4-
var config = require('./libs/bb8-instance').config;
5-
6-
var executeCommand = function (command, options) {
7-
if (bb8) {
8-
bb8.connect(function () {
9-
require(command)(bb8, options)
10-
});
11-
}
12-
};
1+
var program = require('commander'),
2+
packageFile = require('./package.json'),
3+
executeCommand = require('./libs/execute-command');
134

145
program.version(packageFile.version);
156

@@ -33,7 +24,7 @@ program
3324
.command('disco')
3425
.description('Command to make your BB8 Unit A disco ball')
3526
.action(function () {
36-
executeCommand('./commands/disco');
27+
executeCommand('disco');
3728
});
3829

3930
program
@@ -43,20 +34,20 @@ program
4334
.option('-cc, --country <country>', 'Country name such as uk')
4435
.option('-t, --access-token <accessToken>', 'API Key')
4536
.action(function(options) {
46-
executeCommand('./commands/weather', options);
37+
executeCommand('weather', options);
4738
});
4839

4940
program
5041
.command('github')
5142
.description('Command to get notifications of new issues and PRs')
5243
.option('-t, --access-token <accessToken>', 'API Key')
53-
.action(require('./commands/github'));
44+
.action(require('github'));
5445

5546
program
5647
.command('roll')
5748
.description('BB8 will roll!')
5849
.action(function () {
59-
executeCommand('./commands/roll');
50+
executeCommand('roll');
6051
});
6152

6253

@@ -70,9 +61,17 @@ program
7061
.option('--access-token-key <accessTokenKey>', 'Twitter api access token key')
7162
.option('--access-token-secret <accessTokenSecret>', 'Twitter api access token secret')
7263
.action(function (options) {
73-
executeCommand('./commands/tweet', options)
64+
executeCommand('tweet', options)
7465
});
7566

67+
program
68+
.command('express')
69+
.description('Command to setup express server')
70+
.option('-p, --port <port>', 'Port to run express on. Defaults to 3000')
71+
.action(function (options) {
72+
executeCommand('express', options);
73+
});
74+
7675
try {
7776
program.parse(process.argv);
7877
} catch (e) {

Diff for: libs/execute-command.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
var bb8 = require('./bb8-instance')(),
2+
appRootPath = require('app-root-path'),
3+
_ = require('lodash');
4+
5+
module.exports = function (command, options) {
6+
if (bb8) {
7+
bb8.connect(function () {
8+
require(appRootPath + '/commands/' + command)(bb8, options);
9+
});
10+
}
11+
};
12+
13+
module.exports.alreadyConnected = function(bb8, command) {
14+
if (bb8) {
15+
require(appRootPath + '/commands/' + command)(bb8);
16+
}
17+
}
18+
19+
module.exports.alreadyConnectedSingleValue = function(bb8, command, options) {
20+
if (bb8) {
21+
require(appRootPath + '/commands/' + command)(bb8, options);
22+
}
23+
};
24+
25+
module.exports.alreadyConnectedMultipleValues = function(bb8, command, options) {
26+
27+
if (bb8) {
28+
var parameters = _.union([bb8], options);
29+
require(appRootPath + '/commands/' + command).apply(this, parameters);
30+
}
31+
32+
};

Diff for: libs/express.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
var express = require('express'),
2+
app = express(),
3+
bodyParser = require('body-parser');
4+
5+
module.exports = function(callback, options) {
6+
7+
var port = options.port || 3000;
8+
9+
app.use(bodyParser.json());
10+
11+
app.post('/', callback);
12+
13+
app.listen(port, function () {
14+
console.log( 'Server listening on port ' + port );
15+
});
16+
17+
}

Diff for: package.json

+3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
},
2020
"homepage": "https://github.com/mintuz/bb8-commander#readme",
2121
"dependencies": {
22+
"app-root-path": "^1.0.0",
23+
"body-parser": "^1.14.2",
2224
"commander": "^2.9.0",
25+
"express": "^4.13.4",
2326
"github": "^0.2.4",
2427
"home-config": "^0.1.0",
2528
"lodash": "^4.0.0",

0 commit comments

Comments
 (0)