会議室の"あるある課題"を解決 「Robin」を導入し会議室の予約管理を効率化
IT推進室の小笠原です。フォルシアでは、紙の電子化、イントラ改修など業務効率化のための施策を検討し、日々改善を行っています。
最近導入したツールで社員の評判が良かったのは、会議室の管理を効率化する「Robin」。フォルシアではこれまでGoogleカレンダーを使って会議室の予約管理を行っていましたが、この「Robin」の導入によって利用効率の改善が図られました。今回は、まだ日本語の情報が少ない「Robin」について導入方法をご紹介します。また、自社向けのカスタマイズとして、GAS、Slackと連携させた通知機能を実装したので、あわせて参考にしていただければ幸いです。
会議効率化ツール「Robin」って?
会議室でこういった「あるある」ありませんか?
「会議室、空いてたから予約したのに使われてる...」
「あー予約したかったのに埋まってる...あれ?時間過ぎてるのに誰も使ってなさそう」
どうでしょう?フォルシアでは、こういった状況をたまに見かけていました。
ただ正直、5分くらい軽く話したい時や、定例など毎週やっている会議のスキップを毎回カレンダーで調整するのは面倒ですよね(自分もそうなんです)。
そこで、この状況を解決するためのシステムが「Robin」です。
Robinって何ができる?
- Robinタブレット用アプリの「Room Display App」をタブレットにインストールしてワンタッチで会議予約、開始、終了を管理できる
- Googleカレンダーに登録している会議室カレンダーとの連携が可能
- APIで各会議の情報にタッチできる
- 無料トライアルもあり(14日間はフルに使え、それ以降は制限)
タブレット画面
- 予約が入っていないとき
- 会議予定時間になった時
- 会議予定時間後、Check inを押して会議を開始した時
あるある問題を解決するには
「会議室、空いてたから予約したのに使われてる...」
タブレットから15、30、60minutesといった時間をタップすれば、簡単に会議室カレンダーに予定が入ります。これでタップさえすれば予約なし会議室利用は解決です。
「あー予約したかったのに埋まってる...あれ?時間過ぎてるのに誰も使ってなさそう
Robinにはブラウザのダッシュボード画面があり、○○分間「check in」されていなければ会議の予定を自動削除させるという設定があります。これで予約はあるが誰もいないゴースト会議も解決です。
運用での懸念点
会議の自動削除を運用するためには、必ず参加者に「check in」を押してもらわなければなりません。しかし、忘れてしまう可能性はやはりあります。
そこで、 「check in」押してないよーという通知音をタブレットで鳴らすリマインド通知機能をGASで実装しました。加えて会議時間を超過しての利用も問題になっていたので、会議終了の合図となるように終了通知も実装しました。Robinには通知音をタブレットで鳴らせる機能はないため、今回はGASからSlackにメッセージを送ることによって通知音を鳴らせています。
GASで通知機能を実装
通知でやりたいことは次の2つです。
- 会議開始5分後から10分後まで「check in」のリマインド(10分過ぎると会議削除)
- 会議終了5分前と終了時間の通知
実装
実装の概要はこんな感じです。
- Google Apps Scriptで記述した下記のような関数をトリガーで1分毎に回します
- 1日の会議室カレンダーの予定を取得
- 会議開始5分後の時点で「check in」が押されていなければ10分後まで1分間隔でタブレットにSlackメッセージ
- 会議終了5分前と会議終了時間でタブレットにSlackメッセージ
function CheckCheckin () { var today = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy-MM-dd'); var jsonData = GetRobinData(today); var data = jsonData.data; //dataにはその日の予定(event)が配列として入っている var overMinutes = 5; // 通知開始時間 var abandonMtgTime = 10; // 通知終了時間 var now = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'HH:mm:00+0900'); for(var i in data) { NoticeToRobin(now, data[i], overMinutes, abandonMtgTime); } } // RobinAPIから予定を取得 function GetRobinData(today) { var after = 'after=' + today + 'T00%3A00%3A00%2B09:00'; var before = 'before=' + today + 'T24%3A00%3A00%2B09:00'; var spaceId = [id]; //idについては後述 var url = 'https://api.robinpowered.com/v1.0/spaces/' + spaceId +'/events?'; var fullUrl = url + after + '&' + before; //何時から何時までの予定を取得するかパラメータに付け加える var options = { 'headers': { 'Authorization': 'Access-Token [Robin-Token]' //Robin-Tokenについては後述 }, 'method': 'get', 'contentType': 'application/json', }; var json = UrlFetchApp.fetch(fullUrl, options).getContentText(); //リクエスト var jsonData = JSON.parse(json); return jsonData; } function NoticeToRobin(now, data, overMinutes, abandonMtgTime) { //開始時刻5分後から10分後までcheck in状態をチェック for(var minutes = overMinutes; minutes < abandonMtgTime; minutes++) { var startDateTime = new Date(data.start.date_time); startDateTime.setMinutes(startDateTime.getMinutes() + minutes); startDateTime = Utilities.formatDate(startDateTime, 'Asia/Tokyo', 'HH:mm:00+0900'); var confirmation = data.confirmation; if(startDateTime === now && confirmation === null) { //nullなら未check in。check inしていればcheck in情報が入る。 PostSlackMessage('@robin please check in'); } } } function PostSlackMessage(message) { var token = [Slack-Token]; var slackApp = SlackApp.create(token); //GASライブラリ「SlackApps」を利用 var channelId = "general"; var options = { link_names: 1, username: 'robin' }; slackApp.postMessage(channelId, message, options); }
※ 終了時刻の通知はCheckChekinとNoticeToRobinを下記のように書き換えてください。
function CheckEndMeeting () { var today = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy-MM-dd'); var jsonData = GetRobinData(today); var data = jsonData.data; var now = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'HH:mm:00+0900'); var beforeEndTime = 5; //会議終了の5分前に通知 for(var i in data) { NoticeToRobin(now, data[i], beforeEndTime); } }
function NoticeToRobin(now, data, beforeEndMinutes) { var endDateTime = new Date(data.end.date_time); var justEndTime = Utilities.formatDate(endDateTime, 'Asia/Tokyo', 'HH:mm:00+0900'); endDateTime.setMinutes(endDateTime.getMinutes() - 5); var beforeEndTime = Utilities.formatDate(endDateTime, 'Asia/Tokyo', 'HH:mm:00+0900'); if(beforeEndTime === now) { PostSlackMessage('@robin end time before 5 minutes'); } else if (justEndTime === now) { PostSlackMessage('@robin end time'); } }
「後述」の説明
var spaceId = [id];
関数GetRobinDataでは会議室のeventsを取得するために下記RobinAPIを使っています。
var url = 'https://api.robinpowered.com/v1.0/spaces/' + spaceId +'/events?';
spaceIdとはRobinに紐づけた会議室のidで、Robinダッシュボード画面から確認できます。
確認方法はというと、下記URLからダッシュボード画面を開きます。
※[organization]は登録時に「organization's Robin domain」として登録したidです。
ダッシュボード画面を開いたら下記のように順番に辿り、会議室ページのURL末尾に数字が書かれています。それが「spaceId」になります。
- 「Manage」→ 「Office」→ 「locations」の歯車マーク→ 登録した会議室の歯車マーク
'Authorization': 'Access-Token [Robin-Token]'
ヘッダーの[Robin-Token]ですが、こちらもダッシュボード画面から取得できます。下記URLの下部に「API Tokens」があり、「Generate new token」で発行できます。
トリガーの設定
関数にトリガーを設定すればあとはGASがやってくれるので、これでタブレットを会議室に設置できます。自身が書いたGoogle Apps Script画面の「編集」→ 「現在のプロジェクトのトリガー」をクリックすると、プロジェクトページに遷移します。
プロジェクトページ右下の 「トリガーの追加」をクリックし以下のように設定します。
- 実行する関数を選択
- CheckCheckin (CheckEndMeeting)
- イベントのソースを選択
- 時間手動型
- 時間ベースのトリガーのタイプを選択
- 分ベースのタイマー
- 時間の間隔を選択
- 1分おき
さいごに
今回の実装のようにAPIがあればそれぞれのシステムを連携できるので、システム単体ではできないことも工夫次第で実現できます。使う用途、状況に沿ったシステムにカスタマイズしていくこと・システム的にカスタマイズできることが大切ですね。
また、GASを使うことによって自前のサーバが必要なく、cronのような日時実行もGUIでサクッとできることがとても便利です。共有も簡単で属人化も防ぐことができるので積極的に使って行くのがいいですね。
小笠原優
2016年新卒入社、エンジニア
IT推進室にて、kintoneなどの外部サービスを使った業務改善、業務効率化を主に担当