カレンダー編集時に発動するカレンダートリガー
2018年2月26日のGoogle Apps Scriptのアップデートでカレンダーの編集を引き金に、Google Apps Scriptのプログラムを実行するトリガーが追加されました。
これでカレンダーを編集時に編集した情報を取得できるぞ!と喜んでいた私ですが、GASでカレンダー関連の処理を行う基礎的なCalendarAppではあまり大したデータが取得できないことが分かり一人落胆したことも記憶に新しい出来事です。
ちなみにカレンダー編集時に発動するようにトリガーを設定する方法を紹介しておこうと思います。
スクリプトエディタの時計マークをクリックしてトリガーウインドウを表示させた後に右下の「+トリガーを追加」ボタンをクリックして下記スクリーンショットのように設定してみましょう。
上記スクリーンショットの左下にある『カレンダーのオーナーのメールアドレス』という部分にカレンダーIDを指定して保存することでIDと一致するカレンダーを編集した時にプログラムが自動的に起動するようになります。
下記コードを使ってカレンダー編集時にどんな情報が取得できるのかを確認してみると、結構がっかりします。
カレンダーIDの確認方法はこちらの記事に記載してあります。
カレンダートリガーで何が取得できるかな?
//カレンダー編集時トリガーで取得できるデータ確認 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 APIのSyncronizing resources guideをご確認下さい。)
To synchronize with Calendar in Apps Script, perform the following steps:
(日本語訳:Google Apps Scriptでカレンダーを同期させるためには、次の手順に従って事前準備をして下さい。)
-
Enable the Calendar advanced service for the script project. The built-in Calendar service isn’t sufficent for this workflow.
-
Determine what calendars should be synchronized. For each such calendar, perform an intitial sync operation using the Calendar advanced service’s Events.list() method.
-
The result of the initial sync returns a
nextSyncToken
for that calendar. Store this token for later use. -
When the Apps Script
EventUpdated
trigger fires indicating a calendar event change, perform an incremental sync for the affected calendar using the storednextSyncToken
. This is essentially another Events.list() request, but providing thenextSyncToken
limits the response to only events that have changed since the last sync. -
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.
-
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.
(日本語訳)
- 対象のGASプロジェクトで上位カレンダーサービスを有効化して下さい。初期のカレンダーサービス(CalendarApp)ではこの機能を利用するには不十分です。
- どのカレンダーを同期させるかを決めて下さい。同期させるそれぞれのカレンダーに対して、上位カレンダーサービスのEvents.list()メソッドを使って初回の同期を行って下さい。
- 初回の同期の結果、対象のカレンダーに対する
nextSyncToken
が返り値として返されますので、このトークンを保存して下さい。 - GASの
EventUpdated
(予定変更)トリガーが発動し、カレンダーの予定が変更されたことが通知されたら、先程保存したnextSyncToken
を使って対象のカレンダーの差分同期を行って下さい。やり方は先程と同じようにEvents.list()メソッドをリクエストするのですが、nextSyncTokenを
一緒にリクエストことで前回同期してから変更された予定にだけ限定して返り値を取得します。 - どの予定が編集されたのかを知るために、差分同期の返り値を確認してプログラムにその後のプロセスを適切に処理させて下さい。例えば、変更点を記録したり、スプレッドシートを更新したり、Eメールで通知を送ったりというような処理を行って下さい。
- 差分同期が終わった後に、
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 } ] }
よく使う部分のデータの日本語訳をつけておきます。
- summary = カレンダー名
- nextSyncToken = トークン
- updated = 更新日時
- items配列内id = イベントID(予定ID)
- items配列内summary = 予定名
- items配列内status = 編集区分(confirmed = 新規作成 or 予定編集、cancelled = 予定削除)
まとめ
カレンダーイベントトリガーの有効活用の方法をご紹介しました。
このトリガーは上位カレンダーサービスと連携させて初めて輝き出すトリガーということがお分かりいただけたかと思います。
イベントIDが取得できればそこからさらに様々な操作を行うことができるようになりますので、更に幅が広がっていきます。
ぜひ皆さんもカレンダーイベントトリガーを使ったプログラムを開発してみて下さい。
以上、小ネタでした。