-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimetree.gs
More file actions
131 lines (115 loc) · 3.66 KB
/
Copy pathtimetree.gs
File metadata and controls
131 lines (115 loc) · 3.66 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
123
124
125
126
127
128
129
130
131
// https://for-dummies.net/gas-noobs/how-to-use-oncalendar-change-triggers-for-gas/
const properties = PropertiesService.getUserProperties();
const getSync = async () => {
const calendarId = "primary";
const syncToken = properties.getProperty("nextSyncToken");
const options = {
singleEvents: true,
syncToken: syncToken
};
// Google Calendar APIを用いて予定の一覧を取得する
try {
events = await Calendar.Events.list(calendarId, options);
console.log(events);
} catch (e) {
throw e;
}
if (events.items && events.items.length === 0) {
console.info("予定が見つかりませんでした");
return;
}
// 前回のCalendar.Events.list()実行時との予定一覧のうち、更新されたもののみの一覧が取得できる
properties.setProperty("nextSyncToken", events.nextSyncToken);
const event = events.items[0];
try {
// event.descriptionがある場合に遷移。
const isPrivate = event.description.includes("private");
if (isPrivate) {
console.info("非公開の予定です");
return;
}
} catch {
// event.descriptionがない場合に遷移。
}
try {
if (event.status === "confirmed") {
await postToTimeTree(events.items[0]);
}
} catch (e) {
throw e;
} finally {
console.log("end");
}
}
// https://developers.timetreeapp.com/ja/docs/api/oauth-app#create-an-event
const postToTimeTree = async (event) => {
const accessToken = properties.getProperty("accessToken");
const calendarId = properties.getProperty("calendarId");
const endPoint = `https://timetreeapis.com/calendars/${calendarId}/events`;
const body = {
data: {
attributes: {
category: "schedule",
title: event.summary,
// all_day: date形式でなくdateTime形式ならば、終日ではない
all_day: event.start.dateTime ? false : true,
// start_at: date形式でなくdateTime形式ならば、日時を返す
start_at: event.start.dateTime ? event.start.dateTime : event.start.date,
// end_at: date形式でなくdateTime形式ならば、日時を返す。Sカレンダーの仕様上終日の場合1日遅れるので(e.g. 3/1で終日登録 => end at dateは3/2)1日戻してリターンする
end_at: event.end.dateTime ? event.end.dateTime : getBeforeOneDate(event.end.date),
},
relationships: {
label: {
data: {
id: "1",
type: "label"
}
}
}
}
};
const options = {
method : "post",
contentType: "application/json",
headers: {
Authorization: `Bearer ${accessToken}`,
},
payload : JSON.stringify(body)
};
try {
await UrlFetchApp.fetch(endPoint, options);
} catch (e) {
throw e;
} finally {
console.log("end");
}
}
const getBeforeOneDate = (date) => {
const dt = new Date(date);
dt.setDate(dt.getDate() - 1);
const y = dt.getFullYear();
const m = `00${dt.getMonth() + 1}`.slice(-2);
const d = `00${dt.getDate()}`.slice(-2);
return (`${y}-${m}-${d}`);
}
const initialSync = async () => {
let events;
const calendarId = "primary";
const options = {
timeMin: (new Date()).toISOString(),
singleEvents: true,
};
// Google Calendar APIを用いて予定の一覧を取得する
try {
events = await Calendar.Events.list(calendarId, options);
} catch (e) {
console.warn(e);
}
if (events.items && events.items.length === 0) {
console.info("予定が見つかりませんでした");
return;
}
// 取得できた予定の配列
console.log(events.items);
properties.setProperty("nextSyncToken", events.nextSyncToken);
}