Skip to content

Commit 4e6d8c5

Browse files
committed
adding fitbit API
1 parent 09364b6 commit 4e6d8c5

4 files changed

Lines changed: 214 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ ScribeJava support out-of-box several HTTP clients:
4848
* Доктор на работе (https://www.doktornarabote.ru/)
4949
* Etsy (https://www.etsy.com/)
5050
* Facebook (https://www.facebook.com/)
51+
* Fitbit (https://www.fitbit.com/)
5152
* Flickr (https://www.flickr.com/)
5253
* Foursquare (https://foursquare.com/)
5354
* Frappe (https://github.com/frappe/frappe)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.github.scribejava.apis;
2+
3+
import com.github.scribejava.apis.service.Fitbit20ServiceImpl;
4+
import com.github.scribejava.core.builder.api.DefaultApi20;
5+
import com.github.scribejava.core.model.OAuthConfig;
6+
import com.github.scribejava.core.oauth.OAuth20Service;
7+
8+
9+
/**
10+
* Fitbit's OAuth2 client's implementation
11+
* source: https://dev.fitbit.com/docs/oauth2/
12+
*
13+
* Note - this is an updated version of this library for Scribe v5.3.0. Original code here:
14+
* - https://github.com/alexthered/fitbitAPI20-scribe-java
15+
*/
16+
public class FitbitApi20 extends DefaultApi20 {
17+
18+
protected FitbitApi20() {
19+
}
20+
21+
private static class InstanceHolder {
22+
private static final FitbitApi20 INSTANCE = new FitbitApi20();
23+
}
24+
25+
public static FitbitApi20 instance() {
26+
return InstanceHolder.INSTANCE;
27+
}
28+
29+
@Override
30+
public String getAccessTokenEndpoint() {
31+
return "https://api.fitbit.com/oauth2/token";
32+
}
33+
34+
@Override
35+
protected String getAuthorizationBaseUrl() {
36+
return "https://www.fitbit.com/oauth2/authorize";
37+
}
38+
39+
@Override
40+
public OAuth20Service createService(OAuthConfig config) {
41+
return new Fitbit20ServiceImpl(this, config);
42+
}
43+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.github.scribejava.apis.service;
2+
3+
import com.github.scribejava.core.builder.api.DefaultApi20;
4+
import com.github.scribejava.core.java8.Base64;
5+
import com.github.scribejava.core.model.OAuthConfig;
6+
import com.github.scribejava.core.model.OAuthConstants;
7+
import com.github.scribejava.core.model.OAuthRequest;
8+
import com.github.scribejava.core.oauth.OAuth20Service;
9+
10+
import java.nio.charset.Charset;
11+
12+
/**
13+
* Created by hd on 10/09/16.
14+
*
15+
* Note - this is an updated version of this library for Scribe v5.3.0. Original code here:
16+
* - https://github.com/alexthered/fitbitAPI20-scribe-java
17+
*/
18+
public class Fitbit20ServiceImpl extends OAuth20Service {
19+
20+
public Fitbit20ServiceImpl(DefaultApi20 api, OAuthConfig config) {
21+
super(api, config);
22+
}
23+
24+
/**
25+
* ref: https://dev.fitbit.com/docs/oauth2/#access-token-request
26+
* @param code
27+
* @param request
28+
* @param <T>
29+
* @return
30+
*/
31+
@Override
32+
protected OAuthRequest createAccessTokenRequest(String code)
33+
{
34+
final DefaultApi20 api = getApi();
35+
final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
36+
final OAuthConfig config = getConfig();
37+
request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
38+
request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
39+
request.addParameter(OAuthConstants.CODE, code);
40+
request.addParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
41+
String scope = config.getScope();
42+
if (scope != null) {
43+
request.addParameter(OAuthConstants.SCOPE, scope);
44+
}
45+
46+
//this is non-OAuth2 standard, but Fitbit requires it
47+
request.addHeader("Authorization", "Basic " + getKeyBytesForFitbitAuth());
48+
49+
request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.AUTHORIZATION_CODE);
50+
return request;
51+
}
52+
53+
/**
54+
* ref: https://dev.fitbit.com/docs/oauth2/#refreshing-tokens
55+
* @param refreshToken
56+
* @param request
57+
* @param <T>
58+
* @return
59+
*/
60+
@Override
61+
protected OAuthRequest createRefreshTokenRequest(String refreshToken)
62+
{
63+
if (refreshToken != null && !refreshToken.isEmpty()) {
64+
final DefaultApi20 api = getApi();
65+
final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
66+
final OAuthConfig config = this.getConfig();
67+
request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
68+
request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
69+
request.addParameter(OAuthConstants.REFRESH_TOKEN, refreshToken);
70+
request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.REFRESH_TOKEN);
71+
72+
//this is non-OAuth2 standard, but Fitbit requires it
73+
request.addHeader("Authorization", "Basic " + getKeyBytesForFitbitAuth());
74+
75+
return request;
76+
} else {
77+
throw new IllegalArgumentException("The refreshToken cannot be null or empty");
78+
}
79+
}
80+
81+
/**
82+
*/
83+
private String getKeyBytesForFitbitAuth()
84+
{
85+
final OAuthConfig config = getConfig();
86+
String keyAndSecret = String.format("%s:%s", new Object[] {config.getApiKey(), config.getApiSecret()});
87+
byte[] keyBytes = Base64.getEncoder().encode(keyAndSecret.getBytes(Charset.forName("UTF-8")));
88+
89+
return new String(keyBytes);
90+
}
91+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.github.scribejava.apis.examples;
2+
import java.util.Scanner;
3+
4+
import com.github.scribejava.apis.FitbitApi20;
5+
import com.github.scribejava.core.builder.ServiceBuilder;
6+
import com.github.scribejava.core.model.OAuth2AccessToken;
7+
import com.github.scribejava.core.model.OAuthRequest;
8+
import com.github.scribejava.core.model.Response;
9+
import com.github.scribejava.core.model.Verb;
10+
import com.github.scribejava.core.oauth.OAuth20Service;
11+
12+
/**
13+
* Created by hd on 10/09/16.
14+
*/
15+
public class FitbitApi20Example {
16+
17+
private static final String NETWORK_NAME = "Fitbit";
18+
19+
// Replace with user ID to test API against
20+
private static final String USER_ID = "your user id";
21+
private static final String PROTECTED_RESOURCE_URL = "https://api.fitbit.com/1/user/" + USER_ID + "/profile.json";
22+
23+
24+
private FitbitApi20Example() {
25+
}
26+
27+
public static void main(String... args) throws Exception {
28+
29+
// Replace these with your client id and secret fron your app
30+
final String clientId = "your client id";
31+
final String clientSecret = "your client secret";
32+
final OAuth20Service service = new ServiceBuilder(clientId)
33+
.apiSecret(clientSecret)
34+
.scope("activity profile") // replace with desired scope
35+
.callback("http://www.example.com/oauth_callback/") //your callback URL to store and handle the authorization code sent by Fitbit
36+
.state("some_params")
37+
.build(FitbitApi20.instance());
38+
final Scanner in = new Scanner(System.in);
39+
40+
System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
41+
System.out.println();
42+
43+
// Obtain the Authorization URL
44+
System.out.println("Fetching the Authorization URL...");
45+
final String authorizationUrl = service.getAuthorizationUrl();
46+
System.out.println("Got the Authorization URL!");
47+
System.out.println("Now go and authorize ScribeJava here:");
48+
System.out.println(authorizationUrl);
49+
System.out.println("And paste the authorization code here");
50+
System.out.print(">>");
51+
final String code = in.nextLine();
52+
System.out.println();
53+
54+
// Trade the Request Token and Verfier for the Access Token
55+
System.out.println("Trading the Request Token for an Access Token...");
56+
final OAuth2AccessToken accessToken = service.getAccessToken(code);
57+
System.out.println("Got the Access Token!");
58+
System.out.println("(if your curious it looks like this: " + accessToken
59+
+ ", 'rawResponse'='" + accessToken.getRawResponse() + "')");
60+
System.out.println();
61+
62+
// Now let's go and ask for a protected resource!
63+
// This will get the profile for this user
64+
System.out.println("Now we're going to access a protected resource...");
65+
66+
final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL);
67+
request.addHeader("x-li-format", "json");
68+
69+
//add header for authentication (why make it so complicated, Fitbit?)
70+
request.addHeader("Authorization", "Bearer " + accessToken.getAccessToken());
71+
72+
final Response response = service.execute(request);
73+
System.out.println();
74+
System.out.println(response.getCode());
75+
System.out.println(response.getBody());
76+
77+
System.out.println();
78+
}
79+
}

0 commit comments

Comments
 (0)