開発
【GAS】Googleスプレッドシートで管理している当番表をメンション付きでCisco Webex Teamsに定期的に通知する
Junichi Fujinuma
藤沼です。Eyes, JAPANでは毎週木曜日に勉強会を行う取り組みを長年続けています。このブログと同様に毎回一人の担当者(person in charge)を割り当てており、持ち時間は30〜35分間(30分未満はNG)。外国人スタッフが過半数を占めるため、原則英語。テーマは、技術はもちろんのこと、イベント参加報告や趣味などもOKであり、特に厳しい制約は設けていません。
この条件は学生スタッフも一緒です。社会人でさえ慣れていない人にとっては人前で日本語で10分間話すのも大変なので「30分間英語でプレゼン」というのはなかなかチャレンジングな環境です。事実、苦労しているスタッフも少なくありません。私は過去に日系大企業と外資系コンサルに在籍しており、そこでも有意義な勉強会は開かれていましたが、それらの環境と比較してもEJは面白いことを続けているなと思います。英語が流暢かどうかはさておき、定期的に「英語で伝えようとする」機会が巡ってきますので、英語が苦手な人にとっても刺激を受ける場になっているようです。
チームの課題は「仕組み」で解決する
さて、弊社では勉強会とブログの当番表をGoogle Sheets(Googleスプレッドシート)で管理しています。私の前任までは、基本的には「シートを自分で見て自分の当番を確認してもらう」スタンスでいたのですが、どうしても忘れる(あるいは認識していない)スタッフが少なからず出ていました。
前々からこの課題が気になっていた私は引き継ぎを受けて暫くした頃に「当番表の今後●週間分の担当者を取得してメッセージングツールに連携する」簡易的なbot(のようなもの)を作ろうと思い立ちました。実装にあたってはQiitaの「Google Apps Scriptで朝礼当番と掃除チームをSlackに連携・通知する」を参考にさせて頂きました。
弊社ではSlackではなくCisco Webex Teamsをコミュニケーションツールとして使用しているのですが、Cisco Webex Teamsにおけるインテグレーションに関しては日本語のリソースがまだ充実していない気がします。この記事ではWebex Teamsへのインテグレーション手順を簡単に解説します。
Webex App HubでIncoming WebhooksのURLを生成する
Slackと同様、WebexにもCisco Webex App Hubという各種インテグレーション用のポータルがあり、その中にIncoming Webhooksがあります。
設定も特段難しいことはなく、Webex App Hubにログインし、Incoming Webhooksの画面で「名称(Webex Teams上の表示名)」と「どのスペースに追加するか」を設定する事でWebhook URLが生成されます。
スプレッドシート/GASでメッセージの定義・生成・連携をする
あとはスプレッドシートやGoogle Apps Script側で、通知するメッセージ内容の定義/整形や連携処理を書きます。Webexでのメンションはメールアドレスで指定ができます。Slackでは user_id での指定が必要なので、それに比べると管理・運用がちょっとだけ楽です。
参考までに、スプレッドシートは以下の様なフォーマットにしています。管理上の都合で一部隠しているカラムがありますが、D列で担当者名を入力(選択)すると、O列に連携用のメッセージが生成されるようにしています。ここはGASで書いてしまっても良いところではありますが、私の場合はExcelに慣れていることもあり関数を使ってスプレッドシート上で解決してしまっています。(個人的にはこのほうが可読性・メンテ性が高い、という考えもあり。)
スクリプトはこんな感じです。
/* ---------------------------------------- / スプレッドシートとWebex Teamsの連携用 / ---------------------------------------- */ function notifyEventsToWebexTeams() { // スプレッドシートを指定 var obj = SpreadsheetApp.openById('スプレッドシートのID'); Logger.log(obj); // シートを指定 var sht = obj.getSheetByName("シートの名称"); Logger.log(sht); // 探索範囲の開始日・終了日 var dateToday = new Date(); // 本日の日付を取得 var date21day = new Date(dateToday.getYear(), dateToday.getMonth(), dateToday.getDate() + 21); // 21日後の日付を取得 // スプレッドシートの日付列をチェックして探索範囲内のイベントのメッセージ本文を取得する var row, eventmsg = "", msgbody = ""; for(row = 17; row <= sht.getLastRow()-1; row++){ // 開始行(17行目)〜最終行を1行ずつチェック var dateEvent = sht.getRange(row,2).getValue(); // イベント日付(B列)を取得 if(dateToday <= dateEvent && dateEvent <= date21day){ // イベント日付が探索範囲内であれば次の処理を実行 var eventmsg = sht.getRange(row,15).getValue(); // Webex Teamsに連携するメッセージ(O列)を取得 Logger.log(eventmsg); //デバッグ用 console.log(eventmsg); //デバッグ用 msgbody = msgbody + '<br />' + eventmsg; // 改行を挟みつつメッセージ本文を連結 } eventmsg = ""; // 次の処理に向けて空に。 } Logger.log(msgbody); //デバッグ用 console.log(msgbody); //デバッグ用 // メッセージ本文にスプレッドシートのURLを連結 var allMsg = ""; allMsg = '[Coming up PIC]'+msgbody+'<br /><br />'+'Check the schedule and fill your theme on spreadsheet.<br />https://docs.google.com/spreadsheets/d/スプレッドシートのURL<br />'; Logger.log(allMsg); //デバッグ用 console.log(allMsg); //デバッグ用 // Webex Teamsにおける連携先のWebhook URLを指定。(Incoming Webhooks) // https://apphub.webex.com/my-integrations にて確認。 var url = "https://api.ciscospark.com/v1/webhooks/incoming/xxxxxxxxxxxxxxxxxxxxxxxx"; // ヘッダの指定(-Hオプションの中身) var headers = { "Content-type": "application/json" } // ヘッダの指定(-dオプションの中身) var data = { "markdown": allMsg } // オプションの指定 var options = { "method": "post", "payload": JSON.stringify(data), "headers": headers }; UrlFetchApp.fetch(url, options); }
GASを定期的に実行させる
ここまで来ると敢えて書くほどのことでもありませんが、上記のスクリプトに対する時限式トリガを設定します。
Webex Teamsにて連携結果を確認する
という訳で無事、メンション付きで通知が来ました。
なんだかSlack一強みたいな状況ですが、そんな状況下でも敢えてSlackを脱却しWebex Teamsに移行した弊社としては、Slackに負けないようなインテグレーションを進めたいところでして、常日頃から効率化・高度化を心掛けています。