初心者でもわかるGoogle Apps Script活用のススメ

【GAS】Googleカレンダー編集時に発動するトリガーを使いこなす

カレンダー編集時に発動するカレンダートリガー

2018年2月26日のGoogle Apps Scriptのアップデートでカレンダーの編集を引き金に、Google Apps Scriptのプログラムを実行するトリガーが追加されました。

これでカレンダーを編集時に編集した情報を取得できるぞ!と喜んでいた私ですが、GASでカレンダー関連の処理を行う基礎的なCalendarAppではあまり大したデータが取得できないことが分かり一人落胆したことも記憶に新しい出来事です。

ちなみにカレンダー編集時に発動するようにトリガーを設定する方法を紹介しておこうと思います。

スクリプトエディタの時計マークをクリックしてトリガーウインドウを表示させた後に右下の「+トリガーを追加」ボタンをクリックして下記スクリーンショットのように設定してみましょう。

上記スクリーンショットの左下にある『カレンダーのオーナーのメールアドレス』という部分にカレンダーIDを指定して保存することでIDと一致するカレンダーを編集した時にプログラムが自動的に起動するようになります。

下記コードを使ってカレンダー編集時にどんな情報が取得できるのかを確認してみると、結構がっかりします。

カレンダーIDの確認方法はこちらの記事に記載してあります。

カレンダートリガーで何が取得できるかな?

サンプルコード1
//カレンダー編集時トリガーで取得できるデータ確認
function sampleCode1(e) {
  console.log(e);
}

上記コードの実行結果をログでみてみると・・・

{
 authMode=FULL,
 calendarId=h349j2dgs3rf6pj9f6v318qnqo@group.calendar.google.com,
 triggerUid=332753
}

オブジェクトでこの3つだけが取得されていました。
calendarIdは編集されたカレンダーのID(トリガーに設定したIDと同じ)
triggerUidはカレンダー編集トリガーの一意のトリガーID

こんなものしか取得できません。
なので、どの予定が追加/変更/削除されたのかもわからないのです。
これだけだとあまり使えないですよね。

そこで公式リファレンスをサラサラ~っと読んでいると、

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.

(日本語訳:カレンダーイベントトリガーが使えるようになったよ。このトリガーは上位カレンダーサービスと連携させることで通常の同期プロセスを通して最近編集したカレンダーの内容を取得することができまっせ!)

と書いてあるのを発見しました。
そうなんです。このカレンダートリガーはCalendarAppではなく、上位カレンダーサービス(calendar API)と連携させることで初めて真価を発揮するトリガーなのでした。

とりあえず、このリンク先に少し詳しく書いてありますので、内容ご紹介していきます。

カレンダーイベントトリガー

Calendar triggers fire when a user’s calendar events are updated (created, edited, or deleted).

(日本語訳:カレンダートリガーはユーザーのカレンダーの予定が更新(新規作成、編集、削除)されたときに発動します。)

These triggers do not tell you which event changed or how it changed. Instead, they indicate that your code needs to do an incremental sync operation to pick up recent changes to the calendar. For a full description of this procedure, see the Synchronizing resources guide for the Calendar API.

(日本語訳:このトリガーだけではどの予定が編集されたかやどのように編集されたかを知ることはできません。その代わりに、このトリガーはカレンダーが編集されたのでプログラムがカレンダーに差分同期する必要が有りますよということを教えてくれます。このプロセスの詳しい説明はCalendar APISyncronizing resources guideをご確認下さい。)

To synchronize with Calendar in Apps Script, perform the following steps:

(日本語訳:Google Apps Scriptでカレンダーを同期させるためには、次の手順に従って事前準備をして下さい。)

  1. Enable the Calendar advanced service for the script project. The built-in Calendar service isn’t sufficent for this workflow.

  2. Determine what calendars should be synchronized. For each such calendar, perform an intitial sync operation using the Calendar advanced service’s Events.list() method.

  3. The result of the initial sync returns a nextSyncToken for that calendar. Store this token for later use.

  4. When the Apps Script EventUpdated trigger fires indicating a calendar event change, perform an incremental sync for the affected calendar using the stored nextSyncToken. This is essentially another Events.list() request, but providing the nextSyncToken limits the response to only events that have changed since the last sync.

  5. Examine the response of the sync to learn what events were updated and have your code respond appropriately. For example, you can log the change, update a spreadsheet, send email notices, or take other actions.

  6. Update the nextSyncToken you stored for that calendar with the one returned by the incremental sync request. This forces the next sync operation to only return the most current changes.

