【業務効率化】シフト勤務者の味方!slackに翌日の勤務スケジュールを通知させよう

slack x GAS

今回は翌日の勤務スケジュールを毎日slackに通知させるツールを紹介します。

作成した背景

現在、私の本業シフト勤務中であり、日によって出勤時間や退勤時間が異なります。毎日Googleカレンダーをチェックするのも良いですが、「パッとひと目で翌日の勤務スケジュールが分かればいいな」と感じました。

更に、家庭内slackに通知すれば妻にも自分の勤務スケジュールを逐一把握してもらうことができます。

以上の理由から、開発するに至りました。

難易度

★★★★☆

使用する技術

  • JavaScriptにおける多次元配列からの値の取り出し
  • for文を用いたループ処理
  • switch文とcase文を用いた条件分岐

要件(仕様)

今回の要件は次の通りです。

  • スプレッドシートに記載した翌日の勤務スケジュールを毎日決まった時間に通知する
  • 通知の際、slackに翌日の日付を表示させる

準備

今回もslackの「Incoming Webhook」を使用します。

チャンネルのインテグレーションにアプリを追加から「Incoming Webhook」を追加してください。

手順はこちらの記事で紹介しています。

ソースコード

今回もソースコードから紹介します。

function sendToSlack(body, channel) {
  var postUrl  = "webhockのURL";
  var data = { "channel" : channel, "username" : "明日のシフトをお知らせします", "text" : body};
  var payload = JSON.stringify(data);
  var options = {
    "method" : "POST",
    "contentType" : "application/json",
    "payload" : payload
  };
  var response = UrlFetchApp.fetch(postUrl, options);
}

function tommorowShiftNotification() {

  var tomorrow = new Date(new Date().toDateString()); 
  tomorrow.setDate(tomorrow.getDate() + 1);
  var yearNum = tomorrow.getFullYear(); 
  var monthNum = tomorrow.getMonth() + 1 ; 
  var dayNum = tomorrow.getDate(); 
  var dayArr = ['日', '月', '火', '水', '木', '金', '土'] 
  var day = dayArr[tomorrow.getDay()];  
  var tomorrowString = String(yearNum) + "/" 
                    + String(monthNum) + "/"
                    + String(dayNum) + "" 
                    + "("+ String(day) + ")";
  var tommorowDay = "明日の日付:"+ tomorrowString 

  var shifts = SpreadsheetApp.openById("スプレッドシートのID").getSheets()[シート番号];
  var schedules = shifts.getRange("xx:xx").getValues();  

  for (let i = 0; i < schedules.length; i ++) {
    if (schedules[i][0].getTime() == tomorrow.getTime()){
      switch (schedules[i][1]) {
        case "9:00-18:00":
          var shift = "<@slackのID> :9:00-18:00";
          summary(shift)
          break;
        case "10:00-19:00":
          var shift = "<@slackのID> :10:00-19:00";
          summary(shift)
          break;
        case "11:00-20:00":
          var shift = "<@slackのID> :11:00-20:00";
          summary(shift)
          break;
        case "13:00-22:00":
          var shift = "<@slackのID> :13:00-22:00";
          summary(shift)
          break;
        case "休み":
          var shift = "<@slackのID> :休み";
          summary(shift)
          break;
      } 
    }else{
      // バグがあった際、発見しやすくするために残しておく
      console.log("日付が一致しなかったインデックス")
      console.log(i)
    }
  }

  function summary(shift){
    var body = tommorowDay + "\n" + shift;
    sendToSlack(body, "#チャンネル名");
  }
}

通知される形

このソースコードを使用すると次のような形で通知されます。

では、ソースコードを解説していきます!

読み込みの順番

このソースコードでは、次の順で関数が読み込まれます。

①:tommorowShiftNotification関数

②:summary関数

③:sendToSlack関数

これらについて解説していきます。

tommorowShiftNotification関数

この関数では次の処理を行います。

①:日付の取得

②:スプレッドシートからスケジュールを取り出す

③:取り出したスケジュールをループ処理で処理する

④:ループ処理の際、条件に応じて表示内容を変更する

⑤: summary関数でslackに送信する値を生成する

それぞれを見ていきましょう!

日付を取得する

まずは日付を取得します。

今回はスプレッドシートに入力された日付とGoogle Apps Script側で取得した日付を比較演算子で比較させます。

   // 日付を取得
   // Dateメソッドはインスタンス化されているため、返り値を都度変数代入しなくて問題ない
  // このように記述することで日付の部分を文字列で取得できる。自動で0:00になる。
  var tomorrow = new Date(new Date().toDateString()); 
  
  // 翌日を取得するため、+1で加算する
  tomorrow.setDate(tomorrow.getDate() + 1);

  // 当年を取得
  var yearNum = tomorrow.getFullYear(); 

 // 月は0から数えるため、当月にするために+1する
  var monthNum = tomorrow.getMonth() + 1 ;

  // 日にちを取得
  var dayNum = tomorrow.getDate(); 

  // 明日の日付に曜日を追加するために曜日の配列を用意
  var dayArr = ['日', '月', '火', '水', '木', '金', '土'] 

  // getDay()関数でtommorowに一致する曜日を取り出す
  var day = dayArr[tomorrow.getDay()];  
  var tomorrowString = String(yearNum) + "/" 
                    + String(monthNum) + "/"
                    + String(dayNum) + "" 
                    + "("+ String(day) + ")";

   // 実際に表示させる形式を作成
  var tommorowDay = "明日の日付:"+ tomorrowString

曜日を表示させる部分はやや複雑ではあるものの、様々なプログラムに流用させることができます。

スプレッドシートからスケジュールを取り出す

