ENGINEER BLOG

ENGINEER BLOG

GAS part3 ハングアウトチャットの便利機能を使った業務改善

0.はじめに

はじめまして。グループC&I本部所属の磯部です。

突然ですが皆さん、Googleハングアウトが 「ハングアウトChat」と「ハングアウトMeet」に分割されるのはご存知でしょうか?

この機会にハングアウトチャットの機能を調べてみたところ、
botを利用できるようになったり、もちろんG Suiteと簡単に連携できるし、チャットルームを作れるし・・・
なかなか楽しそうな機能が追加されていました。

せっかくなので、追加された便利機能を使って業務改善しちゃいましょう。
従来のハングアウトではできなかった「bot × G Suite × チャット」を使用して
まずは手始めに、簡単なルーチンを通知する機能を実装してみましたのでご紹介します。

1.やりたい事

今回は、ついつい忘れがちな会議室の掃除当番というルーチンを
当番前日に担当者へハングアウトチャットで通知する、という機能を実装してみることにしました。

会議室の掃除は、定期的に社員が実施しています。
イレーザーの洗浄、インクの詰め替え、ホワイトボードの黒ずみ除去などとても地味な作業ですが、
社員のパフォーマンスを高める為に必須の作業です。自分たちが使う会議室ですから、気持ちよくしておきたいですよね。

・・・とは思いつつ、忘れてしまうこともあります。
というのも、我が部署では今まで当番の事前通知は行っておらず、スプレットシートで当番表を作成し各自が当番日を確認する、
という運用を行っていました。

  • スプレットシートを逐一確認するのが面倒…

  • せっかくスプレットシートを使用しているので、 これを活かして事前通知を設定したい!

  • 少しでも自動化して、業務に時間を割きたい!

  • なんなら業務で活用できるように勉強しておきたい!

当番を忘れないようになる上に、新しい機能を勉強できる良いチャンスです。さっそく実装してみましたのでみていきましょう。

◎当番は、週2回、2か所の会議室を2名で担当する、とします。

2.実装

今回の実装では、ハングアウトチャットとスプレッドシートの2つに手を加えていきます。

まずは、ハングアウトチャット側です。

①ハングアウトチャット

①-1)チャットルームを作成

まずは、ハングアウトチャットの「ユーザー、チャットルーム、bot」をクリックし、 「チャットルーム作成」を続けて選択します。

2020-02-14-11-00-33

①-2)Webhook エンドポイントの作成をする。

次に、Webhookの設定を行います。

Webhookとは簡単に言うと、イベント発生時に指定したURLにPOSTリクエストする仕組みのことです。
ここで設定したURLを、後述のスクリプト側でメッセージ送信の宛先として指定することで、プログラムからイベントが実行された際に、このチャットルームへ通知が送られるようになります。

チャットルーム名を押下するとメニューが開くので、「Webhookを設定」を選択します。

2020-02-14-11-01-37

Webhookの設定では、以下を設定できるので、作成する際の目的に応じて設定します。

名前:botの名前を設定出来ます。後で変更可能です。
    ここでは「おしらせちゃん」と命名しておきましょう。

アバターのURL:botのアバター(画像)を設定出来ます。設定は省略可能です。

設定が完了したら「保存」を押下します。

2020-02-14-11-02-24

すると、設定したWebhookのURLが作成されるので、このURLをコピーして記録しておきましょう。
スプレッドシートのソース内で記述することになります。

ハングアウトチャット側の実装は以上です。

次に、スプレッドシート側に処理を加えていきます。

②スプレッドシート

②-1)スプレットシートで担当表を作成する

まずは、スプレッドシートで「担当一覧」シートを作成します。
日付列には日付を、会議室列には各日付で会議室を担当する人の名前を記入します。

※①②があるのは当番が2人必要であるため

2020-02-14-11-03-44

②-2)スクリプト編集

次に作成したスプレッドシートのスクリプトを編集していきます。

②-2)-1.作成したスプレットシートの「ツール」タブから、「スクリプトエディタ」を選択し、開きます。

②-2)-2.表示されたスクリプトに実装したいソースを書き込んでいきましょう。
実装したい事をソース内では、以下のように表しています。

