Click here to Skip to main content
15,880,956 members
Articles / Programming Languages / Javascript

Introducing FitJS, an AJAX library for Fitbit

Rate me:
Please Sign up or sign in to vote.
4.91/5 (3 votes)
4 Nov 2013CPOL8 min read 15.7K   6  
Introducing FitJS, an AJAX library to develop Fitbit app

Introduction  

Google Code: https://code.google.com/p/fitjs/ 

Fitbit is an awesome device to track daily activities, sleep and etc. However, the website itself provides limited applications to users other than displaying data and some basic diagrams. Third-party developers like you can seize this opportunity to develop awesome apps for this new market by providing application related to gamification or motivation.  

 Fitbit provides RESTful APIs to access users' data. The benefits is that you can develop apps on a variety of platforms without downloading anything. The downside is that you will need to know write a lot of tedious code to call the APIs.   

 FitJS is an AJAX library that wrap around Fitbit's RESTful APIs. You can directly call Javascript functions to request tokens, accessing token or even create pop-ups to redirect users to authorize your access.

 FitJS is completely open-source under Apache License 2.0. You can help develop the library at:

 https://code.google.com/p/fitjs/ 

 The 1.0 version now supports only the OAuth Authorization functionalities. However, accessing resources is on the way in the next update. Your help with the library with be greatly appreciated.  

Using the code 

Prerequisite 

Using the library 

Downloading and placing the files 

1. go to https://code.google.com/p/fitjs/ and download the ZIP file on Google Drive

2. Unzip this file to your website folder

3.  include fitjs.js in your web page     

JavaScript
 <script src="fitjs/fitjs.js"></script>  

4. Make sure your server runs on PHP. If not, you may want to make following changes:

  • Open "fitjs.js"
  • Find FitJS_OAuth() method. Change following code 
C++
this.url={
   ........
    verifier:"fitjs/oauthverifier.php",
    signature:'fitjs/oauthsignature.php',
    proxy:"fitjs/proxy.php"
}; 

to reflect your choice of web language such as ASP JSP etc.

5. Replace those files in FitJS folder with your files that accomplish the same functionalities.

"oauthverifier.php" returns the verifier returned by Fitbit after users authorize the access. Note that Fitbit will call a URL you provided once users authorize your access to their data. The URL should write the verifier and token returned by this call to your database. "oauthverifier.php" merely pulls these two variables from your database and print it in following format:

JavaScript
verifier=XXX&token=XXX  

"oauthsignature.php" signs a base string with with your consumer secret by using HMAC-SHA1 method. If you wish to use other hash methods, please make sure your constructor of the FitJS Object will reflect that.  

"proxy.php" is a proxy for XMLHttpRequest to avoid cross-domain call restrictions by most browsers. Javascript function will first send specific requests to this file and this file then call Fitbit APIs and return the response. The file uses a POST method to intake 1) the header Fitbit required for that request 2) the body request for that request 3) the method such as POST or GET for that particular request to Fitbit. You can read the source code to understand better what it does.  

Using the JS methods: 

0. Basics of FitJS OAuth 

This following diagram demonstrates the FitJS OAuth process. 

1. Initializing FitJS 

JavaScript
foauth=new FitJS_OAuth("http://example.com/oauthverifier.php",  //callback URL for OAuth verifier
                                "999999999999999999999999", //consumer key provided by Fitbit
                                "HMAC-SHA1" // hash method. FitJS 1.0 only supports HMAC-SHA1.
                                );  

2. Requesting token    

var baseString=foauth.oauthBaseString("request_token"); // create base string of the signature
    var signature=foauth.oauthSignatureString(baseString); // generate signature string with HMAC-SHA1
    foauth.requestToken(signature, true, readyStateChange);   // request token  
    // second parameter means whether it is an asynchronous call
    // third parameter is a call back function for handling state changes on the XMLHttpRequest 

Please note that "readyStategChange" is a callback function with a standard XMLHttpRequest as an argument. To check whether you receive a valid response you may want to do:

function readyStateChange(xmlhttp)
{
    if (xmlhttp.readyState===4 && xmlhttp.status===200)
    {
        //receive temporary token from Fitbit API successfully
    }
    else
    {
        // error handling
    }
}  

3. Redirecting users to Fitbit.com for authorization 

