Categorygithub.com/anyappinc/fitbit
modulepackage
0.0.3
Repository: https://github.com/anyappinc/fitbit.git
Documentation: pkg.go.dev

# README

fitbit - Fitbit API client written in go

fitbit package provides the client to communicate with Firbit Web API.

This implementation contains the structure to interact with Fitbit Web API, but only some APIs(endpoints) have been implemented right now.

For more details, see Implemented APIs section.

Installation

go get github.com/anyappinc/fitbit

Features

  • Obtaining tokens through a secure OAuth2 authentication process.
    • This package follows Authorization Code Grant Flow with Proof Key for Code Exchange (PKCE) defined by RFC 7636, which is Fitbit's recommended option.
  • The configurable client. You can specify the application type(Server/Client/Personal), locale, language, and scopes.
  • Auto-refreshing of an access token using a refresh token when needed.
    • And the hook function is configurable so that you can observe a token refreshing.
  • Easy access to the rate limit.

Implemented APIs

Debug Mode

When debug mode is on, the consent dialog appears every time when users try to authorize.

Client has functions below to change debug mode.

  • EnableDebugMode()
  • DisableDebugMode()

Example

package main

import (
  "context"
  "encoding/json"
  "io"
  "log"
  "net/http"
  "strconv"

  "github.com/anyappinc/fitbit"
)

const (
  clientID     = "xxxxxx"
  clientSecret = "******"
  redirectURI  = "http://localhost:8080/link"
)

var (
  fitbitClient *fitbit.Client
  state        string
  codeVerifier string
  userID       string
  token        *fitbit.Token
)

func updateTokenFunc(oldToken, newToken *fitbit.Token) error {
  log.Print("Token updated.")
  return nil
}

func init() {
  fitbitClient = fitbit.NewClient(clientID, clientSecret, fitbit.ServerApplication, &fitbit.Scope{
    Location: true,
    Profile:  true,
    Weight:   true,
  })
  fitbitClient.SetLocaleAndLanguage(fitbit.LocaleJapan)
  fitbitClient.SetUpdateTokenFunc(updateTokenFunc)
  fitbitClient.EnableDebugMode()
}

func main() {
  http.HandleFunc("/authorize", func(w http.ResponseWriter, req *http.Request) {
    authCodeURL, _state, _codeVerifier := fitbitClient.AuthCodeURL(redirectURI)
    state = _state
    codeVerifier = _codeVerifier
    http.Redirect(w, req, authCodeURL.String(), http.StatusSeeOther)
  })

  http.HandleFunc("/link", func(w http.ResponseWriter, req *http.Request) {
    requestQuery := req.URL.Query()
    if requestQuery.Has("error") {
      http.Error(w, requestQuery.Get("error"), http.StatusInternalServerError)
      return
    }
    if requestQuery.Get("state") != state {
      http.Error(w, "state mismatched.", http.StatusBadRequest)
      return
    }
    ctx := context.Background()
    linkResp, err := fitbitClient.Link(ctx, requestQuery.Get("code"), codeVerifier, redirectURI)
    if err != nil {
      http.Error(w, err.Error(), http.StatusInternalServerError)
      return
    }
    userID = linkResp.UserID
    token = linkResp.Token
    io.WriteString(w, "ok")
  })

  http.HandleFunc("/profile", func(w http.ResponseWriter, req *http.Request) {
    ctx := context.Background()
    profile, _, _, err := fitbitClient.GetProfile(ctx, userID, token)
    if err != nil {
      http.Error(w, err.Error(), http.StatusInternalServerError)
      return
    }
    jsonBytes, _ := json.Marshal(profile)
    w.Header().Set("Content-Type", "application/json")
    w.Write(jsonBytes)
  })

  portString := ":" + strconv.Itoa(8080)
  log.Print("Listening ", portString)
  log.Fatal(http.ListenAndServe(portString, nil))
}

Notes

Most lines of oauth2_internal.go were adapted from https://go.googlesource.com/oauth2/+/refs/heads/master/internal, which is distributed under BSD-3-Clause, to customize behavior on token refresh.
The original license is available at https://go.googlesource.com/oauth2/+/refs/heads/master/LICENSE

This chunk is used instead of the corresponding part of oauth2 package when the hook function on token auto-refreshing is configured. So this may cause different behavior from the original one. For example, in fact, this does not do any special handling for App Engine.

License

TBD

# Packages

No description provided by the author

# Functions

NewClient initializes Fitbit API Client.

# Constants

ClientApplication represents client type application.
CodeChallengeMethod is the method used to hash the code challenge.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
LowercaseAlphabetLetters is a set of lower case alphabetic characters.
NumberLetters is a set of characters represent numbers.
PersonalApplication represents personal type application.
ScopeInvalid represents an invalid scope.
ScopeReadOnly means it is allowed to read data within the scope.
ScopeReadWrite means it is allowed to read and write data within the scope.
ScopeUnknown represents an unknown type of scope.
ServerApplication represents server type application.
UppercaseAlphabetLetters is a set of upper case alphabetic characters.

# Variables

CodeVerifierLength represents the length of `code_verifier` generating on authorization process.
CSRFStateLength represents the length of `state` generating on authorization process.
HTTPClient is the context key to use with golang.org/x/net/context's WithValue function to associate an *http.Client value with a context.
MetricUnit represents a list of units that is used when the language is set to neither LocaleUnitedStates nor LocaleUnitedStates.
RandomByteSet is a set of characters used to construct random bytes.
UnitedKingdomUnit represents a list of units that is used when the language is set to LocaleUnitedStates.
UnitedStatesUnit represents a list of units that is used when the language is set to LocaleUnitedStates.

# Structs

No description provided by the author
APIError represents an error that occurred on a request to Fitbit APIs.
No description provided by the author
Client is a client to interact with Fitbit APIs.
ContextKey is just an empty struct.
No description provided by the author
DetailError represents an error returned from Fitbit APIs that contains error title and detail fields.
DetailSourceError represents an error returned from Fitbit APIs that contains DetailError plus source parameter.
No description provided by the author
No description provided by the author
No description provided by the author
FieldNameMessageError represents an error returned from Fitbit APIs that contains MessageError plus fieldName.
No description provided by the author
No description provided by the author
No description provided by the author
MessageError represents an error returned from Fitbit APIs that contains error type and message fields.
No description provided by the author
No description provided by the author
RawError represents an error that only contains raw error returned from Fitbit APIs.
RequestError represents an error that occurred in a request process.
Scope represents the scope of permission.
No description provided by the author
Token represents the OAuth 2.0 Token.
No description provided by the author
Unit represents a list of units used in API responses.
No description provided by the author
No description provided by the author

# Interfaces

Error is the interface that has ability to return raw error returned from Fitbit APIs.

# Type aliases

ApplicationType represents the type of registered application.
Locale is used to specify the language and units of API responses.
ScopeType represents the type of scope.