このエントリーは、家庭を支える技術 Advent Calendar 2016 - Adventar の2日目の記事として書きました。
昨年までとは、趣きを変えて、家庭内における連絡手段の冗長化についてです。
家庭内チャットについて
我々のチームでは、チャットサービスとして以下のサービスを利用しています。
- slack
- LINE
- chatwork
使い分けとしては、帰宅の連絡など普段のコミニケーションとしてはLINE、Calendarやtodoの共有、事案メールの通知などにはslackという感じになっています。
chatworkは、slack導入までは、メインに使っていましたが、今は、家庭内の連絡に使うことはほぼなくなっています。ただし妻が仕事で利用しているので、妻としては見やすいということで、アカウントはそのままになっています。
気づかない問題
どれか一つの方法でだけ連絡した場合、気づかないときには、全然気づかず、レスポンスがすぐ欲しいときに困ることがありました。
もちろん、緊急のときは、電話を鳴らしたりもしますが、それも気づかないということがあったりもしました。*1
マルチポストしたい
複数の経路をもっているので、マルチポストできれば、どれかには、気づいてもらえるかもしれません。
そこで、どこか一つに書くとそれをよしなに他のチャットにも書き込んでくれる仕組みを作りました。
実装のはなし
今回は、slackの特定のchannelに書き込むと、Outgoing Webhookによって、その内容を GCPの Cloud Functionsの http trigger に送り、Cloud Functionsが LINE Notifyと chatworkの APIをキックして、内容を書き込んでくれる仕組みを整えました。
/** * HTTP Cloud Function. * * @param {Object} req Cloud Function request context. * @param {Object} res Cloud Function response context. */ var request = require('request'); var config = require('config'); var lineConfigAccessToken = config.Line.access_token; exports.sendLineNotify = function sendLineNotify (req, res) { var options = { url: 'https://notify-api.line.me/api/notify', method: 'POST', headers: { 'Content-Type':'application/x-www-form-urlencoded', 'Authorization': 'Bearer ' + lineConfigAccessToken, }, form: { message : `${req.body.text}` } }; // request LINE Notify request(options, recallback); function recallback(error, response, body) { if (error == true) { console.log(body); } } res.send('ok'); };
/** * HTTP Cloud Function. * * @param {Object} req Cloud Function request context. * @param {Object} res Cloud Function response context. */ var request = require('request'); var config = require('config'); var chatworkConfigRoomId = config.Chatwork.room_id; var chatworkConfigApiToken = config.Chatwork.api_token; exports.sendChatwork = function sendChatwork (req, res) { var options = { url: 'https://api.chatwork.com/v1/rooms/' + chatworkConfigRoomId + '/messages', method: 'POST', headers: { 'Content-Type':'application/x-www-form-urlencoded', 'X-ChatWorkToken': chatworkConfigApiToken, }, form: { body : `from_slack [${req.body.user_name}]: ${req.body.text}` } }; // request Chatwork API request(options, callback); function callback(error, response, body) { if (error == true) { console.log(body); } } res.send('ok'); };
その他packegeなどをふくめたソースは↓
Outgoing Webhookのリクエストを受取り、LINE Notifyとchatwork API のエンドポイントにPOST requestを送るだけで完了です。
APIをcallした時のエラーハンドリングなどをほぼしていないので、異常系の処理ができていないですが、正常系は問題なく稼働しています。
プロトタイプ
slackにherokuで動かしているhubotがいたので、はじめは、hubotのscriptを実装して、意図通り動くところまでのプロトタイプを作りました。
# Description: # Emergency bot # # Commands: # emergency channel hear # # Author: # tknzk module.exports = (robot) -> robot.hear /.*/, (res) -> room = res.envelope.room text = res.message.text console.log room console.log text if room == 'emergency' # line request = res.http("https://notify-api.line.me/api/notify") .headers("Authorization": "Bearer " + process.env.HUBOT_LINE_NOTIFY_API_TOKEN) .headers("Content-Type": 'application/x-www-form-urlencoded') .post("message=" + text) request (err, resp, body) -> if err res.send err else if body.length == 0 res.send "Failed " else res.send body # chatwork request = res.http("https://api.chatwork.com/v1/rooms/" + process.env.HUBOT_CHATWORK_ROOM_ID + "/messages") .headers("X-ChatWorkToken": process.env.HUBOT_CHATWORK_API_TOKEN) .headers("Content-Type": 'application/x-www-form-urlencoded') .post("body=" + text) request (err, resp, body) -> if err res.send err else if body.length == 0 res.send "Failed " else res.send body
ただ、それではあんまりにも技術的な進歩がなさすぎたのと、昨今の流行りからお手軽に試すにはserverlessでしょうということでCloud Functionsで実装してみました。
AWS lambda を選ばなかったのは、趣味の問題です。*2 *3
さて、動作的には、↓のようなかんじになります。slackの特定のchannelに書き込むと同じものがLINEとchatworkに転送されます。
まとめ
チャットを確実に受け取りたいということで、Cloud Functionsでマルチポストを実装してみました。
Advent Calendar Drivenで開発したので、実は運用はまだ行っていないのが実情です。。
なので、今日から運用開始です。