おはようございます。まさきんです。
スマホを iPhone から Android に替えました。それを機に、健康データの通り道を1本に寄せています。ところが睡眠だけが、毎朝の通知で「記録元なし」のままでした。原因は OAuth のスコープと同意のやり直しだったので、公式情報と合わせて残しておきます。
※記事公開時点の情報です。最新の条件は公式サイトでご確認ください。
- Google Health API の睡眠は、歩数とは別のスコープ
sleep.readonlyで読みます - スコープを後から足しても、手元のトークンに権限は増えません。同意のやり直しが要ります
- 認可URLに
include_granted_scopes=trueを付けると、前に許可したスコープもまとめて引き継げます - 直ったかどうかは、本番に書かないドライランで先に確かめられます
- 権限を足す前の約1週間分は、僕の場合さかのぼって埋まりませんでした
起きていた症状
僕の健康データは、いまこういう経路で流れています。活動量計から Google の健康アプリ(Google Health)へ。そこから API を通って、自前の記録(健康ログ)へ。この1本です。
歩数などは、先に取り込めていました。ところが睡眠の欄だけが埋まりません。毎朝届く通知には、睡眠のところに「記録元なし」と出ていました。
原因は後から足したスコープ
原因は単純でした。睡眠用の権限を、後から足していたんです。
最初に同意したとき、求めていたのは歩数などのスコープでした。そのあと、コード側に睡眠のスコープを書き足しました。ただ、同意はやり直していませんでした。
Google Health API の公式ドキュメントには、こう書かれています。発行されるアクセストークンに含まれるのは、同意した利用者が許可したスコープだけ。つまりコードに書き足しただけでは、何も変わらないわけです。
Google Health API という名前
Google Health API は、公式に「Fitbit Web API の次世代版」と説明されています。Fitbit や Pixel Watch などのデータを、Google の OAuth 2.0 の上で扱う仕組みです。
旧来の Fitbit Web API には、終了の日程が出ています。サポートの終了が2026年9月30日。API そのものの停止が2026年10月30日です。データを取り続けるには、Google Health API への移行が案内されています。
ただ、同じ案内には注意書きもあります。現時点では新しいプロジェクトの受け入れをしていない、という趣旨です。これから始める場合は、公式の最新の案内を先に見ておくと安心かもしれません。
症状と原因の切り分け
「睡眠だけ取れない」ときに考えられる原因を、表にしておきます。
| 症状 | 考えられる原因 | 確かめる場所 |
|---|---|---|
| 睡眠だけ空になる | 睡眠のスコープに同意していない | トークンに含まれるスコープ |
| 全部の項目が急に取れない | トークンの失効(401) | 公開ステータスと失効条件 |
| 同意はできたのに呼び出しで失敗する | アカウントが Google Health に未連携 | Google Health アプリの設定 |
| 特定の日だけ空になる | その日の記録が Google 側に無い | Google Health アプリの表示 |
僕の場合は、いちばん上の行でした。歩数は取れていたので、トークン自体は生きていたことになります。
全部が止まるほうの話は、別の記事にまとめています。
Googleのリフレッシュトークンが7日で切れる原因は「テスト中」。本番環境への公開手順
公開ステータスが原因の場合は、そちらが近いと思います。
睡眠データのスコープとデータ種別
Google Health API のスコープは、すべて同じ文字列から始まります。https://www.googleapis.com/auth/googlehealth です。この後ろに、データのまとまりごとの名前が付きます。
公式のスコープ一覧とデータ種別のページから、今回関係するものを抜き出しました。
| スコープ(末尾) | 公式の説明 | 読めるデータの例 |
|---|---|---|
.activity_and_fitness.readonly | 活動とフィットネスのデータを見る | 歩数などの活動データ |
.sleep.readonly | 睡眠のデータを見る | 睡眠セッションと睡眠ステージ |
.health_metrics_and_measurements.readonly | 健康指標と測定データを見る | 睡眠中の心拍変動や呼吸数など |
睡眠のデータ種別は sleep で、記録の単位はセッションです。1回の睡眠の中に、ステージの区間が並びます。ステージは LIGHT / DEEP / REM / AWAKE の4種類です。
僕が健康ログに入れているのは、睡眠時間と深い睡眠とレム睡眠です。どれも .sleep.readonly の範囲で読めるデータでした。
一方で、睡眠中の心拍変動や血中酸素は別です。こちらは健康指標のスコープに入っています。「睡眠」という言葉で一括りにすると、ここを取り違えるかもしれません。
公式は、必要なスコープだけを求めるよう案内しています。書き込みのスコープは、データを送るときだけ設定する形です。読むだけの用途なら readonly で足りそうです。
スコープを足すときの OAuth の仕様
手元のリフレッシュトークンを更新しても、権限は増えません。更新で得られるのは、すでに許可された範囲のアクセストークンです。
新しいスコープを使う道は1つです。そのスコープを含めた認可リクエストを送り直す。利用者が同意画面で許可する。そこで初めて、新しい権限が付きます。
増分認可と include_granted_scopes
スコープを後から足すやり方には、公式の名前があります。増分認可(incremental authorization)です。必要になった時点で、追加のスコープを求める考え方ですね。
このとき使うのが include_granted_scopes というパラメータです。値を true にして同意が通ると、新しいアクセストークンは以前のスコープも含みます。公式では、ベストプラクティスとして勧められています。
公式には、まとめられた認可のルールも書かれています。そのリフレッシュトークンを使えば、全スコープ分のアクセストークンが得られます。一方で取り消すと、含まれるスコープが同時にすべて外れます。
つまり睡眠だけを足すときも、歩数の権限を失わずに済むわけです。
リフレッシュトークンの扱い
自動で動かすツールなら、リフレッシュトークンが要ります。認可URLの access_type を offline にするのが、そのための指定です。
公式には、もう1つ大事な記載があります。リフレッシュトークンが返るのは、最初に認可コードを交換したときだけです。2回目以降の同意では、返ってこないことがあります。
確実に新しいものを受け取りたいときは prompt=consent を付けます。同意画面を毎回出す指定です。同意をやり直す場面では、付けておくほうが迷わないかもしれません。
同意をやり直す手順
一般的な流れを、番号でまとめます。Web サーバー向けの OAuth 2.0 の公式手順に沿った形です。
- Google Cloud コンソールで、目的のプロジェクトを開いているか確かめる
- ツール側のスコープ一覧に
.sleep.readonlyを書き足す - 認可URLを組み立てる。
scopeに必要なスコープを並べる - 同じURLに
access_type=offlineとinclude_granted_scopes=trueを付ける - リフレッシュトークンを取り直すなら
prompt=consentも付ける - 本人がブラウザでそのURLを開き、同意画面で内容を読んで許可する
- 戻ってきた認可コードを、トークンに交換する
- 応答の
scopeに、睡眠のスコープが入っているか確かめる - 新しいリフレッシュトークンを保存し、古いものは使わないようにする
8番は、地味ですが大事な手順です。同意画面では、利用者がスコープごとに許可を選べます。
AIに任せた作業と自分でやった操作
今回の下ごしらえは、AI(Claude)に Mac でやってもらいました。スコープを足した認可URLの用意などです。僕がやったのは、同意画面を開いて許可を押すところでした。
| 作業 | 担当 | 理由 |
|---|---|---|
| スコープを足した認可URLの用意 | AI(Claude) | 文字列の組み立てで、間違えやすい |
| 同意画面を開いて許可を押す | 僕 | 本人の意思表示そのものだから |
| 翌朝の通知を見る | 僕 | 最後は自分の目で確かめたい |
同意は、データの持ち主が「渡してよい」と示す操作です。なので、許可を押すところだけは自分でやる形にしています。
毎朝の通知の仕組みは、別の記事に書いています。
朝の身支度中に、AIに1枚の『今日のブリーフィング』を作らせている話
スマホを替えると、こうした連携を一つずつ見直すことになりますね。同じタイミングで、毎月の通信費も見直してみるのはいかがでしょうか。
ドライランで確かめる
同意をやり直したあと、すぐ本番には流しませんでした。まずドライランです。本番の記録には書かずに、取得だけを試す実行ですね。
ドライランで、睡眠のデータが返ってくることを確かめました。そのうえで本番の処理を通しています。健康ログのその日の行に、3つの値が入りました。睡眠時間と深い睡眠、それにレム睡眠です。ここまで見て、完了としました。
ドライランなら、失敗しても何も汚れません。空の値で既存の行を上書きする事故を、先に防げます。
確認の順番は、取得だけの試し実行が先で、本番への書き込みが後です。順番を逆にしないことだけ決めておくと、同意をやり直した直後でも落ち着いて進められると思います。
さかのぼれなかった約1週間
1つだけ、戻らなかったものがあります。権限を足す前の、約1週間分の睡眠です。
この期間は、Google 側にも記録がありませんでした。なので、同意をやり直しても埋まりません。健康ログのその行は、空のままにしています。
空の行に、推測の値を入れることはしませんでした。あとで見返したときに、本物の記録と区別がつかなくなるからです。「無いものは無い」と残すほうが、ログとしては正直かなと思います。
権限が通っても、元の記録が無ければ何も返りません。切り分けるときは、まずアプリ側の表示を見るのが早いと思います。
スコープを足す予定があるなら、足した日をメモしておくのもよさそうです。あとで空の期間を見たときに、理由をすぐ思い出せます。
健康データのスコープは扱いが重い
健康データは、機微な情報です。Google の側でも、扱いは重くなっています。
公式には、Google Health API のスコープの大半が「制限付き」だとあります。一般に公開するアプリは、審査を通す必要があります。審査は2段階で、OAuth アプリの確認と第三者によるセキュリティ評価です。
審査を通していないアプリは、利用者が100人までに制限されます。自分だけで使うツールなら、この上限に届くことはまず無さそうです。ただ、同意の前に未確認アプリの警告が出ることはあります。
よくある失敗・落とし穴
| 失敗 | 起きること | 防ぎ方 |
|---|---|---|
| コードにスコープを足して満足する | トークンの権限は変わらない | 足したら同意をやり直す |
| リフレッシュトークンが返らない | 古いトークンを使い続ける | prompt=consent を付けて取り直す |
| いきなり本番で試す | 空の値で記録を上書きする | 先にドライランを通す |
| 空の期間を推測で埋める | 本物の記録と区別できなくなる | 空のまま残す |
通知に「記録元なし」と出る作りにしておいたのは、助かった点でした。
始める前に確認すること
- 使っている API が Google Health API か旧来の Fitbit Web API か
- コンソールで開いているのが目的のプロジェクトか
- 足したいデータがどのスコープに入っているか
- いまのトークンにどのスコープが含まれているか
- 公開ステータスがテスト中か本番環境か
- 認可URLに include_granted_scopes と access_type を付けたか
- 同意画面を本人が開ける時間を取れるか
- 本番に書かないドライランの手段があるか
公開ステータスが「テスト中」のままだと、リフレッシュトークンは7日で失効します。スコープを足して同意し直しても、この期限は別にかかります。先に公開ステータスを見ておくと、二度手間を避けられるかもしれません。
よくある質問
Q. スコープを足したら、必ず同意し直す必要がありますか?
はい、必要です。トークンに含まれるのは、利用者が許可したスコープだけだからです。コードや設定に足しただけでは、権限は増えません。
Q. リフレッシュトークンを更新すれば、新しいスコープも付きますか?
付きません。更新で得られるのは、すでに許可された範囲のアクセストークンです。新しいスコープは、同意画面で許可して初めて付きます。
Q. 睡眠のデータは、どのスコープで読めますか?
Google Health API では .sleep.readonly です。睡眠セッションと、その中のステージが読めます。睡眠中の心拍変動などは、健康指標のスコープが別に要ります。
Q. 深い睡眠やレム睡眠は取れますか?
公式のデータ種別では、ステージが4種類あります。LIGHT / DEEP / REM / AWAKE です。機種によって対応が違うので、公式の対応機種の表も見ておくと確実です。
Q. 同意する前の日の睡眠は、さかのぼって取れますか?
元の記録が Google 側にあるかどうか次第だと思います。僕の場合は、約1週間分の記録が Google 側にもありませんでした。なので、その期間は空のままです。
Q. 同意の操作まで AI に任せてもよいですか?
僕は任せていません。同意は、データの持ち主本人の意思表示だと考えているからです。認可URLの用意などの下ごしらえまでを、AI に頼む形にしています。
Q. Fitbit Web API のままでも使えますか?
公式では、2026年10月30日に停止すると案内されています。データを取り続けるなら、Google Health API への移行が必要です。新規プロジェクトの受け入れ状況は、公式の案内で確かめてください。
参考にした公式情報
- Google Health API(Google for Developers)
- Google Health API のスコープ(Google for Developers)
- Sleep and recovery データ種別(Google for Developers)
- App verification(Google Health API)
- Troubleshooting(Google Health API)
- ウェブサーバー アプリケーションに OAuth 2.0 を使用する(Google for Developers)
- Google API へのアクセスに OAuth 2.0 を使用する(Google for Developers)
まとめ
睡眠だけが「記録元なし」になる原因は、後から足したスコープでした。足したら、同意をやり直す。わかってしまえば、それだけの話です。
下ごしらえは AI に任せて、許可を押すところは自分でやりました。ドライランで確かめてから、本番に流しています。直ったかどうかの最終確認は、翌朝の通知です。これから見るところですね。
スマホを替えたばかりなら、連携しているアプリの権限を一度だけ眺めてみてください。
回線の乗り換えも考えているなら、MNP乗り換えの手順をまとめた記事もあります。
本記事にはアフィリエイト広告を含みます。当サイトのリンクを経由して商品・サービスへお申し込みいただいた場合、提携先企業から成果報酬を受け取ることがあります。 また、運営者は楽天グループに所属する社員であり、紹介プログラムを通じた報酬を受け取る場合があります。記事内容・評価は広告の有無にかかわらず、運営者の実体験と調査に基づき作成していますが、 上記の関係性をご理解のうえお読みください。詳しくは免責事項・アフィリエイト表記をご覧ください。
楽天モバイルの通信エリア・電波状況について気になることがある方は、公式の電波改善・調査依頼フォームからご相談いただけます。