カレンダーから予定を取得してslackに投稿させた

###謎の業務があった。
googleカレンダーに登録されている予定を確認し、slackでそれを報告しろという謎業務があった。
めんどくさかった。（自分でカレンダー見ればいいじゃん）

###仕様
・報告するフォーマットは決まってる
・カレンダーに登録されている形式も決まっている
・その日の終わりに次の営業日の予定を報告する。
・次の営業日が土日祝の場合、それは報告をしない。（次の平日の予定を報告する）
・次の営業日に予定が一切入っていない場合、その次の営業日の予定を報告する

例：
現在金曜日とする。
土曜日に「〇fuga」「◇fuga」
月曜日は予定なし
火曜日に「◇hoge」と予定が入っている。
この場合、金曜日の定時付近に「hoge1件」と報告する。


###成果物
余計な情報を出すと大変な目に合うので実際に使用しているコードのままではないです。
gasのcronを使ってsetTriggerを毎日0時～1時に実行させてます。
以下ソース

```
//17時00分にトリガーを設定
function setTrigger() {
  var triggerDay = new Date();
  //土日はセット不要
  if(triggerDay.getDay()===0||triggerDay.getDay()===6){
    return;
  }

  //祝日も不要
  if(isHoliday(triggerDay)){
    return;
  }
  
  triggerDay.setHours(17);
  triggerDay.setMinutes(00);
  ScriptApp.newTrigger("main").timeBased().at(triggerDay).create();
}

//その日のトリガーを削除(消さないと残る)
function deleteTrigger() {
  var triggers = ScriptApp.getProjectTriggers();
  for(var i=0; i < triggers.length; i++) {
    if (triggers[i].getHandlerFunction() == "main") {
      ScriptApp.deleteTrigger(triggers[i]);
    }
  }
}

//祝日判定
function isHoliday(today){ 
  const calendars = CalendarApp.getCalendarsByName('日本の祝日');
  const count = calendars[0].getEventsForDay(today).length;
  return count === 1;
}

//本体
function main() {
  deleteTrigger();
  postSlackMessageNextDayPlan();
}

//
function postSlackMessageNextDayPlan() {
  const hoge_Cals = CalendarApp.getCalendarById('');
  var countA = countB = countC = countD = 0;
  var data = new Date();  
  var Weeks = [ "日", "月", "火", "水", "木", "金", "土" ];
  var hoge_Events = [];

  var i=0;
  while(true){
    i++;
    data.setDate(data.getDate() + i);
    //土日の場合
    if(data.getDay()===0||data.getDay()===6){
      continue;
    }

    //祝日も不要
    if(isHoliday(data)){
      continue;
    }

    hoge_Events = hoge_Cals.getEventsForDay(data);
    if(hoge_Events.length > 0){
      break;
    }
  }

  var message = 'hoge \n'
  message += '【fuga】' + (data.getMonth() + 1) + '/' + data.getDate() + '(' + Weeks[data.getDay()] + ')' + '稼働予定\n';  
  
  
  for(var i=0;i<hoge_Events.length;i++){
    var title = hoge_Events[i].getTitle();
    if(title.match("×")){
      continue;
    }
    if(title.match("hoge")){
      continue;
    }
    if(title.match("A")){
      countA++;
    }else if(title.match("B")){
      countB++;
    }else if(title.match("C")){
      countC++;
    }else if(title.match("D")){
      countD++;
    }else if(title.match("E")){
      countD++;
    }else if(title.match("F")){
      countD++;
    }
  }
  
  message += 'A'
  + countA + '\n' 
  + 'B ' + countB + '名\n' 
  + 'C' + countC + '名\n' 
  + 'D' + countD + '名\n' 
  + 'hogehoge\n';
  
  // トークン
  const slackApp = SlackApp.create("");
  const channelId = "";
  const options = {
    as_user: true
  }
  
  slackApp.postMessage(channelId, message, options);
}
```


###ざっくり解説
gasのcronは結構ざっくりした設定しか出来ないみたいです。
そのため、setTriggerを定義しました。
これを使用することで細かな設定のcronが出来ます。
今回は土日祝日以外の17時00分にセットするようにしました。

mainが特定の時間に発火され、postSlackMessageNextDayPlanを呼び出します。
カレンダーからイベントを取得します。
その後、イベントのタイトルに対してmatchを使うことでカウントしていきます。
最後に成型して終わりです。

###あとがき
もうちょっときれいに書くべき点がいくつか見えるんですが、まぁいっかと手抜きしてます。

若干考慮漏れもあるんですが、この業務の仕様が怪しいため運用でカバーしています。
運用状況としては
１、botから私自身へDMを飛ばす。
２、目視で確認後、実際にチャンネルに投稿するかを判断し、適宜対応。
上記の状態です。
目視がめんどいので完全に自動化したい。
（臨時休業時にカレンダーどうするのかとか、その辺の仕様が詰まれば恐らく完全bot化できるんですけども。）