【なつやすみのしゅくだい】
前々からgo言語触りたかったってことと、FitbitAPIを叩いて情報を取得したかったので、夏季休暇期間の暇な時間にgo言語でfitbitAPIを叩いて睡眠情報を取得してみた。
ソースはこちら
github.com
作業のお供
zenpad7で dアニメストアでアニメ見ながら作業するのが捗った。
タブレットスタンドがかなり役立った。
CLANNAD Afterの後半とハナヤマタ前半見終わった。
anime.dmkt-sp.jp
fitbitAPIを使うために諸々登録する
dev.fitbit.com
dev.fitbit.comにユーザ登録をした後アプリケーションの登録を行う。
画像の通りに必要なところを埋めていく。
Applicatinon NameやDescription, Application Website, Organization, Organization Websiteまでは適当でOK
自分で使うだけだし。
OAuth 2.0 Application Type はClientを選択した。
Using Implicit Grant Flowを使うためにはClientを選択する必要がある。
Using OAuth 2.0 — Fitbit Web API Docs
Callback URLは重要で、ここで登録したアドレス以外がcallbackのURLとして指定されても使うことができない。
今回はgoのビルドインサーバを使うのでlocalhost:8080とした。
Default Access Typeは読み取りだけでいいのでReadとした。
これでSaveすると、OAuth 2.0 Client ID / Client Secretが発行される。
また、
OAuth 2.0: Authorization URI と OAuth 2.0: Access/Refresh Token Request URIも取得できる。 (このURLは共通なので発行される。というより表示される。という書き方が正しいかもしれない)
どんな感じに叩くか確かめたい
Fitbit API Debug Tool
Debug toolが用意されている。
これに自分のClient IDやsecretを入力し指示に従って行くと、一通り認証から必要な情報の取得までできる。
プログラムを組み終わった後この機能に気づいた...
認証ページのURLを生成する
generateOauthURL.goとして作成した。
今回はAuthorization Code Flowで認証するための認証ページのURLを作成した。
examplsにあるように、
https://www.fitbit.com/oauth2/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scopes}
となる。
client_id/redirect_urlは上で生成したものになる。
scopeは
Using OAuth 2.0 — Fitbit Web API Docs
から見たい情報のscopeを選択する。今回は睡眠情報なのでsleepを指定。複数の場合空白で繋げて%エンコードする必要がある。
(%20で複数scopeをつなぐ)
コード上では、HttpParam構造体とAuthUrl構造体を作り、必要な情報はこれを使うようにしている。
また、環境変数は.envとしてアプリケーションのルートディレクトリに作成して、それをgithub.com/joho/godotenvライブラリを使用して読み込んで使用している。
アクセストークンの取得
上記で生成したURLにアクセスすると認証画面が表示され、認証するとredirect_urlに設定したページに飛ばされる。
このリダイレクト先をfitbit.goとして作成している。
今回は簡単に使いたかったのでgoのbuild inサーバを使用している。
リダイレクトされるとクエリパラメータに?code=とaccess token取得用のcodeが付与される。
まずはこのcodeを使用してaccess tokenを取得する。
https://dev.fitbit.com/docs/oauth2/#accessT
endpointのURLはhttps://api.fitbit.com/oauth2/token
これに対してPOSTを行う。必要なBody部分としては、
リダイレクトのときについてきたcodeとgrant_type=authorization_code,client_id,redirect_uriが必要。
また、Headerには {client_id}:{client_secret}をBase64 Encodingしたものが必要となる。:をつけた状態の文字列をBase64 Encoding忘れるのがありがちなミスなので注意したいところ。
これでPOSTするとjson形式でaccess_tokenやscope,user_idが返却される。
この値をdecodeしたいので、FitbitJsonという構造体を作り、json.Unmarshalでdecodeした。
これで睡眠情報を取得するためのユーザIDとaccess_tokenが取得できた。
睡眠情報を取得する。
Sleep Logs — Fitbit Web API Docs
睡眠情報に関してAPIは多種あるが、今回は単純に睡眠時のログを取得するAPIを叩く。
APIのエンドポイントは、https://api.fitbit.com/1/user/[user-id]/sleep/date/[date].json
となる。user-idはアクセストークンの取得で取得できたものを使用する。
dateはyyyy-MM-dd形式で指定する。
このAPIを叩くときには認証が必要なのでHeaderに Authorization: Bearer [access_token]
を与えてあげる必要がある。
これで睡眠情報が取得できる。
睡眠情報の形式
以下のようにjson形式で返却される。 (ここでは見やすいようにjson_decodeしたものを記載している)
起きた回数や睡眠効率。何時に寝てその時間帯はどんなステータス(寝返りを打っていたのか、目覚めていたのか)
何時間寝ていたのか。など取得できる。
{
"sleep": [
{
"awakeCount": 0,
"awakeDuration": 0,
"awakeningsCount": 13,
"dateOfSleep": "2016-08-xx",
"duration": 25260000,
"efficiency": 94,
"isMainSleep": true,
"logId": 12226936629,
"minuteData": [
{
"dateTime": "00:49:30",
"value": "1"
},
{
"dateTime": "00:50:30",
"value": "1"
},
~~~~~
{
"dateTime": "07:49:30",
"value": "1"
}
],
"minutesAfterWakeup": 0,
"minutesAsleep": 396,
"minutesAwake": 25,
"minutesToFallAsleep": 0,
"restlessCount": 13,
"restlessDuration": 25,
"startTime": "2016-08-xxT00:49:30.000",
"timeInBed": 421
}
],
"summary": {
"totalMinutesAsleep": 396,
"totalSleepRecords": 1,
"totalTimeInBed": 421
}
}
今後
REFRESH TOKENをつかって認証したり、何か別なシステムと連携して捗るようにしたい。