掃除当番の割当を Google Apps Script で自動化して Slack  の BOT として通知


## 概要

職場では毎週掃除の日があり、輪番で掃除の役割を回しています。
毎回手動で色々するのはめんどうくさいので、うまいことやって Slack とかで適当にその日の当番を教えてくれると便利ですね。

というわけで、掃除の時間帯になったら、その日の掃除当番を Slack に通知してくれる BOT を作成してみます。


##  使うもの
- Google スプレッドシート + Google App Script（GAS）
- [Slack Web API](https://api.slack.com/web)

## 当番データの準備

Google スプレッドシートで以下のようなデータを作成します。

| Member | Role | 
|:-----------|:------------|
| 東方  | トイレ掃除     |
| 空条  |  階段ほうき   |
| 広瀬  |  1F掃除機      |
| 虹村  |  ゴミ捨て      |
| 岸辺  |  デスク掃除      |
| 山岸  | 2F掃除機      |
| 矢安宮 | 休み      |

## Slack Web API token の取得

以下などを参考に、Slack Web API を利用するための token を適当に取得しておきます。
[Slack APIを使用してメッセージを送信する](http://qiita.com/rubytomato@github/items/6558bfdb37d982891c09)

## Google Apps Script の作成

先ほど準備したスプレッドシートの組み込みスクリプトとしてコードを書きます。
GAS の使い方がわからない場合は、[こちら](http://www.casleyconsulting.co.jp/blog-engineer/?p=6054)などを参考にしてください。

### SlackApp ライブラリの導入

まず、GAS で楽に Slack を扱うために、[SlackApp ライブラリ](http://qiita.com/soundTricker/items/43267609a870fc9c7453)といういい感じのライブラリを導入します。

エディタの画面のメニューより リソース > ライブラリ を選択します。
「ライブラリを検索」に SlackApp ライブラリのキーを入力します。

```
M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO
```

![gas_slackapp.png](https://qiita-image-store.s3.amazonaws.com/0/108319/3a6d5375-2213-f207-0d25-d03b6b0f794b.png)

SlackAppライブラリが追加されますので、バージョンを選択して、「保存」をクリックします。

### GAS コード

それでは、実際に動作させるスクリプトのコードを書いてみます。

```js:cleanup.gs
//slack定義
var slack = {
  postUrl: "https://slack.com/api/chat.postMessage",
  token: "(token)",  //取得したSlackWebAPIのtoken
  ChannelId: "(ChannelId)",  //投稿するチャンネルのChannelId
  userName: "Achtung Baby",  //botの名前
  iconEmoji: ":sunglasses:"  //botのアイコン
}

//メンバー・役割のデータをスプレッドシートから取得
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var lastrow = sheet.getLastRow();

var members = sheet.getSheetValues(2, 1, lastrow-1, 1);  //データ行のみを取得する
var roles = sheet.getSheetValues(2, 2, lastrow-1, 1); //データ行のみを取得する

//メンバーに掃除当番を割当ててSlackで通知する
function notifyCleaningRole() {

  //平日のみ実行
  var currentDate = new Date();
  var weekday = currentDate.getDay();
  if (weekday == 0 || weekday == 6) {
    return;
  }
  //祝日は実行しない
  var calendar = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com');
  if (calendar.getEventsForDay(currentDate, {max: 1}).length > 0) {
    return;
  } 
 
  //本日の当番を割り当てる
  var msg = "";  
  var todaysRoles = rotate(roles);  
  for(var i = 0; i < todaysRoles.length; i++){
    msg = msg + ">" + (members[i]+ "　　　　　").slice(0,4) + "： " + todaysRoles[i] + "\n";
    //割り当てた結果をスプレッドシートにも反映させる
    sheet.getRange(i+2, 2).setValue(todaysRoles[i]);
  } 
  
  //Slackにメッセージを送る
  var slackApp = SlackApp.create(slack["token"]);
  var Message = slackApp.postMessage(
    slack["ChannelId"], "<!channel> 本日の掃除当番:dusty_stick:\n\n \n" + msg + "", {
      username : slack["userName"],
      icon_emoji: slack["iconEmoji"]
    } 
  ); //@hereだと何故かデスクトップ通知されないため、仕方なく@channelを使う
}

//配列の要素を後ろにずらして、最後の要素を先頭に移動する
function rotate(array){
  array.unshift(array[array.length-1])
  array.pop();
  return array;
}

```

雑なコードですね :fearful: 

スプレッドシートからメンバーと役割を取得して、役割を回してから [postMessage メソッド](https://api.slack.com/methods/chat.postMessage)を使って Slack にメッセージをpost、という処理をしています。
実行されるごとに掃除の役割が順番に回っていきます。

なお、お休みの日に出社して掃除したくないので、平日のみ割当と通知を実行するようにしています。

### トリガーの設定
掃除の日の掃除開始前ぐらいに通知して欲しいので、スクリプトを定期実行するようトリガーを設定します。
トリガーってなんのこっちゃという場合は、[こちら](http://dotinstall.com/lessons/basic_google_apps_script/24313)。

![gas_trigger.png](https://qiita-image-store.s3.amazonaws.com/0/108319/a0d15a52-56af-2698-bdd4-a1e93212700f.png)

掃除開始前の時間帯に設定の上、**notifyCleaningRole**ファンクションを指定し、「保存」をクリック。
これで掃除開始前にスクリプトが定期実行されます。サーバーレスでいいですね。

## 実行イメージ

こんな感じで BOT が掃除当番を教えてくれます。

![赤ちゃんはここにおる](https://qiita-image-store.s3.amazonaws.com/0/108319/521aa48d-ec84-73a5-00ff-fc6d27c530d0.png)


## 参考

[毎週のお掃除当番をSlackへランダムで通知する](http://qiita.com/Yamotty/items/b0eb3d855c4266b18b39)
大変参考になりました :bow: