GASでSlackのメッセージを制御する

# これは何？
- Google App ScriptでSlackを制御するためのスクリプト例です
    - 経常業務に掛かる稼働の軽減を図ることを目的としています


## 土日祝を除外したリマインダー
- WebhookURLを取得する
- 参照する「日本の祝日」カレンダーを指定する
    - 祝日の場合は送らないように定義する
    - 年末年始の```12/27-01/03```も除外する
- メッセージ文とリンクを指定する
- 投稿先のチャンネルとユーザーグループを指定する
- 送信時刻を指定する
    - 別途トリガーを指定時刻の1時間前付近で設定しておく

```javascript
function sendNotification() {
  // send mention automatically
  var slackWebhookUrl = 'https://hooks.slack.com/services/xxx';

  // 祝日を定義
  function isHoliday(date) {
    var calendarId = 'ja.japanese#holiday@group.v.calendar.google.com';
    var calendar = CalendarApp.getCalendarById(calendarId);
    var events = calendar.getEventsForDay(date);
    return events.length > 0;
  }

  // 年末年始を定義
  function isYearEnd(date) {
    var month = date.getMonth() + 1; // getMonth() returns 0-11
    var day = date.getDate();
    return (month === 12 && day >= 27) || (month === 1 && day <= 3);
  }

  // 投稿内容を定義
  var mentionMessage = ' メッセージ文 （ <https://xxxxxx|テキスト> ）';

  // 現在の日時等を取得
  var now = new Date();
  var dayOfWeek = now.getDay();
  var currentTime = Utilities.formatDate(now, 'JST', 'HH:mm');

  // 祝日と年末年始を除いた平日に通知されるようにセット
  if ( 0 < dayOfWeek && dayOfWeek < 6  ) {
    // send mention without holiday
    if (!isHoliday(now)&&!isYearEnd(now)) {
      var payload = {
        text: "<!subteam^ユーザーグループID>" + mentionMessage,
        channel: '#チャンネル名',
      };
      var options = {
        method: 'post',
        contentType: 'application/json',
        payload: JSON.stringify(payload),
      };
      UrlFetchApp.fetch(slackWebhookUrl, options);
    }
  }
  deleteTrigger()
}

// タイマーをセットする
function setReminder(){
  var time = new Date();
  time.setHours(11);
  time.setMinutes(00);
  time.setSeconds(00);
  ScriptApp.newTrigger('sendNotification').timeBased().at(time).create();
}

// トリガーの削除する（溜まると発火しなくなるため）
function deleteTrigger() {
  var triggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < triggers.length; i++) {
    if (triggers[i].getHandlerFunction() == "sendNotification") {
      ScriptApp.deleteTrigger(triggers[i]);
    }
  }
}

```

## 毎週水曜日のリマインダー
- WebhookURLを取得する
- 参照する「日本の祝日」カレンダーを指定する
    - 祝日の場合は送らないように定義する
    - 年末年始の```12/27-01/03```も除外する
- メッセージ文とリンクを指定する
- 投稿先のチャンネルとユーザーグループを指定する
- 送信時刻を指定する
    - 別途トリガーを送信時刻の1時間前付近で設定しておく
    - トリガーを削除する（トリガーが溜まり過ぎると動かなくなるため）

```javascript
function sendNotification() {
  // send mention automatically
  var slackWebhookUrl = 'https://hooks.slack.com/services/xxxx';

  // designate time and day of week
  var notificationDay = 3; // 0:Sun, 1:Mon, ..., 6:Sat

  // check holiday
  function isHoliday(date) {
    var calendarId = 'ja.japanese#holiday@group.v.calendar.google.com';
    var calendar = CalendarApp.getCalendarById(calendarId);
    var events = calendar.getEventsForDay(date);
    return events.length > 0;
  }

 // check YearEnd
  function isYearEnd(date) {
    var month = date.getMonth() + 1; // getMonth() returns 0-11
    var day = date.getDate();
    return (month === 12 && day >= 27) || (month === 1 && day <= 3);
  }

  // content
  var mentionMessage = ' <https://xxxx|テキスト>を確認して完了報告をしてください！';

  // get action date
  var now = new Date();
  var dayOfWeek = now.getDay();
  var currentTime = Utilities.formatDate(now,'JST','HH:mm');

  // set Wednesday
  if (dayOfWeek === notificationDay && currentTime) {
    // send mention without holiday
    if (!isHoliday(now)&&!isYearEnd(now)) {
      var payload = {
        text: "<!subteam^ユーザーグループID>" + mentionMessage,
        channel: '#チャンネル名',
      };
      var options = {
        method: 'post',
        contentType: 'application/json',
        payload: JSON.stringify(payload),
      };
      UrlFetchApp.fetch(slackWebhookUrl, options);
    }
  }
  deleteTrigger()
}

// Set Trigger
function setReminder(){
  var time = new Date();
  time.setHours(11);
  time.setMinutes(00);
  time.setSeconds(00);
  ScriptApp.newTrigger('sendNotification').timeBased().at(time).create();
}

function deleteTrigger() {
  var triggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < triggers.length; i++) {
    if (triggers[i].getHandlerFunction() == "sendNotification") {
      ScriptApp.deleteTrigger(triggers[i]);
    }
  }
}

```


## 毎月月初○営業日目のリマインダー
- WebhookURLを取得する
- 参照する「日本の祝日」カレンダーを指定する
    - 祝日だった場合は翌営業日に送るように定義する
- メッセージ文とリンクを指定する
- この例では月初5営業日と定義する
- 投稿先のチャンネルとユーザーグループを指定する


```javascript
function sendNotification() {
  // send mention automatically
  var slackWebhookUrl = 'https://hooks.slack.com/services/xxx';

  var today = new Date();

  // 参照するGoogleカレンダーを定義
  var calendarId = 'ja.japanese#holiday@group.v.calendar.google.com';
  var calendar = CalendarApp.getCalendarById(calendarId);
  var holidays = calendar.getEventsForDay(today);

  // content
  var mentionMessage = ' メッセージ<#チャンネルID|テキスト>';

  // 月初5営業日目を計算
  var businessDays = 0;
  var date = new Date(today.getFullYear(), today.getMonth(), 1);
  while (businessDays < 5) {
    if (date.getDay() != 0 && date.getDay() != 6 && calendar.getEventsForDay(date).length == 0) {
      businessDays++;
    }
    if (businessDays < 5) {
      date.setDate(date.getDate() + 1);
    }
  }

  if (today.getDay() == 0 || today.getDay() == 6 || holidays.length > 0) {
    return;
  }

  // 今日が月初5営業日目かどうかを確認
  if (today.getDate() != date.getDate()) {
    return;
  }

  var payload = {
    channel: '#チャンネル名',
    text: "<!subteam^ユーザーグループID>" + mentionMessage,
  };

  var options = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify(payload),
  };

  UrlFetchApp.fetch(slackWebhookUrl, options);
}

```

# 最後に
少しクセがありますが、慣れるとかなり便利なSlackをより便利にしてやりましょう！