├── .gitignore ├── LICENSE ├── Procfile ├── README.md ├── example └── test.js ├── lib └── fitbit_client.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | .DS_Store 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Simon Murtha Smith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node example/test.js $CONSUMER_KEY $CONSUMER_SECRET 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fitbit-js 2 | 3 | Simple FitBit API client for express 3. 4 | 5 | ``` bash 6 | npm install fitbit-js 7 | ``` 8 | 9 | ## Usage 10 | 11 | fitbit-js has two methods: 12 | 13 | ```javascript 14 | getAccessToken(req, res, callback) // Uses oAuth module to get the access_token 15 | apiCall(http_method, path, params, callback) // Does a call to the FitBit API. 16 | ``` 17 | 18 | `params` must contain the token. 19 | 20 | ## Test 21 | 22 | [Register an app with fitbit](https://dev.fitbit.com/apps/new) specifying a 23 | callback URL of `http://localhost:8553`. 24 | 25 | ```bash 26 | npm install 27 | cd example 28 | node test.js [Consumer Key] [Consumer Secret] [Unit System (en_US or en_GB)](optional. Defaults to metric units) 29 | ``` 30 | 31 | open [http://localhost:8553](http://localhost:8553) 32 | -------------------------------------------------------------------------------- /example/test.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var cookieParser = require('cookie-parser'); 3 | 4 | var app = express(); 5 | app.use(cookieParser('sess')); 6 | 7 | var PORT = process.argv[5] || 8553; 8 | 9 | var fitbitClient = require('../')(process.argv[2], process.argv[3], 10 | 'http://localhost:' + PORT, process.argv[4]); 11 | 12 | var token; 13 | app.get('/', function (req, res) { 14 | fitbitClient.getAccessToken(req, res, function (error, newToken) { 15 | if(newToken) { 16 | token = newToken; 17 | res.writeHead(200, {'Content-Type':'text/html'}); 18 | res.end('Now get stuff'); 19 | } 20 | }); 21 | }); 22 | 23 | app.get('/getStuff', function (req, res) { 24 | fitbitClient.apiCall('GET', '/user/-/profile.json', 25 | {token: {oauth_token_secret: token.oauth_token_secret, 26 | oauth_token: token.oauth_token}}, 27 | function(err, resp, json) { 28 | if (err) return res.send(err, 500); 29 | res.json(json); 30 | }); 31 | }); 32 | 33 | app.get('/cookie', function(req, res) { 34 | res.send('wahoo!'); 35 | }); 36 | 37 | 38 | app.listen(PORT); 39 | console.log('listening at http://localhost:' + PORT + '/'); 40 | -------------------------------------------------------------------------------- /lib/fitbit_client.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fitbit-js 3 | */ 4 | 5 | var url = require('url'); 6 | var OAuth = require('oauth').OAuth; 7 | var querystring = require('querystring'); 8 | var Serializer = require('serializer'); 9 | 10 | var baseURI = 'https://api.fitbit.com/1'; 11 | 12 | module.exports = function (api_key, api_secret, callbackURI, unit_system) { 13 | var client = { 14 | version: '0.3.1' 15 | }; 16 | var serializer = Serializer.createSecureSerializer(api_key, api_secret); 17 | var headers = { 18 | Accept: '*/*', 19 | Connection: 'close', 20 | 'User-Agent': 'fitbit-js ' + client.version 21 | }; 22 | 23 | if (typeof unit_system !== 'undefined' && unit_system !== null) { 24 | headers['Accept-Language'] = unit_system; 25 | } 26 | 27 | var oAuth = new OAuth('https://api.fitbit.com/oauth/request_token', 28 | 'https://api.fitbit.com/oauth/access_token', 29 | api_key, api_secret, '1.0', callbackURI, 30 | 'HMAC-SHA1', null, headers); 31 | 32 | function requestCallback(callback) { 33 | return function (err, data, response) { 34 | if (err) return callback(err, data); 35 | var exception = null; 36 | try { 37 | data = JSON.parse(data); 38 | } catch (e) { 39 | exception = e; 40 | } 41 | callback(exception, response, data); 42 | }; 43 | } 44 | 45 | function get(path, params, token, callback) { 46 | oAuth.get(baseURI + path + '?' + querystring.stringify(params), 47 | token.oauth_token, 48 | token.oauth_token_secret, 49 | requestCallback(callback)); 50 | } 51 | 52 | function post(path, params, token, callback) { 53 | oAuth.post(baseURI + path, 54 | token.oauth_token, 55 | token.oauth_token_secret, 56 | params, 57 | null, 58 | requestCallback(callback)); 59 | } 60 | 61 | function oAuthDelete(path, params, token, callback){ 62 | oAuth.delete(baseURI + path, 63 | token.oauth_token, 64 | token.oauth_token_secret, 65 | requestCallback(callback)); 66 | } 67 | 68 | // PUBLIC 69 | client.apiCall = function (method, path, params, callback) { 70 | var token = params.token; 71 | delete params.token; 72 | if (method === 'GET') get(path, params, token, callback); 73 | else if (method === 'POST') post(path, params, token, callback); 74 | else if (method === 'DELETE') oAuthDelete(path, params, token, callback); 75 | }; 76 | 77 | client.getAccessToken = function (req, res, callback) { 78 | var sess; 79 | if (req.cookies && req.cookies.fitbit_client) { 80 | try { 81 | sess = serializer.parse(req.cookies.fitbit_client); 82 | } catch(E) { } 83 | } 84 | 85 | var qs = url.parse(req.url, true).query; 86 | 87 | var has_token = qs && qs.oauth_token, 88 | has_secret = sess && sess.token_secret; 89 | 90 | if (has_token && has_secret) { // Access token 91 | oAuth.getOAuthAccessToken(qs.oauth_token, 92 | sess.token_secret, 93 | qs.oauth_verifier, 94 | function (error, oauth_token, oauth_token_secret) { 95 | if (error) return callback(error, null); 96 | 97 | callback(null, { 98 | oauth_token: oauth_token, 99 | oauth_token_secret: oauth_token_secret 100 | }); 101 | }); 102 | } else { // Request token 103 | oAuth.getOAuthRequestToken({oauth_callback: callbackURI}, 104 | function (error, oauth_token, oauth_token_secret) { 105 | if (error) return callback(error, null); 106 | 107 | // stash the secret 108 | res.cookie('fitbit_client', 109 | serializer.stringify({ 110 | token_secret: oauth_token_secret 111 | }), 112 | { 113 | path: '/', 114 | httpOnly: false 115 | } 116 | ); 117 | 118 | res.redirect('https://www.fitbit.com/oauth/authorize?oauth_token=' + 119 | oauth_token); 120 | }); 121 | } 122 | }; 123 | 124 | return client; 125 | }; 126 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fitbit-js", 3 | "description": "Simple FitBit API client", 4 | "version": "0.3.2", 5 | "author": "Simon Murtha Smith ", 6 | "keywords": ["fitbit"], 7 | "main" : "lib/fitbit_client.js", 8 | "directories" : { 9 | "lib" : "./lib" 10 | }, 11 | "dependencies": { 12 | "oauth": ">= 0.8.2", 13 | "serializer": ">=0.0.2 <0.1.0" 14 | }, 15 | "devDependencies": { 16 | "cookie-parser": "^1.3.5", 17 | "express":">= 4.0.0" 18 | }, 19 | "repository" : { 20 | "type": "git" , 21 | "url": "http://github.com/smurthas/fitbit-js.git" 22 | }, 23 | "engines": { 24 | "node": ">=0.8.0 <6.0.0" 25 | } 26 | } 27 | --------------------------------------------------------------------------------