当番表にメールお知らせ機能をつけた話

# はじめに
僕の研究室では全体ゼミの議事録当番というものがある。
もちろんその当番表も存在しているが、下の画像を見てほしい(名前は全て偽名である)。
![screenshot-docs.google.com-2020.10.28-23_57_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/b1b3e8e9-5e96-582f-d4ca-ef643a485eb9.png)
**見にくい**。

しかも、全体ゼミの前にメンバーそれぞれにこの表の確認をお願いするのである。
**嗚呼、なんと素晴らしき情報化社会か**。

バカ言ってないで、こんなフェッチ式はお終いにしてプッシュ式を導入しよう。
Googleの力で。

# 作成
## アドレスシート
まずは送信先のメアドを載せたシートを作成する。
こんな感じ。
![screenshot-docs.google.com-2020.10.28-23_59_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/85c43a11-f954-6c0e-499c-c78b867000f6.png)
ここで、Calendarシートの名前とMail_Addressシートの名前は順番が一致するようにする。

## スクリプト
ツールタブにあるスクリプトエディタからスクリプトは作成できる。

### 流れ
1. スプレッドシートやら、シートやら、この表やらの読み込み
2. スクリプト実行時の日付と当番日時を比較
3. 当番日時とスクリプト実行時の日付が等しい人にメールを送る。

なお、メール送信日時（スクリプトの実行日時）は全体ゼミ当日の朝を想定している。

### 中身

まずはスクリプトでこのスプレッドシートを読み込む。

```javascript
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
```

次は2つのシートの読み取り。
こんな感じ。


```javascript
var table_sheet = spreadsheet.getSheetByName("Calendar");
var address_sheet = spreadsheet.getSheetByName("Mail_address");
```

表。

```javascript
var turn_table = table_sheet.getRange("C5:G23").getValues();
var address_list = address_sheet.getRange("B1:B19").getValues();
var name_list = address_sheet.getRange("A1:A19").getValues();
```

スクリプト実行時の日付の取得。

```javascript
var today = new Date();
var today_str = Utilities.formatDate(today, 'JST', 'MM/dd');
```

気の利いたメール件名、本文。

```javascript
var subject = "今日の全ゼミ議事録当番のお知らせ";
var message1 = "今日の議事録は";
var message2 = "さんと";
var message3 = "さんです．\n忘れないようにお願いします．\n自動で送っているものなので返信はしなくて大丈夫です．\n\n------------------------------------------------\n見谷\nkmitani@mail.sample.com\nスクリプト書いた人\nししなう\n------------------------------------------------";
```

当番の検索とメール送信。
メール送信を条件分岐させているのは、当番が2人いるときと1人だけのときの両方に対応させるため。

```javascript
var hoge = [];
var temp_address = [];
for(var i in turn_table) {
  for(var j in turn_table[i]){
    if(typeof(turn_table[i][j]) != 'string'){
      if(Utilities.formatDate(turn_table[i][j], 'JST', 'MM/dd') == today_str){
        hoge.push([i]);
        temp_address.push(address_list[i]);
      }
    }
  }
}
  
if(hoge.length == 2){
  message = message1 + name_list[hoge[0]] + message2 + name_list[hoge[1]] + message3;
  MailApp.sendEmail(temp_address, subject, message);
}else if(hoge.length == 1){
  message = message1 + name_list[hoge[0]] + message3;
  MailApp.sendEmail(temp_address, subject, message);
}
```

結果、出来上がるのはこんなん。

```javascript:SendNoticeMail
function SendNoticeMail(){
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var table_sheet = spreadsheet.getSheetByName("Calendar");
  var address_sheet = spreadsheet.getSheetByName("Mail_address");
  
  var today = new Date();
  var today_str = Utilities.formatDate(today, 'JST', 'MM/dd');
  
  var turn_table = table_sheet.getRange("C5:G23").getValues();
  var address_list = address_sheet.getRange("B1:B19").getValues();
  var name_list = address_sheet.getRange("A1:A19").getValues();
  
  var subject = "今日の全ゼミ議事録当番のお知らせ";
  var message1 = "今日の議事録は";
  var message2 = "さんと";
  var message3 = "さんです．\n忘れないようにお願いします．\n自動で送っているものなので返信はしなくて大丈夫です．\n\n------------------------------------------------\n見谷\nkmitani@mail.sample.com\nスクリプト書いた人\nししなう\n------------------------------------------------";
  
  var hoge = [];
  var temp_address = [];
  for(var i in turn_table) {
    for(var j in turn_table[i]){
      if(typeof(turn_table[i][j]) != 'string'){
        if(Utilities.formatDate(turn_table[i][j], 'JST', 'MM/dd') == today_str){
          hoge.push([i]);
          temp_address.push(address_list[i]);
        }
      }
    }
  }
  
  if(hoge.length == 2){
    message = message1 + name_list[hoge[0]] + message2 + name_list[hoge[1]] + message3;
    MailApp.sendEmail(temp_address, subject, message);
  }else if(hoge.length == 1){
    message = message1 + name_list[hoge[0]] + message3;
    MailApp.sendEmail(temp_address, subject, message);
  }
}
```

### スクリプトの実行設定
どこかにトリガーっていう設定項目があるはずなので、そこから「週1水曜朝9時に実行」に設定。

# まとめ
今回は元から存在している当番表ありきで自動メール送信スクリプトを組んだ。
特にCalendarシートは、メールお知らせ機能を付けることを想定していればもっと別の扱いやすい形で管理できていたはず。
途中の仕様変更には気をつけよう。

あと、GASはそんなに難しくない（書くのにめっちゃ手間取ったのは内緒）。

# 勝手にスペシャルサンクス
偽名生成でお世話になったサイトさん。
[すごい名前生成器](https://namegen.jp/)