Help us understand the problem. What is going on with this article?

GASでGoogle Calendarの削除イベントを検知してLINE groupに通知するbotを作った

作った理由

IMG_52A1BD61E625-1.jpeg

僕は大学院で実験系の研究室に所属しています。
大学内の複数の研究室で共同で利用している実験装置があり、半年前までは深夜でも使うことができたのですが、安全管理が厳しくなって8:00-20:00までしか使えなくなってしまいました。
そのため、Google Calendarで管理しているその装置の予約がいつも埋まっていて1週間に2回くらいしか使えないので、みんなの実験が全然進まないという状態でした。

IMG_F52576ADA638-1.jpeg

こんな感じで1週間のほとんどの時間が埋まっているので、全然実験が進まない。。。

これを少しでも解決するために「Google Calendarで装置の予約が削除されたら研究室のグループLINEに通知するLINE Bot」をGASとLINE Botで作成しました。

要件

image.png

  • Google Calendarの実験装置の予約が削除されたらグループLINEに通知する。
  • 予定変更イベントを検知してたら通知の嵐になりそうなので、削除イベントのみ検知する
  • 無料で使えて管理も楽なGASで稼働させる。
  • 卒業するときに引き継ぎしやすいように、研究室のGoogleアカウントでGASを使う
  • 研究室のメーリスに流すより、グループLINEの方が簡単に見れるのでLINE Botを使う
  • 通知内容は、「カレンダーのタイトル」、「カレンダーの開始時間と終了時間」

完成コード

var scriptProperties = PropertiesService.getScriptProperties();
var nextSyncTokenKey = 'NEXT_SYNC_TOKEN';

function calendarUpdatedSample(e) {
  var calendarId = e.calendarId;

  // 予定取得時にsyncTokenを指定して差分イベントを取得
  var optionalArgs = {
    'syncToken': getNextSyncToken(calendarId),
    'showDeleted': true
  };
  var events = Calendar.Events.list(calendarId, optionalArgs);  
  // 差分イベントを処理
  for (var i = 0; i < events.items.length; i++) {
    var event = events.items[i];
    if (event.status === 'cancelled') {
      title = event.summary

      start = new Date(event.start.dateTime)
      start = start.toLocaleDateString() + ' ' + start.toLocaleTimeString();
      end = new Date(event.end.dateTime)
      end = end.toLocaleDateString() + ' ' + end.toLocaleTimeString();
      time = start.replace('JST', '') + '\n~\n' + end.replace('JST', '')

      message = '削除報告\n\n【タイトル】\n' + title + '\n\n【日時】\n' + time 
      sendLineNotification(message, scriptProperties.getProperty('LINE_GROUP_ID'));
    }
  }

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

function getNextSyncToken(calendarId) {
  // ScriptPropetiesから取得
  var nextSyncToken = scriptProperties.getProperty(nextSyncTokenKey);
  if (nextSyncToken) {
    return nextSyncToken
  }

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

function saveNextSyncToken(nextSyncToken) {
  scriptProperties.setProperty(nextSyncTokenKey, nextSyncToken);
}

function sendLineNotification(message, toId) {
  var url = 'https://api.line.me/v2/bot/message/push';
  var LINE_ACCESS_TOKEN = ScriptProperties.getProperty('LINE_ACCESS_TOKEN');

  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ' + LINE_ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'to': toId,
      'messages': [{
        'type': 'text',
        'text': message,
        'notificationDisabled': false
      }],
    }),
    }
  );
}

GASの使い方

GASの基本的な使い方はいろんな記事がググれば出てくるのでそちらを参考にしていただくとして。
今回作ったbotで重要なのはGoogle Calendarの削除イベントを検知するという機能です。

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

こちらの記事に詳細に纏まっていたので参考にしました。
今回は変更イベントは拾わずに、削除イベントのみ検知したかったので、その部分だけ書き換えました。
該当コードはここです。

if (event.status === 'cancelled') {
  var optionalArgs = {
    'syncToken': getNextSyncToken(calendarId),
    'showDeleted': true
  };

こうすることで削除イベントのみを検知して、大量の通知がグループラインに投下されないようにしました。
またoptionにshowDeleted: trueを入れないと削除されたイベントがレスポンスに含まれなくなります。

LINEbotとの連携

LINE botとの連携に関してもかなり記事があります。
グループにメッセージを投稿するのにグループIDを取得する必要がありますが、これは個人アカウントにメッセージを投稿するのとほとんど変わりません。

LINE Messaging APIでgroupIdを取得してPush APIでグループにメッセージを送る

実際に使ってもらってどうだったか

IMG_F64C606A9D66-1.jpeg

  • 他の研究室の予約が消えたときに5分以内に開いた予約を取れるようになった
  • 同じ研究室内でも予約を消したときにいちいち、報告しなくてよくなった

個人開発で人に使ってもらえるレベルのアプリを作ろうとすると、フロント、サーバーとかいろいろ用意する必要が出てきて大変です。
GASとLINE botやslackなどを組み合わせると、手軽に役に立つアプリが作れるので、息抜きに実装してみてください。

Slackに翻訳botを足す
鍵管理システムを作ったら褒められた話
Hangout Chatで空調アンケート集計Botを作ったら色々学べた話

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした