hubotを使ってhipchat上であれこれする
hubot hipchat
やりたいこと
チャットアプリのhipchatとボットとして動くhubotを使って、下記の事をしてみようと思い、設定してみました。 社内にあるubuntuでhubotを起動して、hipchat上にボットとして常駐させるようにします。
運用するサイトに対する問い合わせが届いた際にチャットに通知する。
- 不具合の問い合わせが複数回来た場合は携帯端末にpush通知する。
- テキストスピーチで読み上げて社内のスピーカーで出力する
AWSで作業した履歴をチャットに通知する(履歴はCloudTrailで収集する)
処理の流れ
データ処理の流れは以下を想定しています。
- 問い合わせ
転送 ポスト 監視 読み上げ Gmail------>MTA------>hipchat<---->hubot--->シェル(open_jtalk) | |push通知 | 携帯端末
- AWSのログ
AWS ポスト ポスト cloudtrail ----------->hubot---------->hipchat sns
設定
下記は設定の記録です。
hipchat
部屋名をcontact,awsとして作成して、その部屋のRoom Notification Tokensも作成します。
hubot
社内のubuntuマシンにhubotをインストールしてひな形アプリも作成します。 hubotがログインの際に使うアカウントも作成して、起動確認まで行います。
$sudo apt-get install node $sudo npm install -g hubot coffee-script $sudo npm install -g yo generator-hubot $mkdir -p examplebot $cd examplebot $yo hubot [?] Owner: app [?] Bot name: examplebot [?] Description: (A simple helpful robot for your Company) hogehoge [?] Bot adapter: (campfire) hipchat $ cat hubot_env export PORT=5555 export HUBOT_HIPCHAT_JID=xxxx_xxxx@chat.hipchat.com export HUBOT_HIPCHAT_PASSWORD=xxxx export HUBOT_HIPCHAT_ROOMS=xxxx_contact@conf.hipchat.com,xxxx_aws@conf.hipchat.com $ source hubot_env $ ./bin/hubot -a hipchat
問い合わせの対応
hipchatに問い合わせ内容をPOSTする
Gmailに転送設定をつけてMTAサーバにメールを転送します。 その後、/etc/aliasesに設定されたスクリプトが起動してhipchatにpostするようにします。
* /etc/aliases contact: :include:/home/ec2-user/contact * /home/ec2-user/contact "| ruby contact.rb"
- /home/ec2-user/contact.rb
#!/usr/bin/env ruby # -*- encoding:utf-8 -*- require 'hipchat' require 'mail' token = "xxxxxxxxxx" room = "contact" sender = "contact" mail = Mail.new(STDIN.read) body = mail.body.decoded.encode("UTF-8", mail.charset) client = HipChat::Client.new(token, :api_version => 'v2') client[room].send(sender, body)
問い合わせ内容を読み上げる
contact部屋にメッセージが追加されたら読み上げソフトウェアであるopen_jtalkを起動するようなスクリプトをhubotに追加します。
- examplebot/scripts/contact.coffee
# Commands: # hubot contact # # Commands: # hubot contact - spawn = require('child_process').spawn module.exports = (robot) -> ROOM = ["contact"] # hipchatの部屋名 SENDER = ["contact"] # hipchatのRoom Notification Tokensで設定したlabelに該当 ENABLE = "contact_enable" # 読み上げるか読みあげないか(reidsのキー名) ERROR_COUNTER = "contact_error_counter" # 不具合報告のカウント数(reidsのキー名) REPORT_COUNT = 5 # この回数以上の不具合報告を受けたらpush通知 MEMBERS = "@foo @bar" #push通知する対象のhipchatユーザ correct = (a, b) -> return true if a.join(" ").match(///#{b}///i) return false robot.hear /^off/i, (msg) -> return unless correct(ROOM, msg.message.room) robot.brain.set(ENABLE, 0) msg.send("読み上げを無効にしました。") robot.hear /^on/i, (msg) -> return unless correct(ROOM, msg.message.room) robot.brain.set(ENABLE, 1) msg.send("読み上げを有効にしました。") # msg.match[1]] 問い合わせの本文 robot.hear /^(.*)$/i, (msg) -> return unless correct(ROOM, msg.message.room) \ and correct(SENDER, msg.message.user.name) \ and robot.brain.get(ENABLE) == 1 # 不具合報告のような問い合わせがREPORT_COUNT回届いた時にpush通知を試みる。 # 不具合報告が多い時はpush通知が連続されるのでトラブルとすぐに認識したい。 if /(エラー|サーバ|重い)/.test(msg.match[1]) cnt = robot.brain.get(ERROR_COUNTER) cnt ?= 0 if cnt > REPORT_COUNT # @fooをつけることでメンションとなり、push通知されるみたい。 msg.send(MEMBERS + " サーバトラブルのお問い合わせを受信") robot.brain.set(ERROR_COUNTER, (cnt++ % REPORT_COUNT)) # 必要ないものは読み上げない return if msg.match[1].length < 10 || /(NGワード)/.test(msg.match[1]) #読み上げ args = ['./bin/talk', "お問い合わせがきました。"+ msg.match[1]] cli = spawn('/bin/bash', args, {setsid: true}) cli.stderr.on 'data', (data) -> console.log('cli stderr: ' + data.toString())
- examplebot/bin/talk
#!/bin/sh # yukkuri #[ -f $yukkuri ] && echo $2 | $yukkuri | aplay # jtalk f=`mktemp` wav=`mktemp` score=$1 echo $2 > $f emp="normal" dic_dir="/var/lib/mecab/dic/open-jtalk/naist-jdic/" voice="/home/app/MMDAgent_Example-1.4/Voice/mei/mei_${emo}.htsvoice" open_jtalk -u 0.0 -jm 0.7 -jf 0.5 -a 0.55 -r 1.2 -m $voice -x $dic_dir -ow $wav $f [ -s $wav ] && aplay $wav exit 0