この記事の概要:
- hubotでボットをコーディングする環境を作って
- chatworkから操作できるようにして
- shellのファイルを実行できるようにして
- それをデーモンにする。
install hubot with chatwork adapter
install node*1
brew install node
install yo generator-hubot*2
npm install -g yo generator-hubot
install coffee. hubotのスクリプトの多くはcoffeeで書かれているみたい。
npm install -g coffee-script
他にredisも必要って出てくる記事が多いけど、自分がやった時はなくても大丈夫だった。
作業ディレクトリ作成 。cwhubot
というディレクトリにしてます。以降、このディレクトリを起点に作業します。
mkdir -p ./cwhubot cd ./cwhubot
create hubot project
yo hubot
途中でアダプタを聞かれるので、デフォルト値のcampfire
を上書きするために chatwork
と書いてEnter。他は書き換えずにEnterでOK。
以下のような感じ
[cwhubot] yo hubot _____________________________ / \ //\ | Extracting input for | ////\ _____ | self-replication process | //////\ /_____\ \ / ======= |[^_/\_]| /---------------------------- | | _|___@@__|__ +===+/ /// \_\ | |_\ /// HUBOT/\\ |___/\// / \\ \ / +---+ \____/ | | | //| +===+ \// |xx| ? Owner: xxxxx <xxxxx@example.jp> ? Bot name: cwhubot ? Description: A simple helpful robot for your Company ? Bot adapter: (campfire) chatwork ? Bot adapter: chatwork create bin/hubot create bin/hubot.cmd ・・・(省略)・・・
起動時にherokuのエラーが出るのでpackage.jsonから削除。*3
vi ./external-scripts.json # heroku 関連の行は削除。
起動
試しに hubot のコマンドラインを起動。bin/hubot
でOK。
cwhubot ping
って打ってPONG
って返ってきたら疎通確認OK。いくつかコマンド例も記述しておきます。
bin/hubot help # コマンドリストの表示 cwhubot help # cwhubotのコマンドリストを表示 cwhubot ping # PONGって返ってくるだけ cwhubot echo hoge # 引数がそのまま返ってくるだけ cwhubot translate me こんにちは # 翻訳してくれる exit # 終了します。CTRL+c でも終了できる。
chatwork adapter
export HUBOT_CHATWORK_TOKEN="*****" # APIのアクセストークンを入力します。これは申請して取得しておいて。 export HUBOT_CHATWORK_ROOMS="****" # ルームIDを指定。カンマ区切りで複数指定可能。テストの時はマイチャットとか指定しとくのが無難。 export HUBOT_CHATWORK_API_RATE="360" # ルーム上の発言の取得回数/時
HUBOT_CHATWORK_API_RATE
をちょっと補足。例えば360なら、3600秒(つまり1時間)あたり360回ルーム上の発言を取得するので、平均的に5秒(=3600秒/360/2)+αの時間でhubotが反応してくれます。*5
ちなみに、書いてる時点ではchatworkのAPIは100回/分の制限なので、RATEは大き過ぎたらだめ。小さ過ぎてもhubotの反応が遅くていらいらする。
チャットワークアダプタで起動
さっきはデフォルトのshellアダプタで起動したのだえ、次はアダプタにチャットワークを指定して起動する。yo hubot
した時にchatworkアダプタ自体は設定しているので、やるべきことは起動時にアダプタを明示するだけ。
bin/hubot -a chatwork -n sample-bot CTRL+Cで終了します。
-a
: アダプタ指定。defaultはshell
アダプタというコマンドラインインターフェイス。-n
: hubot が反応する名前。defaultは今回の場合cwhubot
。このデフォルト値はbin/hubot
内に起動オプションで指定されている。yo
コマンドでプロジェクトが生成される時に勝手にそういうふうにしてくれている。
チャットワークの指定したルームでsample-bot ping
としてPONG
が返ってくれば成功。
scriptを書いて動作を拡張する。
hubotはjavascriptかcoffeeで動作を反応する動作を拡張することができる。coffeeで書くほうがメジャーっぽい。なので、書いたことのないcoffeeを書いてみる。
coffeescriptのシンタックスハイライト
coffeeは初めてなので、sublimetextに以下のpluginを入れてみる。 https://github.com/aponxi/sublime-better-coffeescript#installation
shellファイルを実行するhubotの拡張script
scripts
にcoffeeかjsのファイルを置けば自動で認識してくれるみたい。./scripts/script.coffee
ファイルを作成。
内容は以下のように。
module.exports = (robot) -> # 単純な応答: respond robot.respond /I am (.*)/i, (msg) -> msg.send "Hi, #{msg.match[1]}" # 呼ばれなくても発言に反応: hear robot.hear /今何時/, (msg) -> msg.send new Date() # scriptの実行 robot.respond /sh (.+)/, (msg) -> file = msg.match[1].trim() if /(^\.|\/)/.exec(file) msg.send 'Error: File name must not have "/" and must not start with "."' return @exec = require('child_process').exec command = "sh ./scripts/sh/#{file}" @exec command, (err, stdout, stderr) -> resp = "" resp += err if err? resp += stdout if stdout? resp += stderr if stderr? msg.send "[info][title]execute: #{command}[/title]#{resp}[/info]"
./script/sh/
ディレクトリのスクリプトを指定して実行可能なようにしている。*6
実際に実行するshellファイル。
./scripts/sh/test.sh
を作る。
mkdir -p ./scripts/sh touch ./scripts/sh/test.sh open ./scripts/sh/test.sh
サンプルなので、内容はシンプルに以下のように。
echo "Hello, chatwork->hubot->shellscript sample!" date pwd whoami
chatworkから実行してみる
sample-bot sh test.sh
とチャットワークの対象ルームで発言して、shellの実行結果が返ってくれば成功。
daemonize
forever
というnode_moduleを使う。
npm install -g forever
bin/hubot
をこんな感じに書き換えて仕上げる。
#!/bin/sh set -e npm install export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH" export HUBOT_CHATWORK_TOKEN="*****" export HUBOT_CHATWORK_ROOMS="****" export HUBOT_CHATWORK_API_RATE="1200" forever --minUptime 3000 --spinSleepTime 3000 start -c coffee node_modules/.bin/hubot -a chatwork -n sample-bot "$@"
後は起動するだけ。
bin/hubot
forever list
でプロセスがちゃんと出てくればOK。こんな感じ。
[cwhubot] forever list info: Forever processes running data: uid command script forever pid id logfile uptime data: [0] yoPz coffee node_modules/.bin/hubot -a chatwork -n sample-bot 54899 54939 /Users/xxxxx/.forever/yoPz.log 0:0:1:1.956
forever list
: foreverから起動しているデーモンの一覧表示。forever stopall
: foreverから起動しているデーモンを全て停止する。forever stop [forever process id]
: ID指定で停止する。引数に指定するidはforever list
で確認(上の表示だと54939
がそれ)。*7forever help
: Usageを表示。
起動する際のオプションなどはこちらの方の記事を参考にしました。
感想
簡単にできた。はまったのは、
- coffeeの文法
- homebrewから入れたnodebrewのnpmがうまく動かなかったこと。というかnodebrewの使い方はちゃんと見なかったかも。
- 既存の
bin/hubot
をラップするようにshellを書いて、その中でforever
使ったんだけど、それだとうまく動かなかった。forever的には起動自体はしてるっぽいんだけど。
便利だけどchatops目指すとコマンドもscript(というかrespond)がたくさん増えて管理はそれなりに大変そう。hubotのアカウント自体複数作って、重要度やオペレーション内容で分けたりするのかな。
この記事には書いてないけど、cronも簡単に動かせた。自分にはこっちのほうが(ローカルだと)使い道がありそう。
coffeeは便利だし直感的に分かるから不満はないけど、replでif文がなんかうまく書けない。。。
hubotについて書かれてる書籍は、まだ WEB+DB PRESS しかないみたい。手許にあるんだけど、結構突っ込んだ例まで書かれている。ただ、普通に動かしたりするくらいならネットで調べたほうが早い。
*1:最初nodebrewからやったんだけどなぜか上手くいかなかった。ほんとはnodebrewのほうがいいと思う。
*2:古い記事だと hubot --create とかになっててyoを使ってないので注意。この時点ではyoを使うのが標準。
*3:この記事ではherokuにデプロイしたりしないので。
*4:環境変数以外で設定を渡す方法がよくわかりません。誰か教えてください。
*5:ChatWorkAPIの反応時間、NWを通る時間、hubotの処理時間もろもろがあるので、hubotの応答が返ってくるまでには、平均5秒ではなく。平均5秒+αです。
*6:一応、ディレクトリトラバーサルされないようにファイル名のチェックを入れたけどちゃんとできてるかは自信ないです。
*7:forever list で表示されるIDっぽい数字は2つあるんだけど、後のほう。