GASにGoogleカレンダーのイベント変更検知機能が実装されたので試してみた

February 26, 2018
Calendar event triggers are now available. You can use these triggers in conjunction with the Calendar advanced service to discover recently changed calendar events via regular sync operations.

GAS にGoogleカレンダーのイベント変更検知機能が実装されました。
これを使うことで、自分のカレンダーに予定が書き込まれたときだったり、(G Suite利用時の)会議室カレンダーに予定が登録されたとき、なんかにも応用できるかと思います。

サンプルのGASを書いてみたので参考までにどうぞ。

実装

サービスの有効化

まず Caledar Service を使うので有効にしておく。

  1. Resources > Advanced Google ServicesCalendar を ON
  2. Google API ConsoleCalendar API を 有効にする

コード

calendarUpdatedSample() をイベント検知のトリガーにする。
ポイントとしては次の3つになる。

  1. 仮引数の e には変更された予定情報が設定されているわけではない
  2. 登録・変更・削除された予定情報を取得するには syncToken を予定一覧取得APIを投げるときに設定する
  3. syncToken は予定一覧取得APIを投げるとレスポンスに入っている

今回の実装では ScriptPropetiessyncToken を保存するようにしている。
ScriptPropeties にない場合に、予定一覧取得APIを投げて syncToken を取得する形。
※手抜き実装なのでトリガー設定してから2回目以降からしか差分イベントを処理していない

GASのコード
var scriptProperties = PropertiesService.getScriptProperties();
var nextSyncTokenKey = 'NEXT_SYNC_TOKEN';

function calendarUpdatedSample(e) {
  console.info('calendarUpdatedSample() ------------------------------');
  console.log('authMode:%s/calendarId:%s/triggerUid:%s', e.authMode, e.calendarId, e.triggerUid);

  var calendarId = e.calendarId;

  // 予定取得時にsyncTokenを指定して差分イベントを取得
  var optionalArgs = {
    'syncToken': getNextSyncToken(calendarId)
  };
  var events = Calendar.Events.list(calendarId, optionalArgs);  
  console.log('取得した予定数:%s', events.items.length);

  // 差分イベントを処理(サンプルなのここではログ表示しているだけ)
  for (var i = 0; i < events.items.length; i++) {
    var event = events.items[i];
    console.log('event.summary:%s/event.start:%s/event.end:%s/status:%s', event.summary, event.start, event.end, event.status);
  }

  // 今回処理したイベントを対象外とするためsyncTokenを更新
  saveNextSyncToken(events.nextSyncToken);
}

function getNextSyncToken(calendarId) {
  // ScriptPropetiesから取得
  var nextSyncToken = scriptProperties.getProperty(nextSyncTokenKey);
  if (nextSyncToken) {
    console.log('getNextSyncToken(from property):%s', nextSyncToken);
    return nextSyncToken
  }

  // ScriptPropetiesにない場合は、カレンダーから取得
  var events = Calendar.Events.list(calendarId, {'timeMin': (new Date()).toISOString()}); // 最後の予定を取らないといけない?みたいなので timeMinを指定
  nextSyncToken = events.nextSyncToken;
  console.log('getNextSyncToken(from calendar):%s', nextSyncToken);
  return nextSyncToken;
}

function saveNextSyncToken(nextSyncToken) {
  console.log('saveNextSyncToken:%s', nextSyncToken);
  scriptProperties.setProperty(nextSyncTokenKey, nextSyncToken);
}

トリガーの設定

実装が終わったらEdit > Current project's triggers からトリガーを設定する。
From calendar が今回増えたやつで、最後の入力欄にカレンダーIDを入力する。

image.png

実際に動かしてみる

次のような予定を3つ作る

予定A、予定B、予定Cを順に作っていく
image.png

すると次のようなログが表示される。

image.png

1件ずつ予定が取れていることが確認できる。
注意点として、この 予定A を取得した syncToken で再び予定一覧取得APIを投げると、予定A,予定B,予定Cすべての予定が取得される。
これは、syncToken は以降の変更されたイベントを取るようなパラメータであるため。

その他

削除予定

削除した予定の判別は、status: canceled になるので、 status プロパティから判断すれば良い。

参考サイト

Google Calendar events | Event Objects  |  Apps Script  |  Google Developers

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.