Skip to content

Instantly share code, notes, and snippets.

@tai-sho
Last active May 23, 2024 06:01
Show Gist options
  • Save tai-sho/32ea89f0be8b595f2e616542e39b6d69 to your computer and use it in GitHub Desktop.
Save tai-sho/32ea89f0be8b595f2e616542e39b6d69 to your computer and use it in GitHub Desktop.
Get sleep and workout score of Oura Ring by Google Apps Script and register it to google calendar. Refer: https://tech.affordigitalife.com/oura-api-sleep-log/
/**
* Refer to https://tech.affordigitalife.com/oura-api-sleep-log/
*/
function main(){
const days = 20;
for (let i = 0; i < days; i++) {
let today = new Date()
today.setDate(today.getDate() - i)
let yesterday = new Date()
yesterday.setDate(yesterday.getDate() - (i + 1))
let scheduleCount = getScheduleCounts(today)
console.log(scheduleCount)
if (scheduleCount.workout === 0) {
setWorkoutForDay(today, yesterday)
}
if (scheduleCount.sleep === 0) {
setSleepForDay(today, yesterday)
}
}
}
function connectOuraAPI(api, parameters) {
const token = getProperty('OURA_API_KEY')
const baseUrl = 'https://api.ouraring.com/v2/usercollection/'
let url = `${baseUrl}${api}`
url = setQueryParameter(url, parameters)
let requestOptions = {
muteHttpExceptions: true,
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`
}
}
let res = UrlFetchApp.fetch(url, requestOptions).getContentText()
console.log(res)
return JSON.parse(res)
}
function setQueryParameter(url, parameters) {
url += '?';
for (let parameter in parameters){
url += `${parameter}=${parameters[parameter]}&`
if(Object.keys(parameters).slice(-1)[0] === parameter){
url = url.slice(0, -1)
}
}
return url;
}
function getSleep(start_date, end_date) {
return connectOuraAPI('sleep', {
start_date: formatDate(start_date),
end_date: formatDate(end_date)
})
}
function getSleepScore(start_date, end_date) {
return connectOuraAPI('daily_sleep', {
start_date: formatDate(start_date),
end_date: formatDate(end_date)
})
}
function getWorkout(start_date, end_date) {
return connectOuraAPI('workout', {
start_date: formatDate(start_date),
end_date: formatDate(end_date)
})
}
function addSleepEvent(score, bedtime, awakeTime, description = '') {
const label = getSleepLabel()
addEventForGoogleCalendar(`${label}:${score}`, bedtime, awakeTime, description, 4)
}
function addWorkoutEvent(activity, start, finish, description = '') {
const label = getWorkoutLabel()
addEventForGoogleCalendar(`${label}:${activity}`, start, finish, description, 2)
}
function addEventForGoogleCalendar(title, startDate, endDate, description, color) {
return getCalendar()
.createEvent(title, new Date(startDate), new Date(endDate), {
description: description
})
.setColor(color)
}
function getEventForDayGoogleCalendar(date) {
return getCalendar().getEventsForDay(date)
}
function getCalendar() {
const CALENDAR_ID = getProperty('GOOGLE_CALENDAR_ID_OURA')
return CalendarApp.getCalendarById(CALENDAR_ID)
}
function getScheduleCounts(today) {
let events = getEventForDayGoogleCalendar(today)
let counts = {sleep: 0, workout: 0, date: today}
for (let e of events) {
let title = e.getTitle()
if (title.startsWith(getSleepLabel())) {
counts.sleep++
} else if (title.startsWith(getWorkoutLabel())) {
counts.workout++
}
}
return counts;
}
function setWorkoutForDay(today, yesterday) {
console.log(['workout', today, yesterday]);
let workout = getWorkout(yesterday, today)
if (!workout.data[0]) {
console.log('workout is not found');
return 0;
}
let activity = workout.data[0].activity
for (let w of workout.data){
console.log(w)
addWorkoutEvent(activity, w.start_datetime, w.end_datetime, JSON.stringify(workout))
}
return workout.data.length;
}
function setSleepForDay(today, yesterday) {
console.log(['sleep', today, yesterday]);
let sleep = getSleep(yesterday, today)
let dailySleep = getSleepScore(yesterday, today)
if (!dailySleep.data[0]) {
console.log('sleep is not found');
return 0;
}
let dailySleepScore = dailySleep.data[0].score
for (let s of sleep.data){
console.log(s)
addSleepEvent(dailySleepScore, s.bedtime_start, s.bedtime_end, JSON.stringify(sleep) + '\n' + JSON.stringify(dailySleep))
}
return sleep.data.length;
}
function getSleepLabel() {
return 'Sleep'
}
function getWorkoutLabel() {
return 'Workout'
}
function getProperty(key) {
const prop = PropertiesService.getScriptProperties();
return prop.getProperty(key);
}
function formatDate(date) {
return Utilities.formatDate(date, 'JST', 'yyyy-MM-dd');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment