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 を使うので有効にしておく。
- 
Resources > Advanced Google ServicesでCalendarを ON
- 
Google API ConsoleでCalendar APIを 有効にする
コード
calendarUpdatedSample() をイベント検知のトリガーにする。
ポイントとしては次の3つになる。
- 仮引数の eには変更された予定情報が設定されているわけではない
- 登録・変更・削除された予定情報を取得するには syncTokenを予定一覧取得APIを投げるときに設定する
- 
syncTokenは予定一覧取得APIを投げるとレスポンスに入っている
今回の実装では ScriptPropeties に syncToken を保存するようにしている。
ScriptPropeties にない場合に、予定一覧取得APIを投げて syncToken を取得する形。
※手抜き実装なのでトリガー設定してから2回目以降からしか差分イベントを処理していない
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を入力する。
実際に動かしてみる
次のような予定を3つ作る
すると次のようなログが表示される。
1件ずつ予定が取れていることが確認できる。
注意点として、この 予定A を取得した syncToken で再び予定一覧取得APIを投げると、予定A,予定B,予定Cすべての予定が取得される。
これは、syncToken は以降の変更されたイベントを取るようなパラメータであるため。
その他
削除予定
削除した予定の判別は、status: cancelled になるので、 status プロパティから判断すれば良い。
参考サイト
Google Calendar events | Event Objects | Apps Script | Google Developers


