0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-07-16

###謎の業務があった。
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を使うことでカウントしていきます。
最後に成型して終わりです。

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

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?