JavaScript で作る Google Fit API サンプル

# Google Fit とは

- Google のヘルスケア関連のプラットフォームと SDK 
- 開発公式サイト: [Google Developers - Fit](https://developers.google.com/fit/)
- Android SDK は Android 2.3 GingerBreead (API Level 9) から導入されている
- Web でも REST API で使える

### 2018 年のアップデート

2018 年 8 月に Google Fit アプリがアップデート。WHO (世界保健機構) と協力して、健康に効果的な推奨運動量に基づいた「通常の運動」（分）と「強めの運動」（ポイント）の二つの指標が追加されました。

##### WHO の推奨指標

* 少し心拍数が上がる程度の運動（心拍数 100回/1分の軽めの早歩きなど）を 1 週間に 150 分以上
* またはランニングやエアロビクスなど激しい運動を 1 週間に 75 分以上
* またはそれらを合わせて同程度の運動

これを、Google Fit では「ハートポイント」として表示します。Google Fit アプリで週5日で1日30ポイント＝1週間で150ポイントを目標にして稼ぐことで、上記の WHO の掲げる指標をクリアできるとのこと。結果、以下の効果が得られると [Google Fit アプリのサイト](https://www.google.com/intl/ja_jp/fit/)で言及されています。

 * 心臓病のリスク低減
 * 睡眠の改善
 * 精神的な安定

# Google Fit システムコンポーネント図

モバイルアプリまたは Web ブラウザから入力し、クラウドに健康関連データ保存して、相互に読み書きできる API がある感じです。Android 端末で書き込んだデータを、 Web でダッシュボード的に確認できるとかができると思います。

> ![arch-gen-1.png](https://qiita-image-store.s3.amazonaws.com/0/5542/6c05a110-3fa9-6175-0fa1-d6f5d41e95ea.png)
> 引用元: https://developers.google.com/fit/overview?hl=ja

ちなみに Apple iOS の HealthKit では基本的にデバイス単位になるので、システムアーキテクチャの考え方が Apple と Google で違いが出てるっぽいです。面白いですね。

# ウェブアプリ開発の流れ

Google Fit API を Web ブラウザから利用する場合

1. ユーザーが Google にログインする
2. 承認画面でユーザーが承認 (OAuth)
3. プログラムでデータを取得する (REST API)

といった流れになります。

# セットアップ

Fitness API を使用するアプリケーションを [Google APIs Console](https://console.developers.google.com/flows/enableapi?apiid=fitness&pli=1) から登録し、許可オリジンの設定とクライアント ID を取得します。

# 軽率にデータを引っ張ってくるサンプルコード

1. スコープでまとめられたアクセストークンの取得
2. DataSources の取得
3. DataSources ごとの DataSets を取得

```html
<!doctype html>
<html lang="ja">
<head></head>
<body>
<script src="https://apis.google.com/js/client.js"></script>
<script>
const client_id = 'クライアントID'
const scope = ['https://www.googleapis.com/auth/fitness.activity.read']
let access_token = ''
 
function getToken() {
    gapi.auth.authorize({client_id: client_id, scope: scope, immediate: false, response_type: 'token'}, callback)
}
 
function callback(e) {
    access_token = e.access_token
    console.log(e)
    fetch('https://www.googleapis.com/fitness/v1/users/me/dataSources?access_token=' + access_token)
        .then(response => {
            return response.json()
        })
        .then(json => {
            console.log(json)
            getSteps()
        })
}
function getSteps() {
    const start = new Date('2019/3/1 0:00:00').getTime()
    const end = Date.now()
    console.log(new Date(start))
    console.log(new Date(end))
    
    fetch('https://www.googleapis.com/fitness/v1/users/me/dataSources/derived:com.google.activity.segment:com.google.android.gms:Google:Pixel 3:********:activity_from_steps/datasets/'+start.toString()+'000000'+'-'+end.toString()+'000000?access_token=' + access_token)
        .then(response => {
            return response.json()
        })
        .then(json => {
            console.log(json)
        })
}
window.onload = getToken
</script>
</body>
</html>
```

localhost:8000 とかで開いてみます。

# 実行結果

上記のサンプルコードをステップごとに解説します。

## ① Auth 情報取得

ポップアップブロックに引っかかって一瞬びっくり。

`https://www.googleapis.com/auth/fitness.activity.read` に関するデータを取得するよという感じです。

![スクリーンショット_2019-03-18_18_28_11-1-2.png](https://qiita-image-store.s3.amazonaws.com/0/5542/5f7d9758-dedc-eb6e-d017-628369918b3e.png)


→ アクセストークンとかが取得できます。

## ② Data Sources 取得

Google Fit Store にはデータソース（デバイス）ごとにデータが保存されているので、そのデータソースを一覧表示します。

![スクリーンショット_2019-03-18_18_28_14-1.png](https://qiita-image-store.s3.amazonaws.com/0/5542/27d55a98-9af0-b8f9-ae2c-690becd34796.png)


→ この次でどのデバイスのどのアクティビティについて取得する？といった UI を出すと良さそうです。

## ③ DataSets 取得

説明を端折る為に上のコードでは決め打ちしました。
`derived:com.google.activity.segment:com.google.android.gms:Google:Pixel 3:********:activity_from_steps` というデバイスで歩数を取得します。

取得するデータセットの範囲も指定します。REST API の URL 末尾に`/datasets/startTime-endTime` を指定します。**この値は、nanosec で表現することに注意してください**（JavaScript では表現不可能なので、`+'000000'` します）。

![スクリーンショット_2019-03-18_18_28_19-1.png](https://qiita-image-store.s3.amazonaws.com/0/5542/de1085c3-e6cb-b41f-087e-e7147678500b.png)

歩数が細かい単位で取得できます。

このあと、データをゴニョゴニョやって、日付ごとに統計を作ったりして、歩数履歴を作ったりして、お好きにどうぞ、という感じです。

合わせて `com.google.step_count.cumulative` や `com.google.step_count.delta` の Data Source で取得した場合の DataSets を比較してみてください。

# その他

* 歩数だけじゃなくて色々スコープがあるのでなんか面白いです
* ウェブキャンペーンとかプロモーションで使ったら面白いかもと思ったけど、Google の利用規約的にいいんかなという気持ちがあります
    * と思って確認したら禁止されてた→ https://developers.google.com/fit/terms?hl=ja
* 対応していない Android 端末が意外と多数で要注意です、センサーとかも独自だったりする端末も結構ある

# ちゃんと読もう 

- [API Reference  |  Google Fit  |  Google Developers](https://developers.google.com/fit/rest/v1/reference/)
- [Terms and Conditions  |  Google Fit  |  Google Developers](https://developers.google.com/fit/terms?hl=ja)

# 技術書典6で僕と握手！

Google Fit のことを書きましたが、技術書典6 で [Apple HealthKit の本](https://feb19.booth.pm/items/1304218)を出します。よろしくお願いします。

その後 [Google Fit の本](https://feb19.booth.pm/items/1467104) も書きました〜