一年間寝かし(放置してしまった汗)ておいた

Innovation EGG 第4回 『各クラウドの現状とこれから』7月4日(土)(開始時間は調整中)
2015-07-04(土)11:00 – 18:00 Innovation EGG 第4回です。 Innovation EGG(イノベーションエッグ)は未経験者•初心者の方が気軽にセッションに参加して頂き、また講演内容を気に入って頂け

innovationegg.doorkeeper.jp

をようやく実施できるようになりました汗。

クラウドユーザーグループ7つ+αによる合同勉強会。
去年の2月のXEggはJAWS-UGとJAZUGのみで、他のコミュニティの方にもご協力いただきましたが、今回はクラウドユーザーグループメインでの実施が可能になりました。

1年でたくさんのクラウドユーザーグループが産まれたのはうれしいですね。

今回はHUBOTとmysqlとgoogle カレンダーとgoogle apps script(以降GAS)とslackの連携となります。
今回実施したかった事は、計画的作業の見える化です。

cloudpackでは計画的な時刻指定の作業は、backlogやgoogle カレンダーに記載して対応していましたが、担当者の作業忘れや作業を取りかかっているかどうかが他の人(cloudpack依頼者)から見えないなど、結果的には出来ていたのですが、もやっとした部分があったので日次処理のつぶやきのように、slackへのカレンダーの通知(作業着手URL付き)と、作業着手を受け付けたのを表示するつぶやきと、作業着手できない場合は、定期的に出来ていない事を通知する機能を実装する事にしました。

今回はgoogleカレンダーの連携にGASを利用しました。
hubotからgoogleカレンダーのAPIを呼ぶのも出来るようですが、自身の理解力が無いのか、情報が古いのかわかりませんが、少しやってうまくいかなかったので、GASを使ってgoogleカレンダーの連携を行います。

GASでの方法は、単純で、定期的にgoogleカレンダーにアクセスしてつぶやきたい時間の範囲のカレンダーのデータを取得し、hubotに投げるだけです。
※以降の処理はhubotでさせる。

GASでカレンダーに連携するのは下記のURLを参考にさせて頂きました。

Googleカレンダーにアクセスする(1/5):初心者のためのGoogle Apps Scriptプログラミング入門

※GASですが、非常に便利ですが、色々と罠(仕様)や不具合が潜んでいます。
※簡単お手軽で、サンプルを張ってちょっと修正して動いちゃうのですごく良いのですが
※そこだけを見ていると痛い目に遭いますので注意(今回の範囲ではなかったので記載しません)

//カレンダー連携
function googlecalender() {
    var calendarId = "抽出したいカレンダーのID";
    var cal = CalendarApp.getCalendarById(calendarId);
    var urlstr = "連携先のhubotのurl";

    // 現在時刻を生成
    var date = new Date();
    var d1 = new Date();
    d1.setMinutes(d1.getMinutes());
    var d2 = new Date;
    d2.setMinutes(d2.getMinutes() + 15);
    var evts = cal.getEvents(d1,d2);
    var body = "";

    if (evts.length > 0){
        for (var i in evts){
            var evt = evts[i];
            if(!evt.isAllDayEvent()){ //終日では無い場合
                var creators = evt.getCreators();
                var responsible = "@" + creators[0].slice(0,creators[0].indexOf("@")) + " (イベント作成者)";
                var guests = evt.getGuestsStatus();

                if (guests.length >= 1){//招待者(担当)が登録されていたら招待者を担当者として上書き

                    responsible = guests[0].getEmail()
                    responsible = "@" + responsible.slice(0,responsible.indexOf("@")) + " (招待者)"
                }
                var Id = evt.getId()
                var Title = evt.getTitle()
                var Description = evt.getDescription()
                var StartTime = Utilities.formatDate( evt.getStartTime(), 'JST', 'yyyy年M月d日HH時間mm分')
                var EndTime = Utilities.formatDate( evt.getEndTime(), 'JST', 'yyyy年M月d日HH時間mm分')
                var StartTimeInt = evt.getStartTime();
                StartTimeInt.setMinutes(StartTimeInt.getMinutes() - 3);//処理時間の誤差を許容する為に
                StartTimeInt = Utilities.formatDate( StartTimeInt, 'JST', 'yyyyMMddHHmm')
                var EndTimeInt = Utilities.formatDate( evt.getEndTime(), 'JST', 'yyyyMMddHHmm')

                var query =
                {
                    "Id" : Id,
                    "Title" : Title,
                    "Description" : Description,
                    "StartTime" : StartTime,
                    "EndTime" : EndTime,
                    "StartTimeInt" : StartTimeInt,
                    "responsible" : responsible,
                    "EndTimeInt" : EndTimeInt
                };

                var options =
                {
                     "method" : "post",
                     "payload" : query
                };
                UrlFetchApp.fetch(urlstr, options);
            }
        }
    }
}

な感じで、GASは実装させて頂きました。
実装の詳細ですが

var calendarId = "抽出したいカレンダーのID";
var cal = CalendarApp.getCalendarById(calendarId);

で、抽出したいカレンダーにアクセスします。

var date = new Date();
var d1 = new Date();
d1.setMinutes(d1.getMinutes());
var d2 = new Date;
d2.setMinutes(d2.getMinutes() + 15);

取得したい期間を作成し

var evts = cal.getEvents(d1,d2);

その期間のカレンダーデータを取得します。

evts.length

カレンダーのイベントがあるのかを確認し

for (var i in evts){

データがあればでループさせ、

var evt = evts[i];

一つ一つのカレンダー情報にアクセスします。

evt.isAllDayEvent()

カレンダーが終日かを確認し、終日でなければ

var creators = evt.getCreators();
〜
var EndTimeInt = Utilities.formatDate( evt.getEndTime(), 'JST', 'yyyyMMddHHmm')

hubotに投げる情報を作ります。

そして

                var query =
                {
                    "Id" : Id,
                    "Title" : Title,
                    "Description" : Description,
                    "StartTime" : StartTime,
                    "EndTime" : EndTime,
                    "StartTimeInt" : StartTimeInt,
                    "responsible" : responsible,
                    "EndTimeInt" : EndTimeInt
                };

                var options =
                {
                     "method" : "post",
                     "payload" : query
                };
                UrlFetchApp.fetch(urlstr, options);

でHubotのURLにカレンダー情報を投げます。

今回は③と④の情報を記載しました。

GASの"UrlFetchApp.fetch"での連携は非常に便利ですが

getとpostのみget/post/put/deleteの対応でpatchメソッド非対応なので使う方はちょっと検討する必要があります。

元記事はこちら

【cloudpack 大阪 BLOG】MSPのシステム化について Hubotでの状態管理(mysql)とGoogleカレンダーとslack連携 その1 – 雑なA型によるクラウドとモバイルと運営と