会議のWEBミーティングURLを教えてくれるメール(Gmail)の内容を、Slack通知する

# やること
* その日に行う会議のWEBミーティングURLを教えてくれるメール内容を、Slack通知する
  * 会議の15分前にSlack通知する

Gmailを使っているため、Google Apps Script ( GAS ) を 使ってSlackに通知します

GAS の処理としては下記

1. 会議の15分前 (16:15) に自動で起動 (土日祝日を除く平日のみ)
2. Gmail から該当する件名のメールを見つけて取得
3. 本文を Slack に ( Incoming Webhook を使って)投稿
4. 2.で見つからない場合、「見つかりません」とSlackに通知



## 参考にさせていただいたサイト

ほとんど下記のサイトからもらい、組み合わせました
 ( なにかあれば、お手数ですが、お知らせください )

【初心者向け】GASを使ってSlackへ自動通知
https://qiita.com/chihiro/items/c7b11abc78f5d806c3a8

【GAS】Gmailの特定条件で検索したスレッドの全メールを取得してスプレッドシートに書き出す
https://tonari-it.com/gas-gmail-get-thread/

Google Apps Scriptを正確なスケジュールで実行する
http://nomusiclife.hatenablog.jp/entry/2017/11/10/153341


## コード
下記コードを毎日15〜16時のどこかで動くようにトリガーしています

```js

// thanks to : http://nomusiclife.hatenablog.jp/entry/2017/11/10/153341
function isHoliday(date) {
  if (date.getDay() === 0 || date.getDay() === 6) {
    return true
  }
  
  // 日本の祝日カレンダーに終日予定があれば祝日とする
  var calendar = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com')
  var events = calendar.getEventsForDay(date)
  
  return events.length > 0
}


function createTriggers() {
  console.log('createTriggers')
  var now = new Date()

  // 残っているトリガーを掃除する
  var triggers = ScriptApp.getProjectTriggers()
  if (Array.isArray(triggers)) {
    triggers.forEach(function(trigger) {
      // fetchContactMailのトリガーのみを削除する
      if(trigger.getHandlerFunction() === 'fetchContactMail') {
        ScriptApp.deleteTrigger(trigger);
      }
    })
  }
  
  // 土日祝はスケジュールしない
  if (isHoliday(now)) {
    console.log('there are no schedules today')
    return
  }
  // 16:15にのみ送信する
  var hours = [16] //[12, 13, 14]
  hours.forEach(function(hour) {
    var date = new Date()
    date.setHours(hour)
    date.setMinutes(15)
    if (now.valueOf() < date.valueOf()) {
      // fetchContactMail() のトリガーを指定した日時で作成
      ScriptApp.newTrigger("fetchContactMail").timeBased().at(date).create()
    }
  })
}


// thanks to : https://tonari-it.com/gas-gmail-get-thread/
function fetchContactMail() {
 
  /* Gmailから特定条件のスレッドを検索しメールを取り出す */
  // ここで探すのは 件名：「<検索する文字列> + <今日の日付(M/d)>」となっているメール
  var str1 = "<検索する文字列>";
  var d = new Date();
  // 件名に入る今日の日付(M/d)をGetだぜ
  var formattedDate = Utilities.formatDate( d, 'Asia/Tokyo', 'M/d');

  /* 件名：「<検索する文字列> + <今日の日付(M/d)>」を検索する 
      (「re」の付くものは返信とみなし対象外とする)*/
  var strTerms = 'subject:(' + str1 + ' ' + formattedDate + ' -{re})';

  var myThreads = GmailApp.search(strTerms, 0, 1); //条件にマッチした最新のスレッドを1つ取得

  // 無いときはその旨をSlackに投稿
  if (myThreads.length > 0) {
  } else {
    var contents = "xxxxは見つかりません";   
    redirecttoslack(contents);
    return
  }

  var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する　→二次元配列で格納
 
  var valMsgs = [];
 
  /* 各メールから日時、送信元、件名、内容を取り出す*/
  for(var i = 0;i < myMsgs.length;i++){
    valMsgs[i] = [];
    valMsgs[i][0] = myMsgs[i][0].getDate();
    valMsgs[i][1] = myMsgs[i][0].getReplyTo();
    valMsgs[i][2] = myMsgs[i][0].getSubject();
    valMsgs[i][3] = myMsgs[i][0].getPlainBody();
    valMsgs[i][4] = myThreads[i].getPermalink();  
  } 
 
    /* スプレッドシートに出力 */
    if(myMsgs.length>0){
    
    var mySheet=SpreadsheetApp.openById('<スプレッドシートのIDを入れる>').getSheetByName('メール'); //シートを取得
    var maxRow=mySheet.getDataRange().getLastRow(); //シートの使用範囲のうち最終行を取得
    mySheet.getRange(maxRow+1, 1, i, 5).setValues(valMsgs); //シートに取得したメッセージのデータを追加

    var subject  = mySheet.getRange(maxRow+1, 3).getValue();
    var contents = mySheet.getRange(maxRow+1, 4).getValue();
   
    redirecttoslack(contents);

  }   
}


function redirecttoslack(contents) {

  /* Slack連携 thanks to : https://qiita.com/chihiro/items/c7b11abc78f5d806c3a8 */  
    var postUrl = 'https://hooks.slack.com/services/xxxxxxxxxxxxx(SlackのIncoming Webhook URL)';
    var username = 'xxxxお知らせbot';  // 通知時に表示されるユーザー名
    var icon = ':hatched_chick:';  // 通知時に表示されるアイコン
    var message = "```" + contents + "```";  // 投稿メッセージ
    
      var jsonData =
      {
         "username" : username,
         "icon_emoji": icon,
         "text" : message
      };
      var payload = JSON.stringify(jsonData);
    
      var options =
      {
        "method" : "post",
        "contentType" : "application/json",
        "payload" : payload
      };
    
      UrlFetchApp.fetch(postUrl, options);

}

```