gas
Slack

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

More than 3 years have passed since last update.

今日の予定をまとめて教えてくれるslackの秘書BOTの記事を参考に、自分の会社用にカスタマイズしてみました。

@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となります。


アドレスの登録

会社のメンバーのアドレスを登録する必要があります。

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


スクリプトの作成

スプレッドシートの右下にある赤い+ボタンよりスプレッドシートを作成し、Google Apps Script用のスプレッドシートという名前に変更しておきます。

そのスプレッドシートを開き、[ツール] -> [スクリプトエディタ]をクリックすると、Code.gsというファイルが作成されます。

これも分かりやすいよう、GoogleカレンダーをSlackに送る.gsというファイル名に変更しておきます。


スクリプトを登録

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


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");
}


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

var cals = CalendarApp.getAllCalendars();

コード中にあるCalendarApp.getAllCalendars()で取得できるのはスプレッドシートの所有者が参照しているカレンダーです。

なので、全ての社員のカレンダーが見たい場合は、めんどくさいですが上に書いたアドレスの登録が必要です。

また、会議室などの場所情報はこうやって取得できます。

ちなみに登録されていない場合は空の文字列が返ってきます。

var location    = e.getLocation();


タイマーの設定

スクリプトエディタ上にある時計マークを押すと、スクリプトの実行間隔が設定できます。

イベントは[時間主導型]・[日タイマー]・[飛ばしたい時間]にすればOKです。

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

こんな感じ。

// 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