After you received a valid token from Fitbit.com you should then redirect your users to Fitbit.com for their authorizations on your access to data. In the example below, the redirection is sent out only when token is received. Therefore, the code is placed in "readyStateChange" function (in the last step) 

 function readyStategChange(xmlhttp)
{
    if (xmlhttp.readyState===4 && xmlhttp.status===200)
    {
        foauth.authorize(true, "en_US", false, 800, 500);
       // first parameter means whether you want the redirection to be done in the main window or a popup. If you choose to use Popup, you may want to ensure the browser has not blocked pop-up first
      // second parameter is the locale of the window. For a list of locales Fitbit support, you can check out https://wiki.fitbit.com/display/API/API+Localization
      // third parameter means whether the page is for a mobile device
      // fourth and fifth parameters are the width and height of the pop-up respectively if you choose to redirect the user via a pop-up
        foauth.checkOAuthVerifier(2000, 10000, onTimeOut, onFinished, onFailed);
       // First parameter means how frequently (in milliseconds) should the webpage talk to the server to figure out whether users has authorized the access. Please implement the code in "oauthverifier.php" located in the "FitJS" folder to look up your database and return with format specified in the php file
       // Second parameter means timeout in milliseconds (if the server does not respond within this threshold, the connection will be shut down. 
       // the last three parameters are the functions that handles different events
    }
} 

In the example above, you can see the constant checking is initiated once the pop-up is generated. The checking will be stopped once it detects "oauthverifier" has already returned verifier after user authorize the access.

onTimeOut, onFinished and onFailed are all callback functions accepting one standard XMLHttpRequest argument. In step 5, you can see how onFinished is implemented 

4. Accessing token 

JavaScript
 function onFinished()
{
    var basestring=foauth.oauthBaseString("access_token");
    // generate the base string for access token request 
    var signature=foauth.oauthSignatureString(basestring);  
    // generate signatur string for the access token request 
    foauth.accessToken(signature, true, onAccessTokenStateChange);
    // second parameter means whether it is an asynchronous call
    // third parameter is a call back function for handling state changes on the XMLHttpRequest
}


function onAccessTokenStateChange(xmlhttp)
{
        if (xmlhttp.readyState===4 && xmlhttp.status===200)
    {
        alert("token:"+foauth.oauth_token+" token secret:"+foauth.oauth_token_secret+" user id: "+foauth.oauth_token_secret);    
    }
} 

API Reference 

For the latest API reference you may want to read: https://code.google.com/p/fitjs/wiki/API_Reference 

Before start, you may want to check out http://tools.ietf.org/html/draft-hammer-oauth-10 to understand OAuth protocol 1.0 to understand how Fitbit authorizes your app to access to users' data.

Member Functions

Constructor

FitJS_OAuth(callbackUrl, consumerKey, hashMethod)

Parameters:

Return: A initialized copy of Fitbit instance
callbackUrlan URL for Fitbit API to callback once the user authorize the access to his/her data. The URL should match what's on record unless no record left on Fitbit.com. This URL should write the token and verifier returned by Fitbit to database
consumerKeythe consumer key string provided by Fitbit
hashMethodFitJS currently ONLY ACCEPTS HMAC-SHA1. However, HMAC-SHA1, RSA-SHA1, PLAINTEXT will be supported in the future

Example: 

JavaScript
 foauth=new FitJS_OAuth("http://example.com/oauthcomplete.php",  //callback url
                                "7c799999999999e8a149499999", //consumer key
                                "HMAC-SHA1" //hash method
                                ); 

Signing a request

An OAuth request usually involves several headers. But the complex parts are 1) assembling a request base string 2) signing it. 3) assembling a request header

2) needs your secret. For security reasons, it is highly commended to not store your OAuth secret in the javascript. For this sake, you should store your Fitbit OAuth secret in "oauthsignature.php".

For more information about signing OAuth request, please see:

http://tools.ietf.org/html/draft-hammer-oauth-10#section-3.4

Generating a base string

oauthBaseString(stage);

This function will generate a base string for signing based on the type of request.

Parameters:

stageThis is an Enum variable with two possible values: "request_token" and "access_token".

Return: The function will return a base string for generating signature string based on the type of request provided.

Example:

JavaScript
var baseString=foauth.oauthBaseString("request_token");
var basestring=foauth.oauthBaseString("access_token"); 

oauthSignatureString (baseString)

This function signs the base string by using HMAC-SHA1. Currently, HMAC-SHA1 is the only method allowed in the 1.0 version of FitJS.

Parameters:

baseStringOauth request base string to generate signature. This string is generated by oauthBaseString() function

Return: A signature string by using HMAC-SHA1

Example:

JavaScript
var signature=foauth.oauthSignatureString(baseString);  

Requesting a temporary token

requestToken (signature, async, onreadyStateChange)

Parameters:

signaturethe signature string based on this request's base string
asyncwhether this request is asynchronous
onreadyStateChange callback function for ready state change event. Only if the request is asynchronous, this function will called.

Return: If the request is asynchronous, this function does not have return. If the function is synchronous, the return is a standard XMLHttpRequest

Example: 

JavaScript
 foauth.requestToken(signature, true, readyStategChange);  

Authorizing Access

Through the OAuth authorization process, user has to give your app the permission to access his/her data on Fitbit server. Thus, your app needs to either redirect the user to or use a pop-up window to allow the user access to fitbit.com/authorize.

authorize(usePopUp, locale, mobile, popupWidth, popupHeight)

This function allows both pop-up and redirect, although using pop-up is highly recommended to preserve data in your javascript.

Parameters:

usePopUpwhether the access to fitbit.com is through a pop-up or redirect
localethe locale of your pop-up
mobile whether the user's access to fitbit.com is on a mobile device
popupWidththe width of your pop-up
popupHeight the heigh of your pop-up

Return: None

Example:

JavaScript
 foauth.authorize(true, "en_US", false, 800, 500); 

checkOAuthVerifier(interval, timeout, onTimedOut, onFinished, onFailed)

This function sends requests to "oauthverifier.php" to check whether your website as acquired OAuth verifier from fitbit.com (this occurs only after user has authorized the access). Thus, the prerequisite is to implement a callback URL that allows fitbit.com to send verifier and token and "oauthverifier.php", which pulls data from your database where the verifier and token are stored.

Note that "oauthverifier.php" MUST RETURN VERIFIER AND TOKEN IN FOLLOWING FORMAT:

"verifier=XXX&token=XXX"

Parameters:

intervalfrequency to check on "oauthverifier.php" in milliseconds
timeoutthe threshold to timeout of a single request in milliseconds
onTimedOutcallback function if it does timeout (return XMLHttpRequest)
onFinishedcallback function when finish (return XMLHttpRequest)
onFailedcallback function when error occurs (return XMLHttpRequest)

Return:

None

Example: 

JavaScript
 foauth.checkOAuthVerifier(2000, 10000, onTimeOut, onFinished, onFailed); 

stopCheckingOAuthVerifier()

checkOAuthVerifier() will automatically stop sending requests if it acquires verifier and token from the "oauthverifier". However, should you want to stop the checking manually under certain circumstances, you can call this function.

Parameters:

None

Return: None

Example:

JavaScript
  stopCheckingOAuthVerifier(); 

Accessing a token

accessToken(signature, async, onreadyStateChange)

The last step in the OAuth process is to request and receives token credentials from Fitbit. The return includes token, token secret and the user's user-id. With these credentials, your app can then access user's data.

Parameters:

signaturesignature string generated by "oauthSignatureString()"
asyncwhether this request is asynchronous
onreadyStateChange if the request is asynchronous, the callback function to receive read state change event. The argument will be a standard XMLHttpRequest

Return: If the request is synchronous, the function returns a standard XMLHttpRequest; if not, it does not return anything.

Example:

foauth.accessToken(signature, true, onAccessTokenFinished);

function onAccessTokenFinished(xmlhttp)
{
        if (xmlhttp.readyState===4 && xmlhttp.status===200)
    {
        alert("token:"+foauth.oauth_token+" token secret:"+foauth.oauth_token_secret+" user id: "+foauth.encoded_user_id);    
    }
} 

Member Variables 

JavaScript
    url={
        request_token:"http://api.fitbit.com/oauth/request_token",
        access_token:"http://api.fitbit.com/oauth/access_token",        
        authorize:"https://www.fitbit.com/oauth/authenticate",
        verifier:"fitjs/oauthverifier.php",
        signature:'fitjs/oauthsignature.php',
        proxy:"fitjs/proxy.php"

URLs that FitJS internally uses to complete different parts of the OAuth process.

JavaScript
 callbackUrl 

Callback URL provided when constructing the FitJS_OAuth object.

 consumerKey 

Consumer key provide when constructing the FitJS_OAuth object.

JavaScript
 hashMethod 

Hash method provided when constructing the FitJS_OAuth object. Currently, it uses supports HMAC-SHA1.

verifier 

Verifier received from "oauthverifier.php" once user authorizes the access to his/her data and redirect Fitbit.com to the callback URL, that stores the verifier in the database. 

Token 

Temporary token received from Fitbit.com. 

 callbackConfirmed 

Whether the callback URL is confirmed by Fitbit.com when requesting a token.

JavaScript
 request_token_timestamp 

Timestamp string when request token. This string will change every time when base string function is called to create base string for requesting a token.

JavaScript
  request_token_nonce 

Random string when request token. This string will change every time when base string function is called to create base string for requesting a token.

JavaScript
 access_token_timestamp 

Timestamp string when access token. This string will change every time when base string function is called to create base string for accessing a token.

JavaScript
 access_token_nonce 

Random string when access token. This string will change every time when base string function is called to create base string for accessing a token.

Java
 oauth_token_secret 

OAuth token secret received from Fitbit after accessToken() is called successfully.

JavaScript
 encoded_user_id 

User id received from Fitbit after accessToken() is called successfully. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer Horizon Ideas
United States United States
My name is Jia Chen and I want you tell you about my childhood dream: being a problem-solver. My mom told me it was silly because it wasn't really a profession. Through the last decade, I have been a software engineer, a product manager, a repetitive student, a management consult and an entrepreneur. They appear far from my childhood dream. But I still think I am living it. Because the essence of it is to find problems and solve problems. Some times I may not solve new problems, but I always want to solve old problems in a new way.

Comments and Discussions

 
-- There are no messages in this forum --