出社日の前日にSlackへリマインダーを送信するスクリプト


#概要

私の所属する部署では出社が当番制になっていて、担当割をExcelで管理しています。
しかし、毎回それを見て自分の出社日を確認するのは面倒なので、「Googleスプレッドシートの出社表から自分の出社日を探し、その前日に「明日は出社日！」とSlackにリマインダーを送信してくれるスクリプト」を作りました。

処理の流れはこんな感じです。

1. トリガーを設定し、スクリプトを毎日実行する
1. スプレッドシートから自分の出社日の前日を取得
1. 「スクリプトの実行日」と「2で取得した日」が一致したとき、リマインド用のトリガーを設定
1. リマインド用トリガーを実行し、Slackにリマインダーを送信

#作成したスプレッドシート

体裁は以下の通りです。

- 使用する列はA～Eまでの5列
- 1行目はタイトル
- 2行目は日付のみ
- 3行目から日付＋担当者割

2行目については、実装上の都合でこうなっています。（対象の担当者名を探索し、その前日の日付を取得するため）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674043/15b6f788-f11a-9924-8295-9ca81ba83377.png)

#実装

- 出社日の探索

スプレッドシートのキーは、URLの????????の部分です。
https://docs.google.com/spreadsheets/d/????????/edit

```
function searchWorkDay(){
  //スプレッドシートを取得
  var obj = SpreadsheetApp.openById("スプレッドシートのキー");
  var sheet = obj.getSheetByName("シート名");
  var lastRow = sheet.getLastRow();
 
  //実行日を取得
  let date = new Date();
  var today = Utilities.formatDate( date, 'JST', 'yyyyMMdd')
  Logger.log(today);
  
  let workDay = null;
  
  //対象文字列の探索
  loop: for(var i=3; i<=lastRow; i++){
    for(var j=2; j<=4; j++){
      //未通知の出社日を探索
      if(sheet.getRange(i, j).getValue() === "探索したい文字列" && !sheet.getRange(i, 5).getValue()){
        //1日前の日付を取得
        workDay = sheet.getRange(i-1, 1).getValue();
        var r_workDay = workDay.replace(/-/g, "");
        
        //出社日の前日とスクリプトの実行日が同じである場合、トリガーを設定する
        if(r_workDay === today){
          Logger.log(r_workDay);
          sheet.getRange(i, 5).setValue("done");
          
          setTrigger();
        }
          break loop;
      }
    }
  }
  Logger.log("complete");
}
```

- トリガーの設定

```

function setTrigger(){

  delTrigger();

  //実行日の9時00分にリマインド用トリガーを設定する
  const time = new Date();
  time.setHours(9);
  time.setMinutes(00);
  ScriptApp.newTrigger('postSlack').timeBased().at(time).create();
  
  Logger.log(time + "にトリガーを設定しました");
}

function delTrigger(){
  
  //設定済みリマインド用トリガーを削除する
  const triggers = ScriptApp.getProjectTriggers();
  for(const trigger of triggers){
    if(trigger.getHandlerFunction() === "postSlack"){
      ScriptApp.deleteTrigger(trigger);
    }
  }
  Logger.log("トリガーを削除しました");
}
```

- Slackに送信

参考にした記事
[SlackのIncoming WebhookでのURL取得方法](https://www.sejuku.net/blog/74471)

```
function postSlack(){

  var text = "明日は出社日！";
  var payload  = {
    'text'      :  text, 
  };
  
  var options = {
    'method'      : 'post',
    'contentType' : 'application/json',
    'payload'     : JSON.stringify(payload),
  };

  var url = 'SlackのIncoming Webhookで取得したURL';
  UrlFetchApp.fetch(url, options);

}
```

#毎日実行するトリガーの設定

毎日1～2時の間に実行する設定にしています。

参考にした記事
[時限式のトリガー設置方法](https://tonari-it.com/gas-timed-driven-trigger/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674043/e1d929ba-01f2-45b2-e792-99e132b73a16.png)

#実行結果

こんな感じで通知されます！
アイコンや表示名についても任意で変更可能です。

参考にした記事
[Incoming webhookまとめ](https://qiita.com/kshibata101/items/0e13c420080a993c5d16)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674043/cf7611fb-6c32-9161-f569-831b0be8a52a.png)

#まとめ

今回は、スプレッドシートから自分の出社日の前日を取得し、Slackにリマインダーを送信するスクリプトを作ってみました。
次は、SlackのOutgoing Webhookを用いて、「次の出社日は？」と投稿したら結果が得られるようにしてみたいと思います！