ちょっと一息

ちょっと一息

主に自分の学んだこと、使えそうなことをまとめてます

Google App Scriptを使ってみた~ その2 ~

久しぶりの投稿です

あっという間に新年度になってしまいました。皆さん新年度は何か新しい目標などあるのでしょうか?私はとりあえず、1ヶ月に2記事はブログを更新したいなと思っています(笑)
今月1週目の土曜日は京都はとても天気がよかったので、お花見に行ってきました!去年は道路を移動中に見るだけだったので、今年は少しゆっくり見れて気持ちよかったですよ!
サムネイルはその時撮った桜の写真です(^^)
さて、では本題に入ります。

今回やること

前回の記事はやりたいことが途中で終わってしまっていたのですが、とりあえずslackとGASを連携して、slackで書いた文字をそのままおうむ返しすることができました。
今回は少し修正して、slackからグーグルカレンダーに予定を登録できるようにしてみたいと思います。

やりたかった理由

この機能を作ってみたかった理由ですが、2種類のカレンダーに1回で予定を入れたかったのです。自分用のカレンダーと共有用のカレンダーを使っていて、共有用のカレンダーは複数人の予定が見れて便利なのですが、逆に自分の予定が見辛くなるのでこれまでは自分用と共有用で2回カレンダーに入力していました。
これが案外面倒なので、1回入力したら両方に登録できたら便利だなと思ったのが1番のきっかけです。
他の理由としては、slackを使うことが多いのでslackから登録したかったこと、カレンダーアプリだと連続4日だけの予定とかを登録するのに使い辛かったからです。

作り方

前回までで、slackから文字を送信できているので、CalendarAppを使って登録していきます。
流れとしては、slackに予定を送信 → GASで受け取った文字を処理 → カレンダーに登録 → slackに返事 となるように作ってみます。

作ったもの

カレンダーIDの取得

最初に登録したいカレンダーのIDを取得します。
カレンダーのIDはカレンダーを表示して、以下の写真の場所から確認できます。

f:id:yasumuo:20190415010420p:plain
カレンダーIDの場所(1)

  1. 画像の歯車をクリック
  2. 「設定」をクリック
  3. 「マイカレンダーの設定」から知りたいカレンダー名を選択して「カレンダーの設定」をクリック

f:id:yasumuo:20190415010458p:plain
カレンダーIDの場所(2)

  • 下にスクロールして「カレンダーの統合」の欄にカレンダーのIDがあります

CalendarAppを使ってイベントを登録する

CalendarAppというものを使うことで、簡単にイベントを登録することができます。

  1. 予定を登録したいカレンダーIDを取得したら、getCalendarByIdメソッドを使ってカレンダーを取得します。
  2. createEventメソッドを使うことで予定を登録します。

やることはこの二つだけです!

var myCalendar = CalendarApp.getCalendarById('カレンダーID');
var title = 'CalendarAppテスト';
var startTime = new Date('2019/5/10 09:00:00');
var endTime = new Date('2019/5/10 10:00:00');
var option = {
    description: 'テストテスト',
    location: '京都駅'
}
  
myCalendar.createEvent(title, startTime, endTime, option);

例えば、上記のように書くと5/10 9:00 ~ 10:00で予定を登録できます。
関数にしてGASで実行してみたあとカレンダーを見てみると、

f:id:yasumuo:20190415025618p:plain
登録の例

このように予定が登録できていました!

slackから複数の予定を登録できるようにする

登録はさっきの例でできるようになったので、あとは複数の予定をslackから登録できるようにすればひとまず完成です。

自分で使えるだけで良いので、タイトルや時間はカンマ区切り、イベントは改行で区切ることにしました。
こちらは詳細を割愛しますが、slackから受け取った予定をsplit関数で改行コードとカンマで分けてループでカレンダーに登録しているだけです。

function doPost(e) {
  if(e.parameter.user_name != "slackbot") {
    // カレンダーの取得
    var myCalendar = getMyCalendar();
    
    // 文字からイベント情報の配列を取得
    var EventArray = createEventTextArray(e.parameter.text);
    
    // イベントをカレンダーに登録
    registerEvent(myCalendar, EventArray);
    
    // 返事をslack上に返す
    postSlackMessage(e.parameter.token, e.parameter.channel_name, '登録しときますた! デュフフww');
  }
}

// カレンダーの取得
function getMyCalendar() {
  var myCalendar = CalendarApp.getCalendarById(PropertiesService.getScriptProperties().getProperty('MY_CALENDAR_ID'));
  return myCalendar;
}

// カレンダーに登録
function registerEvent(calendar, eventTextArray) {
  for(var i=0; i < eventTextArray.length; i++) {
    var event = createEventObject(eventTextArray[i]);
    calendar.createEvent(event.title, event.startTime, event.endTime, event.option);
  }
}

// 受け取ったテキストからイベントの配列を作成
function createEventTextArray(postedEventsText) {
  var eventsArray = postedEventsText.split(/\n/);
  return eventsArray;
}

// 受け取った文字列からイベントを作成するオブジェクトを返す
function createEventObject(eventText) {
  var eventDetailArray = eventText.split(',');
  var option = {}
  if(eventDetailArray[3]) {
    option.description = eventDetailArray[3]
  }
  if(eventDetailArray[4]) {
    option.location = eventDetailArray[4]
  }
  return {
    title: eventDetailArray[0],
    startTime: new Date(eventDetailArray[1]),
    endTime: new Date(eventDetailArray[2]),
    option: option
  }
}

function postSlackMessage(web_token, channel, text) {
  var WEB_TOKEN = PropertiesService.getScriptProperties().getProperty('WEB_HOOK_TOKEN');
  if (WEB_TOKEN != web_token) {
    throw new Error('error');
  }
  var token = PropertiesService.getScriptProperties().getProperty('SLACK_TOKEN');
  var slackApp = SlackApp.create(token);
  
  var options = {
    channel: "#"+ channel,
    message: text
  };
   
  slackApp.postMessage(options.channel, options.message);
}

これで準備ができたので、保存してwebアプリケーションとして導入します。

前回作ったslackに返事をしてくれるボットの画像を変更して、返答メッセージも変更して準備ができました!

動作確認

slackに予定を書いて、動作するか試してみます。

f:id:yasumuo:20190415031847p:plain
複数登録

上記のようにタイトルと時間を複数書いて、送信すると...



f:id:yasumuo:20190415032004p:plain
結果1

このようにアプリが返事してくれました!
いい感じにフラウさんが予定を登録してくれたみたいです。このキャラクターはゲームのキャラクターで凄いプログラマーです。(デュフフ フラウとかで検索するとヒットすると思います。)
好きなキャラなのでこんな感じにしてみました(笑)

で、肝心のカレンダーの方を確認してみると...

f:id:yasumuo:20190415032817p:plain
結果2

しっかりカレンダーに登録できました!

まとめ

CalendarAppを使うとカレンダーIDが取得できるととても簡単に予定を登録することができました!
1週間の予定や、繰り返しなどのメソッドもあるようなので、用途に合わせて使えそうです。

この後の拡張としては、

  • 共有カレンダーのIDを取得してカレンダーを取得する
  • 予定を登録する際に共有カレンダーにも登録する

を上記で作ったコードに加えれば、僕の一番やりたかったことができそうなので、時間がある時に作ってみようと思います!

slack, google カレンダー, GASで似たようなことをしてみたい人に少しでも参考になれば幸いです。

次回はまだ決まってないのですが、ReactとFirebaseを使った認証とかをまとめていきたいなと思っています。