FitbitのデータをGoogle Cloudを使って取得する

Fitbitのデータを Google Cloud を使って取得する方法をご紹介します。

Google Cloud で FitBit からデータを取得するサンプルを紹介します。

1. アプリケーションの全体像

今回想定するアプリケーションは以下のようなものを想定します。

  1.   Fitbit の認証情報を取得しプログラムで設定
  2.   Fitbit のデバイス情報を取得
  3.   バッテリーが 20% を切っていた 場合に Google Chat に通知する
  4.   1時間に1回チェックを行う

Google Cloud のフルマネージドサービスを中心に構築する場合以下のようなシステム構成で構築することが出来ます。

使用しているサービスはこちらになります。

  • Fitbit
  • Cloud Functions
  • Cloud Scheduler
  • Google Chat

Cloud Functions が、アプリケーション(コード)を動かすサービスになります。
今回は、単一の機能であり、ソースコードの更新が Web Console から手軽に行えるという理由から、Cloud Functions を選択しています。

Docker コンテナによる構築に慣れている方やより複雑なアプリケーションを構築する場合などは、Cloud Run を選択することも可能です。

2. 設定手順

(1) Fitbit認証

当記事では、自分の Fitbit のデータを参照します。
実際にデバイスと接続済みの Fitbit のアカウントを利用して下さい。

こちらのURLからアプリケーションを新規で登録します。
https://dev.fitbit.com/apps/new

各項目は、ご自身のHP等のURLを登録して下さい。

Redirect URL は、認証情報を取得時にリダイレクトされるURLですが、今回は実際にアクセス出来ないURLでも大丈夫です。
http://localhost:8080/ のようなURLを入力して下さい。

各項目を入力し、Registerボタンを押すとこちらの画面に遷移します。

ここで、以下の項目を利用します

  • OAuth 2.0 Client ID
  • Client Secret

次の手順では、Client Secret の入力を求められますので、メモしておきます。

実際のシステムを構築する際には、認証情報をシステム内で取得することになりますが、Fitbit の公式チュートリアルで取得が可能となっています。

中程にある、 OAuth 2.0 Tutorial のリンクをクリックすると、チュートリアルの画面に遷移します。

Fitbit OAuth 2.0 Tutorial

こちらの画面になります。

Client ID は、入力済みになっています。
Client Secret は、空欄になっているはずなので、先程の画面に記載の Client Secret を入力します。

スクロールし、GENERATEボタンを順番に押していきます。

Step 2 のところで、Authorization URL という項目にURLが表示されています。

このリンクでこれまで GENERATE で作成した認証情報を使って、認証を行います。

こちらの画面が表示されるはずです。
今回は すべて許可する にチェックを入れてすべてのデータを取得出来るようにしましょう。

許可を押すとこちらの「このサイトにアクセスできません」の画面になります。

表示上ではエラーになっていますが、必要な情報はアドレスバーにあります。
以下のようなURLになっていると思います。

http://localhost:8080/?code=xxxxxxxxxxxxx&state=yyyyyyyyyy

このcode と state の値をこの後の手順で使用します。

元のステップに戻り、Step 3 で、先程のcode と state の値を入力し、その後の Step 4 で token を取得します。

その後も、ボタンを順番に押して最後の手順のRefresh Tokens まで進めて下さい。

最後の Response にJSON形式の結果が表示されます。
この中の以下の項目をプログラムに記載しますのでメモします。

  • access_token
  • refresh_token

(2) Google Chat の設定

Cloud Functions の設定の前に、通知先となる Google Chat の設定を先に行いたいと思います。
Chat に通知するための Webhook URL を作成します。

通知用のスペースを用意し、スペースタイトルのメニューからアプリと統合 を選択します。

こちらのポップアップが表示されるので、Webhookを管理 をクリックします。

Webhook の名前を入力します。
チャットの投稿者の名前になりますので、わかる名前になっていれば問題ありません。

以下のように URL が生成されます。
コピーのアイコンをクリックして URL を保存しておいて下さい。

(3) Cloud Functionsの設定

Cloud Functions は、プログラムを動かすためのインスタンスの設定と権限の設定が必要になります。

function作成

ここから、Fitbit へアクセスするプログラムを実行する Cloud Functions の設定を行います。

