見出し画像

Oura Ringから自動で睡眠履歴をGoogle Calendarに同期するGASスクリプト構築

人生初めて睡眠履歴を可視化!!

自動取得された睡眠カレンダー

Oura Ringとは?

Oura Ringとは、フィンランドのSleep Tech企業が開発した睡眠計測用のリング。各種センサーから睡眠をトラッキングすることができます。睡眠時間の計測もありがたいのですが、睡眠のスコアも可視化してくれるので大変素晴らしいリングだと思っています。他にもフィットネス中のアクティビティなども計測してくれるようですが、技術について解像度が高くないのでまたの機会に記載したいと思います。

睡眠計測機器は、

  1. アプリで寝息を計測

  2. 腕時計で計測(apple watch, fitbit, etc)

  3. 指輪で計測(oura ring, soxai ring, etc)

と色々な種類がありますが、個人的に腕時計をつけて寝る習慣がないのでOura Ringを購入。会社でお薦めしてくれる人が多かったのと、睡眠検知の感度が高いことが評判だったことが決めて。

どんな睡眠ログがわかるのか

Ouraアプリで確認できます。web版でも確認できます。

ある日の睡眠スコアを見てみました。79点。可もなく不可もなく。項目別に見てみると、REM睡眠の時間が赤字になっており、足りていない模様。睡眠時間はREM -> Light -> Deepという推移があり、それぞれのバランスや推移数が大事なのかもしれない。言われたところでどう改善するかは難しいと思われるが・・・。


同じ日の睡眠推移を見てみました。深い睡眠(Deep)浅い睡眠(Light)が何時間くらいあって、が時系列でわかります。私は1歳の子供がいるので、夜中に泣いてしまっていると起きてしまっていることがたまにあると思われるのですが、そのせいなのか別の原因なのか午前2時半ごろ一度目覚めているようです。

別の日のログを見ると子供が泣いていたら「あれ?全然起きてないじゃん!?」というのがわかったりもします。

今回作成したGASスクリプト

ほぼこちらのブログを参考にAPIをGAS上にさくっと作成。こちらのブログで大体完成されていましたが、Oura Ringを毎日スマホと同期しているわけではないので、過去1週間分のデータを取得して更新するように変更しました。

その結果、Google Calendar(写真はNotion Calendar)に睡眠履歴が登録されるようになり、「あまり寝ていない」「寝過ぎている」などが一目瞭然でわかるようになりました。夜更かししているかどうかもチェックできるので、睡眠改善に大きく役立てられそうです。純粋に睡眠時間が多ければ良いということでもないので、75点以下だったならばより入眠しやすいような対策を講じる必要があるな〜とかこの日は飲み会があったから睡眠が浅いのか。アルコールは控えようかな。などの考察ができるようになりました。


備考:GASスクリプト

  1. OURAのAPIを取得

  2. Google CalendarのIDを取得

した上で、以下のスクリプトを実行すると同様のカレンダーが生成できます。GASは定期的に実行することができるので、毎週月曜日に実行するなど設定すれば毎回スクリプトを実行しにGASを開かなくても、自動でカレンダー登録を行なってくれます。

function ConnectOuraAPI(api, parameters, token) {
  const baseUrl = 'https://api.ouraring.com/v2/usercollection/'
  let url = `${baseUrl}${api}?`
  for (let parameter in parameters){
    url += `${parameter}=${parameters[parameter]}&`
  }
  url = url.slice(0, -1) // Remove the last '&'
  let requestOptions = { 
    muteHttpExceptions: true,
    method: 'GET', 
    headers: {
      'Authorization': `Bearer ${token}`
    }
  }
  let res = UrlFetchApp.fetch(url, requestOptions).getContentText()
  return JSON.parse(res)
}

function main() {
  let token = '' //ご自身のTokenを入力

  let api = 'sleep'
  let endDate = new Date()
  let startDate = new Date()
  startDate.setDate(startDate.getDate() - 7); // 過去1週間分のデータを取得

  let parameters = {
    start_date: Utilities.formatDate(startDate, 'JST', 'yyyy-MM-dd'),
    end_date: Utilities.formatDate(endDate, 'JST', 'yyyy-MM-dd')
  }
  let sleepData = ConnectOuraAPI(api, parameters, token)
  console.log(sleepData)

  api = 'daily_sleep'
	parameters.start_date = Utilities.formatDate(startDate, 'JST', 'yyyy-MM-dd')
  let dailySleep = ConnectOuraAPI(api, parameters, token)
  console.log(dailySleep)
  let dailySleepScore = dailySleep.data[0].score

  for (let sleep of sleepData.data){
    let sleepScore = sleep.score
    AddEventGoogleCalendar(dailySleepScore, sleep.bedtime_start, sleep.bedtime_end)
  }
} 

function findEvents(calendar, title, startTime, endTime) {
  // 指定された時間範囲でイベントを検索
  const events = calendar.getEvents(startTime, endTime);
  // 指定されたタイトルと一致するイベントをフィルタリング
  return events.filter(event => event.getTitle() === title);
}

function AddEventGoogleCalendar(score, bedtime, awakeTime){
  const CALENDAR_ID = ''; //カレンダーIDを入力
  const calendar = CalendarApp.getCalendarById(CALENDAR_ID)
  const bedtimeDate = new Date(bedtime);
  const awakeTimeDate = new Date(awakeTime);
  const sleepDuration = awakeTimeDate - bedtimeDate; // ミリ秒での睡眠時間
  const hours = Math.floor(sleepDuration / (1000 * 60 * 60)); // 時間に変換
  const minutes = Math.floor((sleepDuration / (1000 * 60)) % 60); // 分に変換

  const eventTitle = `🌙睡眠(${hours}時間${minutes}分)スコア:${score}点`;

// 既存の同様のイベントがないかチェック
  const existingEvents = findEvents(calendar, eventTitle, bedtimeDate, awakeTimeDate);
  if (existingEvents.length === 0) {
    // 同様のイベントがなければ新しく追加
    calendar.createEvent(eventTitle, bedtimeDate, awakeTimeDate);
  }
  }

以上、「Oura Ringから自動で睡眠履歴をGoogle Calendarに同期するGASスクリプト構築」でした!次回は「Readiness」と「Activity」の見方とGAS登録方法についてまとめていきたいと思います。


この記事が気に入ったらサポートをしてみませんか?