GoogleカレンダーAPIのWatchで、変更のあったカレンダーのイベント情報を取得する
Googleカレンダーに登録されたイベントをSlackやLINEで通知するシステムを作成するための覚書です。GoogleカレンダーのJS SDKを使用してWebhook APIを登録し、イベント情報を取得します。nestjsを使用してAPIを作成し、GETリクエストを使用してイベント情報を取得します。注意点として、削除したイベントの情報は取得できないため、データがなければイベントが削除されたと判断する必要があります。また、イベントの件数が多い場合はnextSyncTokenを使用して取得します。
目次
Googleカレンダーに登録されたイベントを中心にしたシステムを作ろうとしたので、その際の覚書です。
やりたかったこと
「カレンダーの追加・変更を、SlackやLINEで通知する仕組み」に挑戦していました。
上手く作れれば、操作する側はGoogleカレンダーを操作するだけで連絡等の作業を自動化できますし、最終的にはGoogleカレンダーをHeadless DB的に使うなんてこともできるかなと考えたのが背景です。
GoogleカレンダーにWebhook APIを登録する
「サービス上のイベント・出来事を外のシステムに通知する」となれば、いつものWebhook連携です。
GoogleカレンダーのJS SDKでは、events.watch
でAPIを登録できます。
const calendar = google.calendar({
version: "v3",
auth: auth
});
const result = await calendar.events.watch({
calendarId:'[email protected]',
requestBody: {
id: 'local-debug-1',
type: 'webhook',
address: 'https://xxxxx.jp.ngrok.io/api/webhook',
expiration: `${dayjs().add(1, 'hours').unix() * 1000}`
}
})
有効期限があるので、一度設定したらずっと使えるわけではない点に注意しましょう。
実際にシステムとして動かす際は、expireする前にAPIを再登録する仕組みが必要です。
WebhookのAPIでカレンダー情報を取得する
Webhook API側でデータを取得する方法です。今回はnestjsを利用してAPIを作りました。
import { Headers, Controller, Get, Post } from '@nestjs/common';
import axios from 'axios';
import { googleAuth } from './googleapi';
@Controller()
export class AppController {
@Post('/webhook')
async webhook(@Headers() headers) {
// 呼び出すAPIのURL
const resourceUri = headers['x-goog-resource-uri']
// アクセストークン
const accessToken = await googleAuth.getAccessToken()
// データ取得
const result = await axios.get(resourceUri, {
headers: {
'Authorization': `Bearer ${accessToken}`
}
})
// 結果
console.log(JSON.stringify(result.data.items, null, 2))
}
}
イベント情報の中身は、リクエストヘッダーのx-goog-resource-uri
に設定されたURLに対してGETリクエストを投げて取得します。その際認証が必要ですので、getAccessToken
でBASIC認証などのキーを取得しましょう。
注意点
「変更したイベントだけ見える」・・・わけではない
該当カレンダーのイベントリストが返ってきます。
そのため、「対象カレンダーのイベントListが取れる」程度の認識がよさそうです。
件数が多い場合は、nextSyncToken
を利用します。
await google.calendar({
version:'v3',
auth: googleAuth
}).events.list({
syncToken: result.data.nextSyncToken
})
「削除したイベント」は見えない
削除したイベントの情報はとれません。
そのため、「データがないなら消えてる」と判断するか、「全消ししてから保存し直す」などの判断が必要になりそうです。