次にスプレッドシートにセットしたスケジュールを取り出します。

シートは0から数えますので、ご注意ください。

  // シフトの入ったスプレッドシートを読み込む。シートは0から数える。
  var shifts = SpreadsheetApp.openById("スプレッドシートのID").getSheets()[シート番号];

  // セル範囲を選択
  var schedules = shifts.getRange("xx:xx").getValues(); 

セル範囲は以下のようなスケジュールの場合はA7からB16を指定します。

日付とスケジュールが入るように取得してください。

変数schedulesには、この表の値が多次元配列で格納されます。この多次元配列をループ処理で処理していきます。

取り出したスケジュールをループ処理で処理する

いよいよこのプログラムで最も重要なループ処理に入ります。

まず、条件を言語化します。

  • 多次元配列schedulesの要素数分、処理を繰り返す
  • スプレッドシートA列の日付と翌日の日付が一致した場合、caseに応じて値を生成する
  • A列の日付と翌日の日付が一致しない場合は処理を行わない

これらの条件に合うように、コードを書きます。

多次元配列schedulesの要素数分処理を繰り返す

for文を用いて記述します。

スタートは0、処理を繰り返す度に添え字を1ずつ増加させます。

そうすることで、多次元配列の0番目から順番に処理が進みます。

schedules.lengthで多次元配列の要素数繰り返すことを示しています。

 for (let i = 0; i < schedules.length; i ++) {

}
スプレッドシートA列の日付と翌日の日付が一致した場合、caseに応じて値を生成する

本プログラムの中で最も重要な部分です。

 if (schedules[i][0].getTime() == tomorrow.getTime()){
      switch (schedules[i][1]) {
         // ケースに応じた処理を記述
     }
}

まず、多次元配列schedulesのi番目の0要素に入っている日付と前の行で取得した明日の日付が一致する場合、switch関数で処理を行います。

多次元配列の中身は次のようになっています。

[ [ Tue Aug 31 2021 00:00:00 GMT+0900 (Japan Standard Time), '13:00-22:00' ], [ Wed Sep 01 2021 00:00:00 GMT+0900 (Japan Standard Time), '11:00-20:00' ]]

以上の結果から、[[日付, シフト], [日付, シフト]]が繰り返されていることが分かります。

ここで、ループ処理を行い二次元配列のi番目の要素内の0番目の要素に入っている日付を取り出し、翌日の日付と一致している場合はswtich関数を用いて処理を進めることで実装できそうなことが分かります。

なぜ.getTimeメソッドを使用しているのか?

Dateオブジェクトでは等値演算子が使用できないことが理由です。JavaScriptにおいては、2つの異なるオブジェクトは等しいと判断されないようです。

getTimeメソッドを用いて、時刻付きに変換すると等値演算子を使用できるようになります。

シフトを取り出し、ケースに応じて処理を行う

続いて、多次元配列のi番目の1番目の要素(シフト)を取り出し、ケースに応じて処理を決めます。

switch (schedules[i][1]) {
        case "9:00-18:00":
          var shift = "<@slackのID> :9:00-18:00";
          summary(shift)
          break;
}

例えば、0番目の1番目に「9:00-18:00」と入っていれば、上記の関数が実行されます。

ケースは必要な処理の数だけ用意します。

実際に表示させる項目を変数shiftに代入し、summary関数に飛ばします。

日付が一致しなかった場合の処理

日付が一致しなかった場合はelseに飛ばします。

ここで日付が一致しなかったindexを残しておくようにすることで、処理に失敗した時の問題判別を容易にします。

}else{
      // バグがあった際、発見しやすくするために残しておく
      console.log("日付が一致しなかったインデックス")
      console.log(i)
    }

summary関数でslackに表示させる形を作成する

summary関数でslackに表示させる形を作成します。

今回は翌日の日付とシフトを表示させるため、次のように記述しています。”\n”を間に挟むことで改行できます。

function summary(shift){
    var body = tommorowDay + "\n" + shift;
    sendToSlack(body, "#チャンネル名");
  }

最後に、sendToSlack関数へ飛ばします。

sendToSlack関数でslackへ通知する

最後にsendToSlack関数に作成した情報を飛ばし、処理は完了です。

function sendToSlack(body, channel) {
  var postUrl  = "webhockのURL";
  var data = { "channel" : channel, "username" : "明日のシフトをお知らせします", "text" : body};
  var payload = JSON.stringify(data);
  var options = {
    "method" : "POST",
    "contentType" : "application/json",
    "payload" : payload
  };
  var response = UrlFetchApp.fetch(postUrl, options);
}

トリガーを時間主導型で設定する

GASに用意されている「トリガー」機能を利用し、毎日通知が来るように設定します。

作成したshiftNotification関数を時間主導型で設定することで、指定した時間に通知させることが可能です。

ただし、GASのトリガーでは時間を直接指定することができません。例えば、こちらのスクリーンショットでは毎日18:00-19:00の間に通知が届きます。

こちらはとある関数を用いることで、特定の指定した時間に通知させることが可能です。

この方法は次回お伝えします。

ループ処理を活用することで様々な業務効率化ツールを作成できる

今回はslackに翌日の勤務スケジュールを通知させる業務効率化ツールを作成しました。

シフト勤務者が翌日のシフトを正確に把握するために、大きな役割を果たします。

このツールの要はループ処理です。GASはJavaScriptと構文がほぼ同じであるため、JavaScriptのループ処理を使いこなせるレベルであれば、簡単に開発できます。

是非、身近な業務をループ処理できないか考えてみましょう!もしかしたら、簡単に自動化できるかもしれません。

最後までご覧いただき、誠にありがとうございました!

タイトルとURLをコピーしました