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
        })

    「削除したイベント」は見えない

    削除したイベントの情報はとれません。

    そのため、「データがないなら消えてる」と判断するか、「全消ししてから保存し直す」などの判断が必要になりそうです。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark