onemuri.space

Cloud Run と Fitbit を連携してみた


今回 Cloud RunFitbit を連携させて、歩数の当月の累積グラフを作成してみました!

Cloud Run と Fitbit を連携して作成したもの

まずは成果物からお見せします!!

今回の作成物

目新しい技術を用いているわけではないですが、Cloud Run を採用して開発したので、これから Cloud Run 触ってみたい人や、Cloud Run って何ができるの?という方のためにこの記事を書こうと思います。

CloudRunとは

グラフを描画するためのデータをAPIとして、提供するために、Cloud Run を採用しました。

Cloud Run はコンテナ技術を活用して、Google Cloud Platform (GCP) にて提供されているマネージドなサーバーレスなコンピューティングプラットフォームです。

これまで、GCPではコンピューティングプラットフォームとして、GCE・GAE・GKE・Cloud Function などを提供していましたが、2018年の8月にアルファ版がリリースされ、2019年4月にベータ版がリリースされたばかりの、比較的新しいコンピューティングプラットフォームです。
https://cloud.google.com/run/docs/release-notes?hl=ja#August_15_2018

基本的には、インフラ環境を考えずに済みアプリの実装に力を注ぐことができるものとして、 GAE と Cloud Function がありましたが、そこに割り込む形で Cloud Run は存在します。

GCP公式がどのコンピューティングを選択すれば良いのかをきれいに図にまとめてくれているので、それを読んでみるとわかりやすいと思います。

GCPコンピューティングプラットフォームの選択

Fitbitとは

グラフを描画するための元データとして、私が日々身につけている Fitbit の計測データを利用しました。 Fitbit は 開発者用に API を用意してくれています。

ちなみに、Fitbit 気になる人もいると思うのでアプリのスクショ載せておきますね。

自分のアプリのスクショとか
fitbitアプリ

やりたいこと

大きく2つの目的があって今回開発しました

  • Fitbit で計測している歩数を累積で表示したい
  • Cloud Run さわってみたい!

2つ目は完璧に個人の願望ですねw

スマートウォッチである Fitbit(私のは Fitbit Charge3です ) は Apple watch と比較すると、バッテリーの駆動時間が圧倒的に良いです。平気で1週間近く充電しなくても持ちます。

なので、常に自分の歩数・心拍数・消費カロリー・歩行距離などを計測してくれます。(充電を意識しなくても良いのはかなりストレスフリーです)

Fitbit はそれらのデータをアプリ上で様々な可視化をしてくれていますが、基本的な表示ばかりで、かゆいところに手が届きません(これはスマートウォッチのアプリはもれなく同じ状態だと思います)

今回は、コロナ の影響もあり明らかに歩数が減ったことも影響して歩数が少なくなる表示を見ることにげんなりしていたので、毎日下がることなく積み重なって、テンションが上がる累積のグラフがみたくなったのです。(コロナ 影響で走ることが多くなったのでその成果を累積でもみてみたかったというのもあります)

また、普段 GCP を使っている中で、 Cloud Run の使い心地が気になっていたので、開発ついでにさわってしまえ!というモチベがありました。

システム構成図

さぁ、今回開発したAPIの構成図です。

アーキテクチャ

大体、開発期間は2週間ぐらいでしょうか(Cloud Run の最初のデプロイが、記事執筆の13日前だったのでw)。

https://onemuri.space は 2020年3月に Nuxt.js で SPA+SSR の構成で作成して、Firebase で Hosting しています。その内容を知りたい人は、以前記事 (ブログを WordPress から自作ブログへと移行しました) を執筆したので是非読んでみてください。

今回は構成図の Firebase と Nuxt.js 以外部分を開発しました。

大まかな説明は以下です。

  • ユーザー(web)は Cloud Run の API を叩いて歩数取得
  • Cloud Scheduler で夜中に一回 Cloud Run が Fitbit API から activities のデータを取得して、Firestore に保存・更新
  • Fitbit API アクセス用の access_token と refresh_token を Cloud Scheduler が Cloud Run のAPIを叩き、4時間おきに更新

※ Fitbit API の token は有効期限が 8時間だったので、定期的に refresh しています。

CloudRun で Fitbit のデータを Firestore へ保存

今回はバッチ処理用のサーバーと REST API サーバーの2つのサービスが必要だったので、Cloud Run も2つのサービスを作成しています。

  • get-activity: REST API サービス
  • healthcare: バッチ処理用のサービス

Cloud Run

(今更見返すと、名称がダサすぎる気がする… のは置いておいて、) healthcare のサービスは Fitbit API を叩いて、私の活動データを取得し、Cloud Firestore へと保存します。直近1週間分を保存・更新するようにしています。

これは、Fitbit アプリを開いていないと同期されず、私が時折開くのを忘れてしまうのでこのようにしています。

