Open1
Google Calendar APIの知見
Flutter大学では、Google Calendar APIを使って、slackに毎日8時と18時にその日の予定を投稿している。
ある日、質問zoomの担当講師が代行になった時に、Google Calendarの繰り返し予定の1つのタイトルを変更した。
その時に変更前と変更後の2つ飛んでしまった。
今回要らない部分は省いてるが、レスポンスは下のような感じ。
{
"items": [
{
"id": "6vr9tlqp0tejvq5q59guransg5",
"status": "confirmed",
"created": "2022-08-21T03:36:11.000Z",
"updated": "2022-08-21T03:36:47.383Z",
"summary": "Aoiさんによる質問zoom",
"start": {
"dateTime": "2022-08-21T20:00:00+09:00",
"timeZone": "Asia/Tokyo"
},
"end": {
"dateTime": "2022-08-21T21:00:00+09:00",
"timeZone": "Asia/Tokyo"
},
"recurrence": [
"RRULE:FREQ=WEEKLY;BYDAY=SU"
],
},
{
"id": "6vr9tlqp0tejvq5q59guransg5_20230129T110000Z",
"status": "confirmed",
"created": "2022-08-21T03:36:11.000Z",
"updated": "2023-01-28T07:00:21.842Z",
"summary": "【代行】kosukeさんによる質問zoom",
"start": {
"dateTime": "2023-01-29T20:00:00+09:00",
"timeZone": "Asia/Tokyo"
},
"end": {
"dateTime": "2023-01-29T21:00:00+09:00",
"timeZone": "Asia/Tokyo"
},
"recurringEventId": "6vr9tlqp0tejvq5q59guransg5",
"originalStartTime": {
"dateTime": "2023-01-29T20:00:00+09:00",
"timeZone": "Asia/Tokyo"
},
}
]
}
items配列中に2つの要素が入っていて、変更前が前者。変更後が後者。
1つだけ消したりすると、statusがcancelledになったので判別できてたのだが、「タイトル変更」は対応できていなかった。
ということで、前者と後者の差分を発見し、対応したい。
差分は
"recurringEventId": "6vr9tlqp0tejvq5q59guransg5",
"originalStartTime": {
"dateTime": "2023-01-29T20:00:00+09:00",
"timeZone": "Asia/Tokyo"
},
だとわかった。
https://developers.google.com/calendar/api/v3/reference/events?hl=ja にはeventのrecurringEventIdについて少し書いてあるが、一個消した場合に出るよとかそういうことは書いてない。
けど、まあ多分1個変更した時こうなるのだという結果がわかったので、recurringEventIdがあるとき、その値と同一のidを持つitemを消すみたいな処理をすればいいという結論に至った。
Firebase Functionsの対応コードを後述する。
const json = response.data;
const jsonArray: Array<any> = json.items;
const confirmedJsonArray: Array<any> = jsonArray.filter((item, index, array) => {
return item.status === 'confirmed';
});
// statusがcancelledもしくはconfirmedかに関わらず、既存の定期予定を打ち消すitemにはrecurringEventIdが入っている
const jsonArrayWithRecurringEventId: Array<any> = jsonArray.filter((item, index, array) => {
return item.recurringEventId !== undefined;
});
// recurringEventIdを持つイベント(上書きitem)でconfirmedのイベントを打ち消す
const activeJsonArray: Array<any> = confirmedJsonArray.filter((item, index, array) => {
// jsonArrayWithRecurringEventIdがなければ全部true
if (jsonArrayWithRecurringEventId.length === 0) {
return true;
}
// jsonArrayWithRecurringEventIdの中に、recurringEventIdがitemと一致するものがあれば、そのitemは弾く
return !jsonArrayWithRecurringEventId.some((item2, index2, array2) => {
return item2.recurringEventId === item.id;
});
});
// このあとactiveJsonArrayを使ってslackに投稿する
以上