みなさん、こんにちは!うえはら(@tifoso_str)です。
今回のシリーズでは、Google Apps ScriptでGoogleカレンダーで予定が更新されたときに、チャットワークへ通知することをお伝えしています。
前回はその中で、Google Apps Scriptでトリガーが実行された時から1ヶ月以内のイベントを取り出し、各イベントの日時、イベント名、更新日時を配列に入れる部分を解説しました。
今回は、更新日時の配列から最大値を取り出し、その値で更新されたイベントか特定してチャットワークへ送信する部分を解説します。
更新日時の配列の中で最大値を取得する
複数の数値から最大値を取得するにはMathオブジェクトのmaxメソッドを使用しますが、数値の集合を全て引数で与える必要があり、通常では配列を指定できません。
そのため、applyメソッドを使用して、配列を引数化してmaxメソッドが使用できるようにします。
書式は下のようになります。
詳しく説明すると長くなりテーマから離れるので、今回は配列から最大値を取得するときはこうやるものとして、覚えてください!
最小値の場合は下記のようになります。
前回のスクリプトで変数 「arrUpDate」に更新日時を配列として入れているので、最大値を取得するのは下記となります。
var maxDay = Math.max.apply(null,arrUpDate);
これで、更新日時の配列の中から最大値(現在に一番近い値)が取り出せました。
配列の中の最大値のインデックスを取得する
配列のインデックスを取得するにはindexOfメソッドを使用します。
書式は下のようになります。
indexOfメソッドについては、下記記事をご覧下さい。
前回分と最大値を取得する部分を含めるとスクリプトは下記のようになります。
function Calendar(e) { var calendarId = e.calendarId; var nowDate = new Date(); var monthLater = new Date(); monthLater.setMonth(nowDate.getMonth()+1);//1ヵ月後の日時 var events = CalendarApp.getCalendarById(calendarId).getEvents(nowDate, monthLater); var arrDate = [];//日付用の配列 var arrTitle = [];//イベント名の配列 var arrUpDate = [];//更新日時の配列 for (var i = 0;i<events.length;i++){//各配列に追加 arrDate.push(events[i].getStartTime()); arrTitle.push(events[i].getTitle()); arrUpDate.push(events[i].getLastUpdated().getTime()); } var maxDay = Math.max.apply(null,arrUpDate);//更新日時の最大値の取得 var index = arrUpDate.indexOf(maxDay);//インデックスの取得 Logger.log('タイトル%s',arrTitle[index]); Logger.log('日付%s',arrDate[index]); Logger.log('更新日時%s',maxDay); }
カレンダーを更新して、ログを確認すると、下記のようになると思います。
イベント名、日付の配列にも同じ順番で追加されているので、更新日時のインデックス番号がわかればそれぞれのイベント名と日付も取得できます。
日付のフォーマット変更
先ほどのログで、イベントの日付が確認できますが、このままでは見にくいので、フォーマットを変更したいと思います。
下記、関数を追加して日付を「○月○日」の形に変更できるようにします。
function _MMdd(date){ return Utilities.formatDate(date,'JST','M月d日'); }
Utilities.formatDateについては、下記をご覧下さい。
先ほどのスクリプトで、日付の部分を下のように変更します。
Logger.log(_MMdd(arrDate[index]));
そうすると、下記のようになります。
更新時間と関数実行時間の比較
いよいよ最後です。
配列から取得した更新時間の最大値と関数実行時間を比較します。
更新時間はミリ秒で配列に追加しているので「1000*10」をプラスした値と比較します。
if (maxDay+1000*10 > nowDate.getTime()){ sendMessageCW(body); }
比較自体はif文を使うだけです。条件に合えば、チャットワークへ送信する関数に、送信する文章を渡してあげます。
これまでのシリーズを併せると、下記のようになります。
function Calendar(e) { var calendarId = e.calendarId; var nowDate = new Date(); var monthLater = new Date(); monthLater.setMonth(nowDate.getMonth()+1);//1ヵ月後の日時 var events = CalendarApp.getCalendarById(calendarId).getEvents(nowDate, monthLater); var arrDate = [];//日付用の配列 var arrTitle = [];//イベント名の配列 var arrUpDate = [];//更新日時の配列 for (var i = 0;i<events.length;i++){ arrDate.push(events[i].getStartTime()); arrTitle.push(events[i].getTitle()); arrUpDate.push(events[i].getLastUpdated().getTime()); } var maxDay = Math.max.apply(null,arrUpDate); var index = arrUpDate.indexOf(maxDay); var body = _MMdd(arrDate[index]) + 'の予定「' + arrTitle[index] + '」が更新されました。'; //今の時間 更新時間+10秒 if (maxDay+1000*10 > nowDate.getTime()){ sendMessageCW(body); } } function _MMdd(date){ return Utilities.formatDate(date,'JST','M月d日'); } function sendMessageCW(strbody){ var client = ChatWorkClient.factory({token: 'XXXXXXXXXXXXXXXXXXXX'}); //チャットワークAPI client.sendMessage({ room_id:000000000, //ルームID body: strbody }); }
チャットワークへの送信は、「ChatWorkClient for Google Apps Script」ライブラリを使用しています。
まとめ
Google Apps ScriptでGoogleカレンダーが更新された時にイベントを特定してチャットワークへ送信する方法をお伝えしてきましたが、いかがだったでしょうか?
更新されたイベントを特定する部分で、私もずいぶん悩みました。
イベントオブジェクトでもう少し情報が得られれば、簡単になるんですけどね~。
Google Apps Scriptは常に進化しているので、仕様が変更されることを期待したいと思います!
おまけ
Google拡張サービスを利用すると、イベントが削除されたことも判別できます。
Google Calendar eventsやAdvanced Calendar Serviceが参考になります。
これだけで物足りない方は、ぜひ挑戦してみてください!