みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
Googleスプレッドシートを使って勤怠管理集計システムを作成しています。
前回の記事はこちらです。
スプレッドシート上に打刻データを元に月次の残業時間や深夜労働時間などを集計する勤怠管理シートを作成しました。
今度はその元になる打刻データをインプットする部分を作っていきます。
チャットワークで出勤や退勤に該当をするメッセージを送ることで、それを打刻としてシステムにインプットしていきたいと思います。
まずは、打刻チャットのベースになる部分として、Google Apps Scriptでチャットワークからの出勤・退勤の情報を受け取るスクリプトを作っていきます。
チャット打刻システムの概要
まずチャット打刻システムの概要について確認していきます。
最初にチャットワークで打刻専用のグループチャットを作りまして、「打刻チャット」と名付けます。
打刻をするメンバー全員がこの「打刻チャット」にメンバーとして参加していて打刻をします。ルールとしては以下を想定しています。
- 出勤時は「出勤」または「おはよう」を含むメッセージを送信する
- 退勤時は「退勤」または「お疲れ」を含むメッセージを送信する
- 出勤、退勤ともに先に投稿された時刻を正とし、後からの打刻は上書きせずに無視する
- 出勤がないときは退勤を無視する
- 修正は管理者のみスプレッドシートを直接修正する
チャットワークでのメッセージは打刻として、Googleスプレッドシートにデータとして蓄積されます。
こちらのシートです。
各カラムについて簡単に説明をしますと
- 打刻ID:日付、整数表示と社員IDの結合で自動付与される
- 日付:打刻に関する日付
- 社員ID:打刻をした社員のID、各社で取り決めをしているもの
- 区分:出勤、退勤以外のステータスに関しては別途対応
- 打刻(出社):出社時刻
- 打刻(退社):退社時刻
ということになります。
チャットワークから新たな日付×社員の打刻情報が送られてくれば、最終行に新たな行が追加される形になります。
打刻チャットからメッセージを取得する
さて、ではベースとなるGoogle Apps Scriptのスクリプトを紹介します。
まずはチャットワークの「打刻チャット」グループからメッセージを取得し、そのテキストに「出勤」「退勤」「おはよう」「お疲れ」というキーワードが含まれているかを判定して、その結果をログ出力するスクリプトです。
function recordTime(){ var params = { headers : {"X-ChatWorkToken" : '---------------------'}, //チャットワークAPIトークン method : "get" }; var roomID = XXXXXXXX; //ルームID var url = "https://api.chatwork.com/v2/rooms/" + roomID + "/messages?force=0"; //指定のグループチャットからメッセージを取得 try{ var respons = UrlFetchApp.fetch(url, params); //チャットワークAPIエンドポイントからレスポンスを取得 var json = JSON.parse(respons.getContentText()); //文字列をJSON形式として解析しJSONオブジェクトとして返す for each(var obj in json){ if(obj.body.match(/出勤/) || obj.body.match(/おはよう/)){ Logger.log("出勤"); }else if(obj.body.match(/退勤/) || obj.body.match(/お疲れ/)){ Logger.log("退勤"); } } }catch(e){ Logger.log('エラーが発生しました'); Logger.log(e.message); } }
以下で解説をしていきますね。
レスポンスがない場合はエラーをログ出力
9行目~28行目のtry~catch文について説明をします。
Google Apps Scriptからチャットワークを操作するために、チャットワークAPIを使用します。
今回、チャットワークからメッセージを取得するAPI
を叩くと、まだ取得していない100件までのメッセージを取得します。
しかし、APIをリクエストした場合に取得していないメッセージがゼロだった場合、そのレスポンスについて色々と処理する以降の命令でエラーが発生してしまいます。
それを回避するために、try~catch文を使います。
エラーがなければtryの中を実行し、エラーが発生すればcatchに処理を以降してエラーの内容をログ出力します。
tyr~catchについてはこちらの記事もご覧ください。
チャットワークの特定のグループからメッセージを取得する
10行目は、チャットワークの特定のグループチャットからメッセージを取得する処理になります。
Google Apps ScriptからAPIを利用するときは、UrlFetchAppに対するfetchメソッドを使います。
APIをたたいた返事としてJSON形式でメッセージを取得することができますが、それがresponsという変数に格納されるという処理になります。
ここで引数として指定するアドレスとパラメータについては、以下記事を参考ください。
受け取ったJSONを解析して配列に格納する
次に受け取ったレスポンスは以下のようなJSONの形式で受け取ることになるのですが、fetchメソッドで受け取った段階ではまだJSONオブジェクトとして取り扱えない状況です。
Google Apps Scriptで取り扱うようにするためにはJSON.parseメソッドを使ってJSONの解析と配列への格納をしなければなりません。
これをしている部分が11行目になりますね。
JSON.parseメソッドを使った後に以下のjsonオブジェクトとして取り扱いすることができるようになります。
[
{
"message_id": 5,
"account": {
"account_id": 123,
"name": "Bob",
"avatar_image_url": "https://example.com/ico_avatar.png"
},
"body": "Hello Chatwork!",
"send_time": 1384242850,
"update_time": 0
}
]
配列jsonの一つ一つの領域に、メッセージ一つ一つが格納されるという形です。
詳しくはこちらの記事もどうぞ。
matchメソッドで特定の文字列が含まれているかを判定
13行目から21行目のfor each文ですが、これは配列json内のメッセージ一つ一つについて繰り返せ、という命令になります。
その中身ですが、if文でobj.bodyつまりメッセージの中身を判断して
- メッセージに「出勤」「おはよう」が含まれていれば「出勤」をログ出力
- メッセージに「退勤」「お疲れ」が含まれていれば「退勤」をログ出力
- いずれでもなければ何もしない
という条件分岐となっています。
そこで、メッセージに特定の文字列が含まれているかどうかの判定としてmatchメソッドを使います。
これで、検査対象文字列内に検索文字列が含まれていれば、trueが返ります。
「/検索文字列/」の部分は正規表現と言いまして、”含まれる”以外の様々な判定もできます。
実行結果
以上のスクリプトを実行してみましょう。
まず、チャットワークの「打刻チャット」のグループでこのように4つのメッセージを投稿します。
次に上記Google Apps Scriptのスクリプトを実行して、ログ出力を確認すると
メッセージに対応した「出勤」または「退勤」がログ出力されていますね。
まとめ
Google Apps Scriptでチャットワークからの出勤・退勤の情報を受け取るスクリプトについてお伝えしました。
- チャットワークAPIでメッセージを受け取る
- UrlFetchApp.fetchメソッドでAPIを叩く
- JSON.parseメソッドでJSONを解析する
- レスポンスについてエラー判定をする
- メッセージに特定の文字列が含まれるか判定する
などのテクニックを使いました。
次回はチャットワークのメッセージの送信の日付そして時刻を取得していきます。
どうぞお楽しみに!