GCP (Google Could Platform)JavaScriptNestjs

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:'xxxxx@group.calendar.google.com',
      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
    })

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

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

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

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts