GASに自動でバイトのシフトを組んでもらう　~リマインド編（Slack連携編）~

# 1. 概要
この記事は前回の続きです．前回の記事は[こちら](https://qiita.com/mtsnoopy/items/7d003a41a6263ce75137)．
前回はシフトを自動で組むプログラムを作成しました．
今回は組んだシフトを参照し，当日シフトの人にSlackのDMでリマインドが届くようにしたいと思います．

## 2. イントロ
### 2-a. システム
前回の記事にも載せましたが，システム図を再掲します．
<img width=700 alt="システム図" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631545/0456e1ef-c803-6003-8a78-f216addf29a5.jpeg">

## 3. 実装
### 3-a. 下準備
リマインド通知を送るSlackのワークスペースを必要に応じて作ります．
### 3-b. Slackとの連携
今回は連携のために"Incoming Webhook"を用います．（[公式記事](https://slack.com/intl/ja-jp/help/articles/115005265063-Slack-%E3%81%A7%E3%81%AE-Incoming-Webhook-%E3%81%AE%E5%88%A9%E7%94%A8) )
これは特定のSlackチャンネルにデータ（メッセージなど）を外部から送信することができるものです．
上記リンクの`Incoming Webhookの設定`を参考に，新規アプリを作成します．ここではアプリの名前をReminderとします．
作成が完了したら，slack apiのサイドバーから，`Features`の`Incoming Webhooks`にいきます．
<img width=700 alt="incoming webhooks" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631545/533e86ca-49f4-eed8-17f9-f5bf50caa26a.png">
`Add New Webhook to Workspace`から，人数分のWebhookを作成します．Webhookはチャネル（DMの場合は人）ごとなので，人数分作成する必要があります．
作成した各`Webhook URL`に対してGASからリクエストを送ると，各チャンネルにデータ（メッセージ）が送信される，という具合です．

`Webhook URL`は`workers`シートにカラムを作って保存します．
<img width=700 alt="webhook urlを記入" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631545/3f0445f9-3847-05df-30b9-2f62bb443544.jpeg">

### 3-c. GASプログラミング
さて，`worker`スプシのAppScriptにもどって，`reminder.gs`を作成します．
コード内の実装手順は，
1. `woker`スプシの`workers`シートから現在のメンバー情報を取得
2. `schedule`スプシの`schedule`シートからシフト情報を取得
3. 今日シフトの人全員にメッセージを送信．

※以下のコードでは`schedule`フォルダのフォルダIDを入力する必要があることに注意．
```javascript:reminder.gs
function reminder() {
  //現在のworkerを取得
  const workerSS = SpreadsheetApp.getActiveSpreadsheet();
  const workerValues=workerSS.getSheetByName("workers").getDataRange().getValues();
  const workerNum = workerValues.length - 1;

  //現在の日付を取得
  let now = new Date();
  //今月を取得
  let date = now.getDate();
  let month = now.getMonth()+1;
  let year = now.getFullYear();
  let lastDay = getLastDay(year,month);
  month = ("0" + month).slice(-2);
  
  //シフト表を探索
  let scheduleFolder = DriveApp.getFolderById('ここにscheduleフォルダのフォルダIDを入力');
  let scheduleFiles = scheduleFolder.getFiles();
  let scheduleFileName = "schedule_"+year.toString()+month.toString();
  let scheduleName;
  let scheduleId;
  let scheduleURL;

  while(scheduleFiles.hasNext()){
    
    let file = scheduleFiles.next();

    scheduleName = file.getName(); // ファイル名
    scheduleId = file.getId(); // ファイルID
    scheduleURL = file.getUrl(); // ファイルURL

    if (scheduleName == scheduleFileName) 
    {
      console.log("Schedule hitted !")
      break;
    }
    else
    {
      scheduleName = null;
      scheduleId = null;
      scheduleURL = null;
    }
  }
  console.log([scheduleName,scheduleId,scheduleURL]);

  const scheduleSS = SpreadsheetApp.openById(scheduleId).getSheetByName('schedule');

  
  let assigneeRange = scheduleSS.getRange(3+date,3,1,workerNum);
  let assigneeValues = assigneeRange.getValues();
  console.log(assigneeValues);

  // ここからSlack
  //workersシートからメンバのwebhook urlを取得
  let memberUrls = []
  for(let m=0;m<workerNum;m++){
    memberUrls.push([workerValues[m+1][0]+workerValues[m+1][1],workerValues[m+1][4]])
  }

const message = "本日バイトのシフトよろしくお願いいたします";
  
  var jsonData =
  {
     "username" : "通知時に表示されるユーザ名",
     "icon_emoji": "通知時に表示されるアイコン",
     "text" : message
  };
  var payload = JSON.stringify(jsonData);
  var options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };
  //シフト表に記入がある人全員に対してメッセージを送信
  for(let p=0;p<assigneeValues[0].length;p++){
    if(assigneeValues[0][p].length > 0){
      UrlFetchApp.fetch(memberUrls[p][1], options);
      console.log("Reminded to "+memberUrls[p][0]);
    }
  }
}
}
```
実行すると，シフト表の今日の欄に記入がある人に対してDMが送られている事が確認できる．

### 3-d. リマインドの定期実行
リマインドを毎日自動で送るには，トリガーを設定する必要があります．
GASのサイドバーの`トリガー`から，`トリガーを追加`をクリックして以下のように設定します．
<img width=800 alt="トリガ設定" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631545/bc5cdf3c-ad85-2375-0619-72b4d25b18db.png">
時間は好きな時間を選択します．１時間単位で設定でき，その間のどこかで実行されます．


# まとめ
slackと連携してGASからリマインドメッセージを送る方法を紹介しました．
当日シフトの人にDMするって，毎日を考えるとなかなか大変なことですが，これが一番確実なリマインド方法ですよね．
自動化によってバイトのすっぽかし人間がいなくなったので効果ありです(^v^)