そんな今日この頃でして、、、

コード書いたり映画みたり。努力は苦手だから「楽しいこと」を探していきたい。

Hubot(とLet's Chat)であそんでみる

MSNメッセンジャー全盛の世代としては人工無能を思い出して懐かしくなりますな。

とりあえずザーッと。

モジュールインストール

$ sudo npm install yo generator-hubot -g


作業ディレクトリ作成

$ mkdir myhubot&&cd $_


テンプレート作成

諸々入力してテンプレートを作成する。

ここでアダプタとしてlets-chatを指定しておく。

$ yo hubot
? ==========================================================================
We're constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
More info: https://github.com/yeoman/insight & http://yeoman.io
========================================================================== No
                     _____________________________
                    /                             \
   //\              |      Extracting input for    |
  ////\    _____    |   self-replication process   |
 //////\  /_____\   \                             /
 ======= |[^_/\_]|   /----------------------------
  |   | _|___@@__|__
  +===+/  ///     \_\
   | |_\ /// HUBOT/\\
   |___/\//      /  \\
         \      /   +---+
          \____/    |   |
           | //|    +===+
            \//      |xx|

? Owner:blue1st
? Bot name: myhubot
? Description: A simple helpful robot for your Company
? Bot adapter: (campfire) lets-chat
? Bot adapter: lets-chat

Shell上で動作テスト

hubotを実行して対話画面に入る。

$ bin/hubot

細かいエラーが出るがひとまず気にしない。

PINGと話しかけると返答してくれる。

myhubot> @myhubot PING
PONG

応答スクリプトを作ってみる

下記のような応答スクリプトを/script/talk.coffeeとして作成してみる

module.exports = (robot) ->

  robot.hear /ぬるぽ/, (res) ->
    res.send "ガッ"

  robot.respond /今何時/i, (res) ->
    d = new Date
    hour = d.getHours()
    min = d.getMinutes()
    res.send "#{hour}時#{min}分"

hearならマッチする文言が登場したときに、respondならbot宛に発言された時に記述された反応を返す。

myhubot> myhubot 今何時?
19時9分
myhubot> ぬるぽ
ガッ

正規表現で記述しているところから分かるように、res.match[1]とかで発言内容を取得できる。

実用的には例えば指定されたサーバのmuninグラフのURL生成して返すようにすることで、Let's Chatの画像表示機能と合わせてサーバの異常値をすぐに確認できるようにするなんてこともできそう。


cronで定期的につぶやかせる

package.jsonにパッケージを追加

〜
  "dependencies": {
〜
    "cron": "~1.0.5"
  },
〜

処理を記述

/script/cron.coffeeで定時処理を記述する。

cronJob = require('cron').CronJob

module.exports = (robot) ->
  new cronJob '0 * * * * *', () =>
    robot.send {room: "552fa8c833783d15002fc699"}, "cronだお"
  , null, true ,"Asia/Tokyo"

cron処理なのでrobot.sendを使うこと、そして本分の前に引数(roomとか指定する)が一つ必要なことに注意。

shell起動だと関係ないけど、後でアダプターで実際に繋いだ際にroomの指定ないとどこにもメッセージが行かない

systemのcronと異なり秒から指定できる。


httpdで待ち受けて動作させる

robot.routerを使うことでhttpdでの何かしらのリクエストをトリガーとして動作させることができる。

デフォルトで8080ポート、環境変数PORTで別のポートを指定することができる。

script/httpd.coffeeとして下記のような記述をすると・・・

module.exports = (robot) ->

  robot.router.get "/test", (req, res) ->
    res.end "ok"
    robot.send {room: "552fa8c833783d15002fc699"}, "httpd"

  robot.router.post "/echo", (req, res) ->
    if not req.body
      res.end "ng"
      return
    res.end "ok"
    message = req.body.message
    robot.send {room: "552fa8c833783d15002fc699"}, message
$ curl  localhost:8080/test
ok
(chat側でhttpdと発言)
$ curl -XPOST localhost:8080/echo -d message=aaa
ok
(chat側でaaaと発言)

Let's Chatにつなげてみる

Let's Chat自体はDockerが使えるなら下記の手順で簡単に立ち上げられるので省略。

github.com

環境変数を設定する

ボットを駐在させたいROOMのURLの末尾と、ボットアカウントの認証トークンをそれぞれHUBOT_LCB_TOKEN HUBOT_LCB_ROOMSとして登録する。

また、ローカルで動かしていない場合はプロトコル(デフォではhttp)、ドメイン(デフォでlocalhost)、ポート(デフォでは5000)をそれぞれHUBOT_LCB_PROTOCOL HUBOT_LCB_HOSTNAME HUBOT_LCB_PORTとして登録する。

起動する

-aオプションでアダプタとして予めインストールしていたlets-chatを指定、ついでに-nオプションでLet's Chat側でのボットアカウント名に合わせて名称を指定しておく。

$ bin/hubot -a lets-chat -n bot

これで少し待てば、Let's Chatにはbotが入ってくるはず。


Dockerfile化する

色々環境変数もあるしなので、作ったhubotをDockerコンテナ化してみる。

以下のようなDockerfileを作成する。

FROM node:latest

RUN npm install hubot coffee -g

ADD 今回作ったのを収めたディレクトリ /hubot
WORKDIR /hubot

ENV HUBOT_LCB_TOKEN ボットアカウントのトークン
ENV HUBOT_LCB_ROOMS 駐在させたい各ROOMのURLの/room/以降をカンマ区切りで
ENV HUBOT_LCB_PROTOCOL http
ENV HUBOT_LCB_HOSTNAME Let'sChatを設置したドメイン
ENV HUBOT_LCB_PORT Let'sChatを設置したポート

EXPOSE 8080

ENTRYPOINT ["bin/hubot"]
CMD ["-a", "lets-chat", "-n", "ボットのアカウント名"]

引数部分だけCMDにすることで、run -it "-a shell"とかすることで任意に挙動を確認できる。

うっかり忘れてしまうところだが、別のコンテナなので同ホスト上であれどlocalhostでは接続できないことに注意。(それ用にコンテナのlinkオプション設定するとかでも良いけどね)

qiita.com


しかし起動時にスクリプトのワーニングが消えない・・・

coffeeスクリプトの書き方もっちょい勉強せんといかんかもしれん。