Google Apps ScriptでSlackにbotを作る(2)

概要

平日のある時間になるとGASがgoogleカレンダーから今日の予定を取得し、ランダムな画像とともにSlackに投稿する。

アジャイル開発のスクラムで言うところのデイリースタンドアップミーティングの際に今日一日の予定を全体で把握する時に使えないかなと思って作りました。

  1. 今日が平日かどうか判定し、平日の場合トリガーが実行される。
  2. GASがグーグルカレンダーから今日の予定を取得する。
  3. GASがスプレッドシートからイメージURLのリストを取得し、ランダムで一つ選ぶ
  4. カレンダーの予定とイメージ画像をSlackにPOSTする。
  5. Slackのチャンネルに投稿される。

完成イメージはこんな感じです。

実写ピカチュウマジかわですね。。。

作成

googleカレンダーまわり

calenderControl.gs

function getCalenderInfo() {
  return CalendarApp.getCalendarById('[gmailアドレス]');
}

function getEvents() {
  return events = getCalenderInfo().getEventsForDay(new Date());
}

単純です。
予定が入っているアカウントのメールアドレスにアクセスして今日の予定を取得します。

スプレッドシートまわり

前回の内容とそんなに変わりません。
ただA列に書いた画像URLリストを丸ごと取得するというだけです。

spreadControl.gs

//A列のデータを配列で取得する
function getSheetColumnValues() {
  var spreadSheet = SpreadsheetApp.openByUrl("[スプレッドシートの共有パス]");
  var sheet = spreadSheet.getSheetByName("imageBank");
  var data = sheet.getRange("A:A").getValues();
  
  var result = new Array();
  
  for each(var value in data) {
    if(value != null && value != "") {
      result.push(value);
    }
  }
  return result;
}

Slackまわり

これも前回と変わっていません。
SlackでIncoming Webhookを設定、URLに向けてPOSTしています。

function testPost() {
  var text = "text";
  postSlack(text);
}

function postSlack(text,url) {
  
  var url="[Incoming Webhookで設定したURL]";
  var jsonData={
    "channel":"botテスト",
    "username":"J.A.R.V.I.S",
    "text":text
  }
  
  var options={
    "method":"POST",
    "headers":{"Content-type":"application/json"},
    "payload":JSON.stringify(jsonData)
  };
  UrlFetchApp.fetch(url,options);
}

この例だと、「#botテスト」というチャンネルがあり、そこに「J.A.R.V.I.S」という名前で投稿するように設定しています。

一つのAppとしてまとめる

main.gs

function announce() {
  var text = modText();
  
  postSlack(text);
}

function timeFormatter(date) {
  return Utilities.formatDate(date, 'JST', 'HH:mm');
}

function modText() {
  
  //カレンダーから今日の予定を取得して成形
  var events = getEvents();
  var eventMsg = [];
  for each(var event in events) {
    var title = event.getTitle();
    var startTime = timeFormatter(event.getStartTime());
    var endTime = timeFormatter(event.getEndTime());
    
    var msg = title + " : " + startTime + "~" + endTime;
    eventMsg.push(msg);
  }
  
  var header = "【Daily StandUp Meeting】 @here \n";
  var image = getRandomImage();
  var introduction = "\nおはようございます。今日の予定は\n";
  var bar1 = "=========================================\n";
  var bar2 = "\n=========================================";
  var conclusion = "\nです。";
  
  var body = header + image + introduction + bar1 + eventMsg.join("\n") + bar2 + conclusion;
  return body;
}

function getRandomImage() {
  var imageArray = getSheetColumnValues();
  var image = imageArray[Math.floor(Math.random() * imageArray.length)];
  
  return image;
}
  • announce()・・・トリガーから起動される関数。Slackに投稿する。
  • timeFormatter(date)・・・スケジュールから取得した予定の時間のフォーマットを設定する関数
  • modText()・・・Slackに投稿する内容を成形している関数。slackはembed型での投稿も有効だが今回は純粋にテキストでの投稿にした。
  • getRandomImage()・・・スプレッドシートから取得した画像リストから一つランダムに選ぶ関数。

トリガー

今回はちょっと特殊なトリガーになってます。
通常のトリガーだと「何時に実行」は指定できても、「平日に」のような設定はできません。
「平日の」「何時に実行」というようなトリガーにするためには、
例えば「平日の」「朝9:30に実行」というトリガーを設定するとしたら以下のようになります。

  1. 通常のトリガーで「8:00~9:00に実行」を設定し、トリガー用の「trigger.gs」を実行する。
  2. 「trigger.gs」で今日が平日かどうかgoogleカレンダーから判定する。
    →休日や祝日の場合は何もせずに終了する。
    →平日の場合は、9:30に「main.gs」を起動させるようなトリガーを新たに設定する。
  3. 設定されたトリガーから、9:30に「main.gs」を実行する。
    その際2で設定した平日起動用のトリガーは削除する。

trigger.gs

//9:30にトリガーを設定
function setTrigger() {
  var triggerDay = new Date();
  triggerDay.setHours(9);
  triggerDay.setMinutes(30);
  
  if(isBusinessDay(triggerDay)) {
    ScriptApp.newTrigger("main").timeBased().at(triggerDay).create();
  }
}

//使い終わったトリガーを削除
function deleteTrigger() {
  var trrigers = ScriptApp.getProjectTriggers();
  for each(var trigger in triggers) {
    if(trigger.getHandleFunction() == "main") {
      ScriptApp.deleteTrigger(trigger);
    }
  }
}

//実行するスクリプト本体
function main() {
  deleteTrigger();
  
  announce();
}

//平日判定
function isBusinessDay(date) {
  if(date.getDay() == 0 || date.getDay() == 6) {
    return false;
  }
  
  var jpCalender = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com');
  if(jpCalender.getEventsForDay(date).length > 0) {
    return false
  }
  return true;
}

ja.japanese#holiday@group.v.calendar.google.comから休日情報を取得できます。

setTrigger()関数は、isBusinessDay(date)で平日判定だった場合にmain()関数を実行するトリガーを新たに作成します。
main()関数でmain.gsのannounce()関数を実行しているのが確認できると思います。

通常のトリガー設定

こんな感じに設定します。
朝8時~9時に「9:30にトリガーを設定する関数(setTrigger)」用のトリガーを設定します。

プログラミングカテゴリの最新記事