-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCode.ts
More file actions
122 lines (105 loc) · 4.03 KB
/
Code.ts
File metadata and controls
122 lines (105 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// =====================
// Configuration
// =====================
// String appended to event descriptions, used to identify peloCal events
const EVENT_DESCRIPTION_SIGNATURE = '(Automatically created by peloCal)';
// Add a location to events (leave string empty for no location)
const EVENT_LOCATION = 'Peloton';
// Tag name used on Google Calendar events to store Peloton IDs
const EVENT_ID_TAG = 'pelotonId';
// Time (in minutes) a reminder will be created before each event. Set to 0 for no reminders
const REMINDER_MINUTES_BEFORE = 5;
// Exact name of the Google Calendar in which events will be created. Leave blank for default calendar
const TARGET_CALENDAR_NAME = '';
// =====================
// Function to select under "Choose which function to run" in Triggers
function run() {
main();
}
function createEventFromRide(
calendar: GoogleAppsScript.Calendar.Calendar,
ride
): GoogleAppsScript.Calendar.CalendarEvent {
console.log(`Adding new event from ride ${ride.title} (${ride.id})`);
const eventTitle = `${ride.title} with ${ride.instructorName}`;
const startDate = new Date(ride.startTime * 1000);
const newEvent = calendar.createEvent(
eventTitle,
startDate,
new Date(startDate.getTime() + ride.duration * 1000),
{
description: `${ride.description}\n\n${EVENT_DESCRIPTION_SIGNATURE}`,
location: `${EVENT_LOCATION}`
}
);
if (REMINDER_MINUTES_BEFORE) {
newEvent.addPopupReminder(REMINDER_MINUTES_BEFORE);
}
newEvent.setTag(EVENT_ID_TAG, ride.id);
console.log(`Added ${eventTitle} at ${startDate.toUTCString()}`);
return newEvent;
}
function main() {
const scriptProps = PropertiesService.getScriptProperties();
let {
pelotonUsername,
pelotonPassword,
sessionId,
} = scriptProps.getProperties();
if (!sessionId || !isSessionValid(sessionId)) {
sessionId = loginToPeloton(pelotonUsername, pelotonPassword);
scriptProps.setProperty('sessionId', sessionId);
}
const scheduledRides = fetchReservations(sessionId)
.map(({ peloton_id }) => fetchPeloton(sessionId, peloton_id))
.map(peloton => {
const { ride } = fetchRide(sessionId, peloton.ride_id);
// Session rides' scheduled_start_times are one minute early, so prefer pedaling_start_time
const startTime = peloton.is_session
? peloton.pedaling_start_time
: peloton.scheduled_start_time;
return {
startTime,
id: peloton.id,
description: ride.description,
duration: ride.duration,
instructorName: ride.instructor.name,
title: ride.title,
};
});
const scheduledRideIds = scheduledRides.map(ride => ride.id);
// get existing peloCal events from Google Calendar
const now = new Date();
const endDate = new Date();
endDate.setDate(endDate.getDate() + 14);
const existingRideIds = new Set();
const calendar = TARGET_CALENDAR_NAME
? CalendarApp.getCalendarsByName(TARGET_CALENDAR_NAME)[0]
: CalendarApp.getDefaultCalendar();
calendar
.getEvents(now, endDate, { search: EVENT_DESCRIPTION_SIGNATURE })
.forEach(event => {
const id = event.getTag(EVENT_ID_TAG);
const title = event.getTitle();
const startTime = event.getStartTime();
// delete calendar events for rides no longer on the schedule
// check to see if the current start time is after current time
// ... since getEvents() will return events that start during
// ... the given time range, ends during the time range, or
// ... encompasses the time range. If the Apps Script trigger is set
// ... to a shorter time (5-30 minutes) it will remove scheduled
// ... workouts that have just started but not ended.
if (!scheduledRideIds.includes(id) && (now < startTime)) {
console.log(`Deleting event for ride ${title} (${id}).`);
event.deleteEvent();
return;
}
existingRideIds.add(id);
});
// add new rides to Google Calendar
scheduledRides.forEach(ride => {
if (!existingRideIds.has(ride.id)) {
createEventFromRide(calendar, ride);
}
});
}