Help us understand the problem. What is going on with this article?

FitbitのAPIを手っ取り早く試してみる方法

More than 3 years have passed since last update.

Fitbitは、腕時計型の活動量計(心拍数計)です。測定データを取得できるみたいだけど、どこから手をつけていいか分からない!という方向けに、まずはプログラムを書かなくても自分のFitbitの登録・測定データを取得できる方法を紹介します。

2017.3.4追記: Postmanをインストール可能な環境であれば、この記事に書かれている方法よりも、FitbitのOAuth 2.0 APIをPostmanで試してみる方法の方が、簡単で、扱いやすいかと思います。

1. OAuth認証情報を作成

https://dev.fitbit.com/ にアクセスします。

F08E99F7-C0F5-4EC7-A148-ACE6D387EFAF.png

画面右上のREGISTER AN APPボタンをクリックすると、登録フォームが表示されます。

3.png

URLを入力する欄がありますが、本記事に基づく作業では、サーバやクラウドを用意する必要はありません。基本的に、何か埋まっていれば良いです。ただし、以下の点に気をつけてください。

  • Desctiptionは10文字以上
  • OAuth 2.0 Application TypeにはClientまたはPersonalを選択
  • Callback URLにはリダイレクトが発生しないURLを入力(http://localhost/推奨)

Callback URLは、最後のスラッシュの有無まで含めて正確にメモっておきましょう。

最後にあるRegisterボタンをクリックすると、登録完了画面が表示されます。

4.png

OAuth 2.0 Client IDClient Secretが、次のステップで必要となります。

2. 認証リクエストURIの生成

OAuth 2.0 tutorial page にアクセスします。
https://dev.fitbit.com/apps/oauthinteractivetutorial

5.png

  • Flow type:に、Implicit Grant Flowを選択(デフォルト)
  • OAuth 2.0 Client ID:Client Secret:に、登録完了画面に表示された値を入力
  • Redirect URI:に、Callback URLで指定したURLを一字一句違えずに入力

入力し終わったら、入力欄の下にある長いリンクをクリックします。

3. 自分のアカウントと対応付け

別ウィンドウが開き、アクセス許可を求められます。

6.png

この画面でなく、「接続しようとしているアプリは Fitbit に有効なデータを提供しませんでした。この問題を報告してください。」と表示される場合は、Redirect URI:で指定したURLが正しいか、余分な空白が含まれていないかを確認してみましょう。

「許可」をクリックすると、存在しないURLであれば、エラーページが表示されます。

7.png

まだ閉じないでください!アドレスバーに表示されているURLをどこかに控えておきます。

先ほど「リダイレクトが発生しないURL」と説明したのは、ここでリダイレクトしてしまうとアドレスが変わってしまい、次のステップで利用することができなくなってしまうためでした。

4. 認証URLを解析

OAuth 2.0 tutorial page に戻ります。

8.png

アドレスバーに表示されていたURLを、2 Parse responseのテキストフィールドに貼り付けます。説明文には#scopeから後の部分を貼り付ける旨書かれていますが、この例では#access_tokenで始まるため、正しくありません。現在は、URL全体を貼り付けても問題なく解析されます。scopesuser idtime to livetokenが表示されていれば、解析に成功しています。これらのデータが今後必要になることはありません。

解析に失敗すると赤い文字でエラーメッセージが表示されます。URLの形式が上記の例と異なっている場合は、リダイレクトしてしまっている可能性が高いですので、Callback URLに別のURLを指定して最初からやり直してみましょう。

5. クエリの実行

下に進むと、curlのコマンドが表示されています。

9.png

curlがインストールされていれば、これをプロンプトやターミナルにコピペして実行できます。

Hurl.itを使ったクエリ実行

コマンド表示欄の下の小さいSend to Hurl.itリンクをクリックすると、ブラウザ上でRESTクエリを実行できます。

FC929E22-6740-4D7F-8F7E-2D3009647605.png

私はロボットではありませんにチェックを入れて、クイズを解き、Launch Requestをクリックします。

fa17ca0a-2b9f-6668-f08f-caffe12d85fd.png

整形されたJSONで結果が返ってきます。画面右端のview rawをクリックすると、生データが表示されます。

6. APIの探検

API Document
https://dev.fitbit.com/docs/

Resource URLs に書かれている書式を参考に、API endpoint URL:を書き換え、クエリを再実行します。Example Request をそのままコピペして実行してみて、少しずつ変更していくのも良いでしょう。

例1:直近1週間の心拍数をゾーン別に取得

https://api.fitbit.com/1/user/-/activities/heart/date/today/7d.json

参考:Get Heart Rate Time Seriesの仕様
https://dev.fitbit.com/docs/heart-rate/#get-heart-rate-time-series

このような結果が取得できます。(11月26日に取得)

{
  "activities-heart": [
    {
      "dateTime": "2016-11-20",
      "value": {
        "customHeartRateZones": [],
        "heartRateZones": [
          {
            "caloriesOut": 154.56368,
            "max": 93,
            "min": 30,
            "minutes": 88,
            "name": "Out of Range"
          },
          {
            "caloriesOut": 322.1564,
            "max": 130,
            "min": 93,
            "minutes": 92,
            "name": "Fat Burn"
          },
          {
            "caloriesOut": 151.52952,
            "max": 158,
            "min": 130,
            "minutes": 27,
            "name": "Cardio"
          },
          {
            "caloriesOut": 16.33092,
            "max": 220,
            "min": 158,
            "minutes": 2,
            "name": "Peak"
          }
        ],
        "restingHeartRate": 72
      }
    },
    {
      "dateTime": "2016-11-21",
      "value": {
        "customHeartRateZones": [],
        "heartRateZones": [
          {
            "max": 93,
            "min": 30,
            "name": "Out of Range"
          },
          {
            "max": 130,
            "min": 93,
            "name": "Fat Burn"
          },
          {
            "max": 158,
            "min": 130,
            "name": "Cardio"
          },
          {
            "max": 220,
            "min": 158,
            "name": "Peak"
          }
        ]
      }
    },
    {
      "dateTime": "2016-11-22",
      "value": {
        "customHeartRateZones": [],
        "heartRateZones": [
          {
            "max": 93,
            "min": 30,
            "name": "Out of Range"
          },
          {
            "max": 130,
            "min": 93,
            "name": "Fat Burn"
          },
          {
            "max": 158,
            "min": 130,
            "name": "Cardio"
          },
          {
            "max": 220,
            "min": 158,
            "name": "Peak"
          }
        ]
      }
    },
    {
      "dateTime": "2016-11-23",
      "value": {
        "customHeartRateZones": [],
        "heartRateZones": [
          {
            "caloriesOut": 13.74296,
            "max": 93,
            "min": 30,
            "minutes": 10,
            "name": "Out of Range"
          },
          {
            "caloriesOut": 146.3536,
            "max": 130,
            "min": 93,
            "minutes": 43,
            "name": "Fat Burn"
          },
          {
            "caloriesOut": 68.62556,
            "max": 158,
            "min": 130,
            "minutes": 11,
            "name": "Cardio"
          },
          {
            "caloriesOut": 73.89072,
            "max": 220,
            "min": 158,
            "minutes": 8,
            "name": "Peak"
          }
        ]
      }
    },
    {
      "dateTime": "2016-11-24",
      "value": {
        "customHeartRateZones": [],
        "heartRateZones": [
          {
            "max": 93,
            "min": 30,
            "name": "Out of Range"
          },
          {
            "max": 130,
            "min": 93,
            "name": "Fat Burn"
          },
          {
            "max": 158,
            "min": 130,
            "name": "Cardio"
          },
          {
            "max": 220,
            "min": 158,
            "name": "Peak"
          }
        ]
      }
    },
    {
      "dateTime": "2016-11-25",
      "value": {
        "customHeartRateZones": [],
        "heartRateZones": [
          {
            "max": 93,
            "min": 30,
            "name": "Out of Range"
          },
          {
            "max": 130,
            "min": 93,
            "name": "Fat Burn"
          },
          {
            "max": 158,
            "min": 130,
            "name": "Cardio"
          },
          {
            "max": 220,
            "min": 158,
            "name": "Peak"
          }
        ]
      }
    },
    {
      "dateTime": "2016-11-26",
      "value": {
        "customHeartRateZones": [],
        "heartRateZones": [
          {
            "max": 93,
            "min": 30,
            "name": "Out of Range"
          },
          {
            "max": 130,
            "min": 93,
            "name": "Fat Burn"
          },
          {
            "max": 158,
            "min": 130,
            "name": "Cardio"
          },
          {
            "max": 220,
            "min": 158,
            "name": "Peak"
          }
        ]
      }
    }
  ]
}

上記の場合は、11月20日にピーク(158以上)が2分、有酸素運動(130以上158未満)が27分、脂肪燃焼(93以上130未満)が92分、ゾーン圏外が88分あったことになります。Fitbitを装着している日だけ、minutes属性が含まれます。

例2:2016年11月20日16時15分の心拍数を取得

手順1にて、OAuth 2.0 Application TypePersonalを指定して登録してある必要があります。

https://api.fitbit.com/1/user/-/activities/heart/date/2016-11-20/1d/1sec/time/16:15/16:16.json

参考:Get Heart Rate Intraday Time Seriesの仕様
https://dev.fitbit.com/docs/heart-rate/#get-heart-rate-intraday-time-series

このような結果が取得できます。

{
  "activities-heart": [
    {
      "customHeartRateZones": [],
      "dateTime": "2016-11-20",
      "heartRateZones": [
        {
          "caloriesOut": 0,
          "max": 93,
          "min": 30,
          "minutes": 0,
          "name": "Out of Range"
        },
        {
          "caloriesOut": 5.62212,
          "max": 130,
          "min": 93,
          "minutes": 1,
          "name": "Fat Burn"
        },
        {
          "caloriesOut": 7.49616,
          "max": 158,
          "min": 130,
          "minutes": 1,
          "name": "Cardio"
        },
        {
          "caloriesOut": 0,
          "max": 220,
          "min": 158,
          "minutes": 0,
          "name": "Peak"
        }
      ],
      "value": "139"
    }
  ],
  "activities-heart-intraday": {
    "dataset": [
      {
        "time": "16:15:00",
        "value": 154
      },
      {
        "time": "16:15:05",
        "value": 149
      },
      {
        "time": "16:15:10",
        "value": 145
      },
      {
        "time": "16:15:15",
        "value": 143
      },
      {
        "time": "16:15:20",
        "value": 136
      },
      {
        "time": "16:15:25",
        "value": 133
      },
      {
        "time": "16:15:30",
        "value": 132
      },
      {
        "time": "16:15:40",
        "value": 130
      },
      {
        "time": "16:15:45",
        "value": 129
      }
    ],
    "datasetInterval": 1,
    "datasetType": "second"
  }
}

7. 実際のアプリ作成

自分の意図するデータが取得できそうであれば、アプリ制作に取り掛かります。Fitbit APIの短いサンプルやチュートリアルをいくつか紹介します。

Fitbit APIをPHPでOAuth認証してWebサイトに心拍数などを出力
https://www.sho-yamane.me/entry/2016/07/16/163712

Fitbit Charge HRの心拍数データを取得する(Python)
http://shima-nigoro.hatenablog.jp/entry/2016/05/29/181309

Fitbit APIにOAuth 2.0でアクセスして心拍データを取得する方法(Ruby)
http://kaorumori.hatenadiary.com/entry/2015/09/23/011006

Using OAuth 2.0 - Accessing the Fitbit API
https://dev.fitbit.com/docs/oauth2/

API開発者によるPoCサンプル(Node.js)
https://github.com/jeremiahlee/fitbit-hapi-demo

psFitb1t: The original Powershell module to retrieve YOUR heartrate data
https://github.com/CollinChaffin/psFitb1t

ここまで来たら、もうOAuth 2.0プログラミングの世界ですので、普通のOAuthの記事を参考に作っていけばいいと思います。

ちなみに、Passport の Strategy があります。

Passport strategy for Fitbit OAuth 2.0
https://github.com/thegameofcode/passport-fitbit-oauth2

makopo
StackOverflowや製品のフォーラム・Issueにはあるけど、日本語での情報が充実していないものを中心に載っけています。興味とお仕事の事情に応じて投稿技術の傾向が変わりますので、フォローされる方はご留意ください。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした