Googleカレンダーの内容をSlackに投稿する


[今日の予定をまとめて教えてくれるslackの秘書BOT](http://qiita.com/seya128/items/028274fc014af37f7931)の記事を参考に、自分の会社用にカスタマイズしてみました。
@seya128さん、すばらしい記事ありがとうございます！

## カスタマイズした点
カスタマイズしたのは下記の点です。

* 会社のメンバー全てのカレンダーをまとめて表示する
* 会議室とか打ち合わせ場所がある場合は「@第1会議室」みたいに表示する

## Slackへの投稿URLの取得

`https://チーム名.slack.com/services`にアクセスします。
そこから、[Integrations] -> [Configured Integrations] -> [Incoming WebHooks]にある「+Add」をクリックします。
[Post to Channel]はとりあえず`#general`にして、「Add Incoming WebHooks Integration」をクリックすると、`Webhook URL`が発行されます。これが投稿用のURLとなります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/37435/623ac703-2f50-1e9a-c3e8-15b79fa296e3.png" width="600" />

## アドレスの登録
会社のメンバーのアドレスを登録する必要があります。
Googleカレンダーの左ペインにある「同僚のカレンダーを追加」より、表示したい会社のメンバーのアドレスを登録します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/37435/4464e738-20bb-c8b9-e305-109b925696b2.png" width="200" />

## スクリプトの作成
[スプレッドシート](https://docs.google.com/spreadsheets/u/0/)の右下にある赤い＋ボタンよりスプレッドシートを作成し、`Google Apps Script用のスプレッドシート`という名前に変更しておきます。

そのスプレッドシートを開き、[ツール] -> [スクリプトエディタ]をクリックすると、`Code.gs`というファイルが作成されます。
これも分かりやすいよう、`GoogleカレンダーをSlackに送る.gs`というファイル名に変更しておきます。

## スクリプトを登録
下記のスクリプトを`GoogleカレンダーをSlackに送る.gs`に貼り付けて、`Ctrl+S`とかでファイルをセーブして下さい。

```js:GoogleカレンダーをSlackに送る.gs
/**
 * Send event of google-calendar to slack.
 * @author shibukk
 * @version 1.0.0 2015/08/20
 */
function myFunction() {
  var events = getEvents();
  var list = formatEvents(events);

  postSlack(list);
}

// list up event of calendar
function getEvents()
{
  var events = [];
  var cals = CalendarApp.getAllCalendars();

  cals.forEach (function (cal) {
    var calEvents = cal.getEventsForDay(new Date());
    calEvents.forEach (function (calEvent) {
      events.push(calEvent);
    });
  });

  events.sort(function(a, b) {
    return (a.getStartTime() <= b.getStartTime() ? -1 : 1);
  });

  return events;
}

// format event
function formatEvents(events)
{
  var list   = "";
  var titles = [];

  events.forEach (function (e) {
    var s           = "";
    var title       = e.getTitle();
    var startTime   = e.getStartTime();
    var endTime     = e.getEndTime();
    var location    = e.getLocation();

    if (titles.indexOf(title) != -1) {
      return;
    }
    titles.push(title);

    if (e.isAllDayEvent()) {
      s += Utilities.formatDate(startTime, "GMT+0900", "MM/dd");
      s += " 終日   ";
    } else {
      s += Utilities.formatDate(startTime, "GMT+0900", "HH:mm");
      s += Utilities.formatDate(endTime, "GMT+0900", "〜HH:mm ");
      if (location != "") {
        s += "@" + location + " ";
      }
    }
    s += title;

    list += s + "\n";
  });

  return list;
}

// send to slack
function postSlack(list)
{
  if (list == "") {
    return;
  }

  var now = new Date();
  var week = ['日', '月', '火', '水', '木', '金', '土'];
  var day = ((now.getMonth() + 1) + '/' + now.getDate() + ' (' + week[now.getDay()] + ')');

  var payload = {
    "text" : "<!channel> " + day + "の予定をお知らせします。\n```" + list + "```\n※スケジュールは随時更新されます。\n最新のスケジュールはGoogleカレンダーで各自確認してください。\nhttps://www.google.com/calendar/",
    "channel" : "#general", // 送信したいチャンネル
    "username" : "総務部", // 送信者名
    "icon_emoji" : ":ledger:" // 送信時のアイコン
  }

  var options = {
    "method" : "POST",
    "payload" : JSON.stringify(payload)
  }

  var url      = "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"; // 取得したWebhook URL
  var response = UrlFetchApp.fetch(url, options);
  var content  = response.getContentText("UTF-8");
}
```

以下コードの簡単な説明です。

```js
var cals = CalendarApp.getAllCalendars();
```

コード中にある`CalendarApp.getAllCalendars()`で取得できるのはスプレッドシートの所有者が参照しているカレンダーです。
なので、全ての社員のカレンダーが見たい場合は、めんどくさいですが上に書いたアドレスの登録が必要です。

また、会議室などの場所情報はこうやって取得できます。
ちなみに登録されていない場合は空の文字列が返ってきます。

```js
var location    = e.getLocation();
```

## タイマーの設定
スクリプトエディタ上にある時計マークを押すと、スクリプトの実行間隔が設定できます。
イベントは[時間主導型]・[日タイマー]・[飛ばしたい時間]にすればOKです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/37435/16af3ea9-69b6-d985-a613-64b3360293e0.png" width="600" />

土日は送りたくない場合は、スクリプト側で送らないようにすればOKです。
こんな感じ。

```diff
// send to slack
function postSlack(list)
{
  if (list == "") {
    return;
  }

  var now = new Date();
+  if (now.getDay() == 0 || now.getDay() == 6) {
+    return;
+  }

...
```

これでいちいちカレンダーを見なくてもSlackでバッチリ確認できるようになりました！

## 参考
[Class CalendarEvent - Google Apps Script](https://developers.google.com/apps-script/reference/calendar/calendar-event)