(日本語訳)

  1. 対象のGASプロジェクトで上位カレンダーサービスを有効化して下さい。初期のカレンダーサービス(CalendarApp)ではこの機能を利用するには不十分です。
  2. どのカレンダーを同期させるかを決めて下さい。同期させるそれぞれのカレンダーに対して、上位カレンダーサービスのEvents.list()メソッドを使って初回の同期を行って下さい。
  3. 初回の同期の結果、対象のカレンダーに対するnextSyncTokenが返り値として返されますので、このトークンを保存して下さい。
  4. GASのEventUpdated(予定変更)トリガーが発動し、カレンダーの予定が変更されたことが通知されたら、先程保存したnextSyncTokenを使って対象のカレンダーの差分同期を行って下さい。やり方は先程と同じようにEvents.list()メソッドをリクエストするのですが、nextSyncTokenを一緒にリクエストことで前回同期してから変更された予定にだけ限定して返り値を取得します。
  5. どの予定が編集されたのかを知るために、差分同期の返り値を確認してプログラムにその後のプロセスを適切に処理させて下さい。例えば、変更点を記録したり、スプレッドシートを更新したり、Eメールで通知を送ったりというような処理を行って下さい。
  6. 差分同期が終わった後に、nextSyncTokenは差分同期の返り値で得られるnextSyncTokenに更新して上書き保存して下さい。そうすることで、次に同期させるときには最新の変更のみデータを確認できます。

ということみたいなのです。

上記の手順をコードで書いて下記に共有します。とりあえず、下記コードを実行する前に、スクリプトエディタの上部メニューから『リソース』→『Googleの拡張サービス』をクリックしてCalendarAPIを有効化して下さい。『Google Cloud Platform APIダッシュボード』でGoogle Calendar APIを有効化していない人はそれも合わせてここで有効化してください。

他のAPIの有効化方法を説明しているページが別にあるので、リンクを貼っておきます。APIの有効化方法
APIは別ですが、手順はリンク先の方法と同じです。

initialSync

初回の同期をするためのコード
//nextSyncTokenをスクリプトプロパティに保存する
function initialSync() {
  var calendarId = "h349j2dgs3rf6pj9f6v318qnqo@group.calendar.google.com"; //同期させたいカレンダーIDを入れる
  var items = Calendar.Events.list(calendarId);
  var nextSyncToken = items.nextSyncToken;
  var properties = PropertiesService.getScriptProperties();
  properties.setProperty("syncToken", nextSyncToken);
}

上記コードでスクリプトプロパティというところにnextSyncTokenを一時的に保存しています。スクリプトプロパティに保存すると関数の処理が完了してもデータを保持し続けられます。

次のコードは、保存したトークンを利用して差分同期(変更した予定の情報のみ取得)をさせるプログラムです。Calendar APIが有効化できていればinitialSync関数を実行してみましょう

onCalendarEdit

差分同期をするためのコード
//カレンダー編集時に自動的に起動するプログラム
function onCalendarEdit() {
  var calendarId = "h349j2dgs3rf6pj9f6v318qnqo@group.calendar.google.com"; //同期させたいカレンダーIDを入れる
  var properties = PropertiesService.getScriptProperties();
  var nextSyncToken = properties.getProperty("syncToken");
  var optionalArgs = {
    syncToken: nextSyncToken
  };
  var events = Calendar.Events.list(calendarId, optionalArgs);
  console.log(events);
  var nextSyncToken = events["nextSyncToken"];
  properties.setProperty("syncToken", nextSyncToken);
}

onCalendarEdit()をカレンダー編集時に発動するようにトリガーを設定し、カレンダーを更新すると一番最初のコードよりも多くの情報を取得することができ、どの予定がどのように更新されたのかがわかります。
下記が取得できる情報になります。

{
 summary=Made by GAS,
 nextSyncToken=CLjLo66H8N8CELjLo66H8N8CGAU=,
 kind=calendar#events,
 defaultReminders=[],
 accessRole=owner,
 timeZone=America/New_York,
 etag="p32scn8tegvodu0g",
 updated=2019-01-15T15:03:12.195Z,
 items=[
  {
   kind=calendar#event,
   etag="3095129184390000",
   id=3g1i2rbsqc7ugsq3cphbpda92s,
   status=cancelled
  }
 ]
}

よく使う部分のデータの日本語訳をつけておきます。

まとめ

カレンダーイベントトリガーの有効活用の方法をご紹介しました。
このトリガーは上位カレンダーサービスと連携させて初めて輝き出すトリガーということがお分かりいただけたかと思います。
イベントIDが取得できればそこからさらに様々な操作を行うことができるようになりますので、更に幅が広がっていきます。
ぜひ皆さんもカレンダーイベントトリガーを使ったプログラムを開発してみて下さい。

以上、小ネタでした。

Exit mobile version