1  function main(){
2
3   // スプレッドシートIDとシート名を入力
4   var ss = SpreadsheetApp.openById('※ここにスプレットシートID');
5   var sh = ss.getSheetByName('担当一覧');
6  
7   // 明日の日付を取得する
8   var date = Moment.moment();
9   var tomorrow = date.add(1, 'days'); //現在日時 + 1日
10  
11  // 明日の日付を月と日だけでフォーマット
12  var tomorrow_dateOnly = tomorrow.format('MM/DD');
13  
14  // 最終行の番号を取得する
15  var lastRow = sh.getLastRow();
16  
17  // 担当者名を格納する空の変数を作成
18  var assignedStaff1 = '';
19  var assignedStaff2 = '';
20  
21  // 担当者一覧表を二次元配列で取得する
22  var table = sh.getRange(2,2,lastRow,4).getValues();
23  
24  // 二次元配列table内の日付を一つ一つループで調べる
25  for(var i = 1; i < table.length; i++) {
26    
27    // 二次元配列内の日付をフォーマットする
28    var tableDate = Moment.moment(table[i][0]);
29    var tableDate_dateOnly = tableDate.format('MM/DD');
30    
31    // 明日の日付と同じ場合、担当者名を変数assignedStaffに格納する
32    if(tableDate_dateOnly === tomorrow_dateOnly){
33      assignedStaff1 = table[i][1] ;
34      assignedStaff2 = table[i][2] ;
35    }
36  }
37  
38  // 当番担当が書き込まれている場合、通知する
39  if (assignedStaff1 !== '' && assignedStaff2 !== '' )  {
40      
41    // 通知メッセージ
42    var text = '【明日(' + tomorrow_dateOnly + ')は会議室当番!】' + '\n'
43             + '会議室当番は' + assignedStaff1 + 'さん・' + assignedStaff2 + 'さんです!' + '\n'
44             + 'よろしくおねがいします◎';
45      
46    // ペイロード        
47    var payload = {
48   'text' : text
49   }
50   
51    // エンコード
52    var json = JSON.stringify(payload);
53
54    // WebhookURL
55    var url = '※ここにwebhookURL';
56 
57    // ポストするためにヘッダーとかボディをまとめて入力
58    var options = {
59    'method' : 'POST',
60    'contentType' : 'application/json; charset=utf-8',
61    'payload' : json
62    }
63 
64    // 送信! 
65    var response = UrlFetchApp.fetch(url, options); 
66  }
67  
68 }

3-5行では、「担当一覧」シートを定義します。

スプレットシートID:担当表を記載したスプレットシートのURLの /d/と/editの間 がスプレットシートIDとなります。
例)https://docs.google.com/spreadsheets/d/ここがスプレットシートID!/edit…
シート名:担当一覧が記載されているシート名を記入する。

// スプレッドシートIDとシート名を入力
var ss = SpreadsheetApp.openById('※ここにスプレットシートID');
var sh = ss.getSheetByName('担当一覧');

7-12行では、明日の日付を取得し、MM/DDの形にします。

日付の取得は「Moment.js」ライブラリを導入して使用します。
tomorrowという変数に、date.addで明日の日付を取得し格納します。
(※明日の会議室の当番が誰かを知りたいので、明日の日付を取得しています。)
そして、.formatメソッドを用いて、取得した日付をMM/DDの形に生成しています。

参考:日付&時刻の便利ライブラリ「Moment.js」をGoogle Apps Scriptで使う方法

// 明日の日付を取得する
var date = Moment.moment();
var tomorrow = date.add(1, 'days'); //現在日時 + 1日
  
// 明日の日付を月と日だけでフォーマット
var tomorrow_dateOnly = tomorrow.format('MM/DD');

14-36行では、担当者一覧表を二次元配列で取得しています。

まずtable変数に、担当者一覧表を二次元配列で取得します。
次に、明日の日付とtable変数に格納されている担当者一覧表の日付が一致するまでfor文で反復します。
そして、明日の日付と担当者一覧表の日付が一致した場合、会議室当番①・会議室当番②の値を変数assignedStaffに格納します。
二次元配列を活用する事によって、APIの使用回数を大幅に減らす事が出来、処理を素早く完了させることが出来ます。

// 最終行の番号を取得する
var lastRow = sh.getLastRow();
   
// 担当者名を格納する空の変数を作成
var assignedStaff1 = '';
var assignedStaff2 = '';
   
// 担当者一覧表を二次元配列で取得する
var table = sh.getRange(2,2,lastRow,4).getValues();
   
// 二次元配列table内の日付を一つ一つループで調べる
for(var i = 1; i < table.length; i++) {
     
    // 二次元配列内の日付をフォーマットする
    var tableDate = Moment.moment(table[i][0]);
    var tableDate_dateOnly = tableDate.format('MM/DD');
    
    // 明日の日付と同じ場合、担当者名を変数assignedStaffに格納する
    if(tableDate_dateOnly === tomorrow_dateOnly){
       assignedStaff1 = table[i][1] ;
       assignedStaff2 = table[i][2] ;
    }
}

38-66行では、ハングアウトチャットに通知を送る設定をしています。

for文で取得した、「会議室当番①」「会議室当番②」の値が空白でなければチャットに通知が来るようにます。
送信するメッセージの内容はtext変数に格納します。
また、データを送信するためのPOSTリクエストとしてpayloadも定義しておきます。
そして、.fetchメソッドを用いて、初めに取得してコピーしておいたwebhookのURLに送るようにします。

// 当番担当が書き込まれている場合、通知する
if (assignedStaff1 !== '' && assignedStaff2 !== '' )  {
        
    // 通知メッセージ
    var text = '【明日(' + tomorrow_dateOnly + ')は会議室当番!】' + '\n'
             + '会議室当番は' + assignedStaff1 + 'さん・' + assignedStaff2 + 'さんです!' + '\n'
             + 'よろしくおねがいします◎';
        
    // ペイロード        
    var payload = {
   'text' : text
    }
   
    // エンコード
    var json = JSON.stringify(payload);
  
    // WebhookURL
    var url = '※ここにwebhookURL';
   
    // ポストするためにヘッダーとかボディをまとめて入力
    var options = {
    'method' : 'POST',
    'contentType' : 'application/json; charset=utf-8',
    'payload' : json
    }
   
    // 送信! 
    var response = UrlFetchApp.fetch(url, options); 

これで、スクリプトの編集は完了です。

②-3)トリガーを設定する

最後に、スクリプトが起動するための詳細を設定していきます。
「編集」タブ内の「現在のプロジェクトのトリガー」を押下します。

2020-02-14-11-07-21

トリガーはfunctionごとに設定出来ますが、今回は「main」のみなので「main」を選択します。
また、毎日午後6時~7時の間に起動させたいので、下記のように指定し「保存」を押下します。

2020-02-14-11-08-07

以上で、実装は完成となります。

3.結果

実際に起動してみると、以下のような連絡が「おしらせちゃん」botから来るようになりました。
※testのため手動で動かしたので時間が13:06となっています。

2020-02-14-11-09-23

実際に運用してみて、

  • 前日に通知があることで、翌日のスケジュールをくみやすくなった。
  • 急遽交代をお願いしたい場合の連絡が取りやすくなった。

との感想が。当番の担当者からも好評なようで一安心です。

また、今までスクリプト言語のソースを書く機会があまり無かったので、
スクリプト言語を学びながら業務改善が出来、一石二鳥でした。

4.まとめ

今回はブログ用ということで簡単なルーチンの通知としましたが、
ハングアウトチャットはここで紹介した機能以外にも、
ファイルを投稿できたり、自分宛にチャットができたりと、便利機能がまだまだあります。
ハングアウトチャットやGASを活用して、
同じメンバーへの定期的なメールや締切前のリマインド機能など、単純作業をどしどし自動化=業務改善すべく、引き続き研究していきたいと思います。

GASに関する記事は他にもありますのでご覧ください。

【過去の関連記事】

Google Apps Scriptで問合せ履歴を自動管理してみた

GAS part2 実績管理もっと楽をしたい!

HangoutChatでチャットボットを作ってみる

最後までお付き合いいただきありがとうございました。
本記事の執筆に当たって、小出さん、渡邉(洋)さん、本橋さん、中嶋さん、村石さん、太田さんに協力して頂きました。