Google Cloud のメニューから functions を開きます。

コンソールの上部にある ファンクションを作成 をクリックします。

こちらの設定画面で各種設定を入力します。

Cloud Functions の 環境 には、第1世代と第2世代があります。
それぞれ特徴がありますが、今後のアップデート等は第2世代に対して行われると思いますので、今回は第2世代を選択します。

トリガーは、HTTPS としておきます。
外部からのアクセスをされないようにするために、認証が必要 としておきます。

ここで表示されている url がこの function を起動するための URL となります。

次へ ボタンを押すとコードを入力する画面が表示されます。

今回は、Python を使いますので、ランタイム で Python 3.11 を選択します。

選択すると、Python の最低限必要となるソースコードが表示されます。

パラーメータを受け取る場合などは、参考になりますので一度確認しておくと良いと思います。

今回は、実際に動くソースを用意しましたので、こちらに書き換えます。

実際に書き換えるソースは以下となります。

import functions_framework
import fitbit
import requests

# Fitbit認証情報
consumer_key = 'xxxx'
consumer_secret= 'xxxxx'
access_token='xxxxxx'
refresh_token='xxxxxx'

# Google ChatのWebhook
chat_webhook = 'https://chat.googleapis.com/v1/spaces/xxxxxx'

@functions_framework.http
def hello_http(request):
    try:
        # Fitbit Client作成
        authd_client = fitbit.Fitbit(consumer_key, consumer_secret,
                                access_token=access_token, refresh_token=refresh_token)
        # Fitbit device情報取得 
        devices = authd_client.get_devices()

        # Fitbit device情報は、複数端末に対応しているため、For文で1津づつ取得
        for device in devices:
            # dviceVersion(デバイス名)とbatteryLevel(バッテリーの残り%)を取得
            deviceVersion = device['deviceVersion']
            batteryLevel = device['batteryLevel']
            # バッテリ残量が20%より少ない場合、Google Chatに通知する
            if (device['batteryLevel'] < 20 ) :
                chat_body = f'{deviceVersion}のバッテリーが低下しています。現在 {batteryLevel}%です。'
                print(chat_body)
                data = {
                    'text': chat_body,
                }
                requests.post(chat_webhook, json=data)
            else:
                # 20%以上の場合は、ログに正常をのログを残す。(正常起動が確認出来るようにするため)
                print(f'{deviceVersion}のバッテリーは、正常です。')
        return 'OK'

    except Exception as e:
        # どこかでエラーになった場合は、エラー情報をログに出力
        print(e)
        return 'NG'

requirements.txt

functions-framework==3.*
fitbit==0.3.1
requests==2.31.0

main.py は、以下の項目を前の手順で取得した値を設定して下さい。

  • consumer_key: Fitbit の Client ID です。
  • consumer_secret: Fitbit の Client Secret です。
  • access_token: Fitbit の access_token です。
  • refresh_token: Fitbit の refresh_token です。
  • chat_webhook = Google Chat の Webhook URL です。

本来は、環境変数に設定するなど、ソースコードの外で設定したほうが良い項目になります。
また、 Fitbit の各項目は、認証情報になるので、本来は暗号化して安全に利用する必要があります。

【特に注意】
Cloud Functions では、環境変数に設定する際に、Google Cloud の暗号化サービスである、Secret Manager を使って、暗号化することが出来ます。
本格的に利用する際には、そちらの利用をするようにして下さい。

以上を反映して デプロイ を押します。

デプロイ完了には、数分かかります。

権限設定

function 作成時に、 認証が必要 と選択した場合には、functions を起動できるのは、起動元ロール(roles/run.invoker) が割り当てられたユーザやサービスアカウントにに限られます。

少し複雑になるのですが、第2世代 は、Google側で、Cloud Run を設定しCloud Run 上で Functions が動く厚生となります。

このため、Cloud Run 側で Cloud Functions に設定されているサービスアカウントに対して、起動元ロール を付与し、Cloud Functions 側では、実際に起動するユーザー、サービスアカウトに対して、 起動元ロール を設定する必要があります。

function の詳細タブを開きます。

ここで、function に設定されているサービスアカウントを確認します。

右上にある、Powered by Cloud Run の項目にあるリンクをクリックすると Cloud Run が開きます。

Cloud Run の権限設定は、Cloud Run の一覧画面で行います。
上の左矢印を押して、一覧画面に遷移します。

一覧画面で、function で利用されているサービス(ここではfitbit)にチェックを入れると、右側に権限設定が出来る項目が表示されます。

ここで、新しいプリンシパル に Cloud Functions で設定された、サービスアカウントを設定し、ロール に Cloud Run 起動元 を設定します。

これで、Cloud Functions から Cloud Run を起動することが出来るようになります。

第2世代にすることで、権限設定が複雑になっている部分はありますが、Cloud Run をベースにすることで、起動できる時間が伸びたり、Cloud Run が対応している Event Aec というサービスを介して起動する事ができるようになり、第1世代と比べて使用できる幅が広がっています。

(4) Cloud Scheduler の設定

最後に、Cloud Functions を定期的に起動するための設定を行います。

定期的に起動するためには、Cloud Scheduler を使います。

Cloud Scheduler は、Google Cloud のメニューのインテグレーションサービス にあります。

Scheduler に遷移し、ジョブを作成 をクリックします。

定義を設定する画面が表示されます。

  • リージョン: asia-northeast1
  • 頻度: 0 */1 * * * (これで1時間に1回起動されます)
  • タイムゾーン: 日本標準時を選択します。(入力時には、日本 と入力するとフィルタがかかります)

※ 一時間に一回なので、UTCでも問題ありません。

実行内容を構成します。

  • URL: Cloud Functionsの起動用URLを設定します。
  • HTTPメソッド: GET
  • HTTPヘッダー: Authヘッダーに OIDC トークンを追加 を選択し、サービスアカウントには、Default compute service account を設定します。

サービスアカウントは、本格的な運用の際には、独自のサービスアカウントを作成して、必要最低限の権限を付与することをお薦めします。
今回は、手順の簡略化のため、Default compute service account を利用します。

次のオプション設定は、デフォルトのママとします。

ここからは、Cloud Functions に戻り、起動元の権限を追加します。

こちらの画面で、 アクセス権を付与 のリンクを押します。

こちらの画面が開きます。

  • 新しいプリンシパル: Cloud Scheduler で設定したサービスアカウント(今回は、Default compute service account)を入力します。
  • ロール: Cloud Functions 起動元 を選択します。

保存を押すと権限が追加されます。

再度、Cloud Scheduler に戻り、操作 のメニューで 強制実行 を押すと即時実行されます。

これで、Google Chat に通知がされれば成功です。
※ Fitbit デバイスのバッテリー残量が 20%を切っていないと Google Chat には通知されないことに注意して下さい。

3. まとめ

一つずつ手順を追っていくと、とても難しく感じますが、半分くらいは、Fitbit の認証になっており、Cloud Functions の設定も権限設定に手間がかかっていることに気が付かれるかもしれません。

特に、Google Cloud の権限設定は、必ず必要になるものでもあり、慣れてくるとあまり時間はかからなくなっていきます。
今回利用した、Cloud Functions、Cloud Scheduler などは、Google のフルマネージドサービスとなっており、無料枠も十分に提供されています。 今回作成したような、簡単なアプリケーションの1時間に1回程度の起動であれば、すべて無料で運用することもでき、ほぼメンテナンスをすることなく、稼働し続けてくれます。

是非、色々なサービスの API を使って自動化をして、Google Cloud に慣れて行って頂ければと思います。

4. 最後に

TD SYNNEXでは、 Google Cloud と Fitbit の両方をお取り扱いしております。
興味のある方は、こちらまでご連絡ください。

Google Cloudの導入は当社にご相談ください

ITディストリビューターであるTD SYNNEXはGoogle Cloud™ Partner Award を受賞するなど、長年にわたりGoogle™のグローバル認定ディストリビューターとして、総合的な Googleソリューションを提供しています。お客様にとって最適なソリューションの提案や導入、活用をサポートします。

製品・サービスについてのお問合せ

情報収集中の方へ

導入事例やソリューションをまとめた資料をご提供しております。

資料ダウンロード
導入をご検討中の方へ

折り返し詳細のご案内を差し上げます。お問い合わせお待ちしております。

お問い合わせ