Firestore

次に、get-activity はブログ用のREST API サーバーです。Fitbitとかとの連携はせずに、Firestore の情報から必要なレスポンスを返します。

実際のところ Client 側で Fitbit API を直接叩いて活動情報を抜き出してもいいですが、Fitbit API は1時間の間で150回以上のリクエストを叩くと、リクエスト上限のエラーに引っかかってしまうので、データをバッチ処理でこちら側の storage にて保持するようにしています。

また、Client 側で、Fitbit に関する credential 情報を保持する必要がないことも大きいです。正直盗み見されて困るようなデータはないですが、問題の切り分け大事です。

将来的に、いろんな人の Fitbit データで何かしたい!ってなったときは大人しく、OAuth で連携すると思います。(どちらにせよリクエスト制限の問題はありますけど)

Cloud Scheduler で バッチ処理

先ほどお見せした、 バッチ処理用の healthcare サービスですが、こちらは OIDC (OpenID Connect) によって認証し、Cloud Scheduler 経由でバッチ処理のエンドポイントを叩いています。(OIDCについてはOIDC作者の記事を読めば良いかなと思います。ちなみに、よく混同される OAuth と OpenID Connectの違いはこちらの記事を読めば良いと思います。)

Cloud Run のエンドポイントを叩くように Scheduler を作成する時に、ターゲットを HTTP にして、AuthヘッダーOIDCトークンを追加を選択して、 healthcare サービスを叩く専用のサービスアカウントを指定します。

Create Cloud Scheduler

ちなみに、 gcloud コマンドでも scheduler を作成することができます。今回はスクリプトを書いて scheduler を作成しました。

作成したジョブは以下2つです

  • PostActivities: Fitbit API と連携して、Firestoreにデータを保存更新するためのエンドポイントを叩く
  • RefreshToken: Fitbit API の refresh_token を更新するエンドポイントを叩く

Cloud Scheduler

CloudRun でブログ用の API 開発

先ほど説明した、 Cloud Run のサービスの内の一つである、 get-activity サービスが、ブログ用のAPIです。

やっていることはとてもシンプルで、Firestore から直近一ヶ月の歩数データを取得し、整形してレスポンスを返すだけです(現状はエンドポイントも一つだけでとてもシンプルAPIです。今後増やしていきたいです)

vue-charts を用いてグラフ化

グラフ描画ライブラリはなんでもよかったですが、有名どころの Chart.js有名どころの Chart.js の wrapper ライブラリである vue-chartjs を利用しました。まぁ、あとでなんでも置き換えできるので、ささっと調べてみて、問題なさそうだったから利用しました。(今回の用件は歩数の累積表示ができることだったので、何でもよかったとも言う)

Vue.js 用のサンプルコードがあったので導入しやすそうというのもありました

Vue.js のライフサイクルの mounted 時に、axios で Cloud Run で作成したget-activity サービスのAPIを叩いて、そのレスポンスでグラフを作成しました。

歩数の累積グラフ

きっと、18日間で 63682歩は大したことない数字なのですが、桁が大きくなると達成感というか幸福感の方が大きくなりませんか?私だけでしょうか?

この時点で、今回の開発における私の満足感は満たされました。だって、今月は5桁も歩いているんですもの!

1日3桁しか歩いていない日なんて知ったこっちゃありません。1ヶ月トータルで歩いた感があれば、今日もう少し走ったら桁が変わるかも!みたいなモチベになりますから。

まとめ

いかがでしたか? Cloud Run は gcloud コマンド一発でデプロイできるので、本当に導入がめっちゃ簡単です。大学院の時にオンプレでいろんなツールをコマンド1行ずつ打ち込んでインフラ構築してからアプリ開発していたのがアホらしいぐらいの時代になりました。(これは大学院時代の自分の技術不足でもあるけど)

もっともっと、クラウドサービスが発展していくことでアプリ開発に集中できるようになるといいですね!

やり残したこと

  • CI/CD 導入
  • 可視化いーーーーぱい!

CI/CD 導入自体は簡単ですが、時間がなくて…
ただ、今後開発を継続的にしていく場合は毎回ビルド&デプロイするの面倒なので、作ろうと思います。

あとは、可視化いーーーーーーーーーーーーーーーーぱい!!!!したいです。

特に、このブログは onemuri.space なので睡眠系の可視化してみたいと思います!!(一歩間違えば私の睡眠は全て筒抜けになりそうw)

ではでは、またの開発・おねむりにて。。。

自己紹介用画像

Riki Akagi

2019年からDeNAで働いています。GCP(CloudSQL・GAE・Cloud Function etc)とGoでAPI開発に勤んでいます。睡眠やエンジニアリングに関することに興味を持って過ごしているのでその情報を皆さんに共有していけたらなと思っています。

自己紹介の詳細