hubotスクリプトの書き方とサンプル集


hubotスクリプトの書き方と、サンプルを掲載します

本ブログ内の関連記事

hubot-scriptの書き方

hubotは、JavaScriptもしくはCoffeeScriptで書いたコードをscriptsディレクトリに入れておけば、起動時に実行してくれます。

% tree -L 2
.
|-- node_modules
|   `-- hubot
|-- package.json
`-- scripts
    |-- google-images.coffee
    |-- help.coffee
    |-- httpd.coffee
    |-- maps.coffee
    |-- math.coffee
    |-- ping.coffee
    |-- pugme.coffee
    |-- roles.coffee
    |-- rules.coffee
    |-- storage.coffee
    |-- translate.coffee
    `-- youtube.coffee

ここでは、次のサンプルを元に説明します

module.exports = (robot) ->
  robot.respond /who are you/i, (msg) ->
    msg.send "I'm hubot!"

  robot.hear /HELLO$/i, (msg) ->
    msg.send "hello!"

  robot.respond /who am I/i, (msg) ->
    msg.send "You are #{msg.message.user.name}"

  robot.respond /what is this (.*)/i, (msg) ->
    msg.send "This is #{msg.match[1]}"

respondとhear

  robot.respond /who are you/i, (msg) ->
    msg.send "I'm hubot!"

  robot.hear /HELLO$/i, (msg) ->
    msg.send "hello!"

respond「呼ばれて答える」
respondの例

hear「チャンネル上の発言に反応する」
hearの例

msgオブジェクト

  robot.respond /who am I/i, (msg) ->
    msg.send "You are #{msg.message.user.name}"

msgオブジェクトの例

  • msgオブジェクトには、関数が呼び出された時の発言に関する情報が入っています
  • msg.send関数によって発言が行われたチャンネルに対してBOTに発言させることができます

正規表現とキャプチャ

  robot.respond /what is this (.*)/i, (msg) ->
    msg.send "This is #{msg.match[1]}"

正規表現とキャプチャの例

  • 第一引数に渡す正規表現にマッチした発言が行われた場合に第二引数に渡す関数が実行されます
  • 正規表現でキャプチャした文字列は、msgオブジェクトから取り出せます

hubot-scriptの実例

基本的な書き方がわかれば、後はnode.jsの豊富なライブラリ群を駆使して自分のやりたいことを実現するスクリプトを書けば良いのですが、典型的ないくつかの処理についてサンプルを貼っておきます。

定期実行(cron)

cronJob = require('cron').CronJob

module.exports = (robot) ->
  send = (room, msg) ->
    response = new robot.Response(robot, {user : {id : -1, name : room}, text : "none", done : false}, [])
    response.send msg

  # *(sec) *(min) *(hour) *(day) *(month) *(day of the week)
  new cronJob('0 0 * * * *', () ->
    currentTime = new Date
    send '#your-channel-name', "current time is #{new Date().currentTime.getHours()}:00."
  ).start()

cronサンプル

  • cronモジュールを使うことで処理の定期実行が可能です
  • 処理タイミングの指定方法は、通常のcronと同じです
  • #your-channel-nameの部分を発言させたいチャンネル名にあわせて下さい

参考

Web APIを叩く(http)

module.exports = (robot) ->
  robot.respond /twitter (.*)/i, (msg) ->
    keyword = encodeURIComponent msg.match[1]
    request = msg.http('http://search.twitter.com/search.json')
                          .query(q: keyword)
                          .get()
    request (err, res, body) ->
      json = JSON.parse body
      msg.send json.results[0].text if json.results.length > 0

twitterサンプル
この時に検索で引っかかったツイート

  • msgオブジェクトのhttpメソッドを使うとHTTP通信できます
  • bodyに取得結果のテキストが入っているのでそのまま使えます
  • httpメソッドで取得できるオブジェクトの実体はscoped-http-clientです

スクレイピング(request, cheerio)

request = require 'request'
cheerio = require 'cheerio'

module.exports = (robot) ->
  robot.respond /title (.*)/i, (msg) ->
    url = msg.match[1]
    options = 
      url: url
      timeout: 2000
      headers: {'user-agent': 'node title fetcher'}

    request options, (error, response, body) ->
      $ = cheerio.load body
      title = $('title').text().replace(/\n/g, '')
      msg.send(title)

scrapingサンプル

  • msg.httpよりも高性能なrequestを使う方がリダイレクト時の処理などが入っており実用的
  • cheerioを使うとjQueryと同じ感覚で要素を取得でき便利
  • デフォルトではUTF-8しか処理できない

色々なエンコーディングのページを読めるようにしたいなら、こちらの記事を参照して下さい

記憶(robot.brain)

module.exports = (robot) ->
  robot.hear /^(.+)\+\+$/i, (msg) ->
    user = msg.match[1]

    if not robot.brain.data[user]
      robot.brain.data[user] = 0

    robot.brain.data[user]++
    robot.brain.save()

    msg.send robot.brain.data[user]

robot.brainサンプル

  • robot.brain.dataにデータを保存しておけます
  • robot.brain.saveで保存したデータを永続化できる筈が、できませんでした。今のところ原因は不明です

http待ち受け(httpd)

module.exports = (robot) ->
  robot.router.get "/version", (req, res) ->
    res.end robot.version

httpdサンプル

その他

もっと沢山のサンプルがhubot-scriptsリポジトリにあるので、興味がある方は見てみると良いと思います

その他のTIPS

hubot起動時のエラー

こんな感じのエラーが出た時は、http待受用のポートが既に使われていることを示しています。デフォルトで8080番ポートを使うので割と被りそうですよね。

Hubot> [Wed Aug 01 2012 02:18:37 GMT+0900 (JST)] ERROR Error: listen EADDRINUSE

そんな時は環境変数PORTを指定してやることで使用ポートを変更できます

% export PORT=9999

noticeで発言させたい時

IRCのBOTはnoticeで発言させたい、そんな時にどうすればいいでしょう。標準のhubot/hubot-ircではBOTにnoticeで発言させることはできません。notice発言があるのはIRCだけなので、msg.noticeなんかができてしまうとscriptsの互換性が失われてしまうんですね。

しかし、実は、hubot-ircの以前のバージョンではmsg.noticeによる発言ができるようになっていました。0.1.0にアップデートされた時に機能が除かれたのです。そういうわけで、hubot-ircの0.1.0に対してmsg.noticeを復活させるパッチを作りました。

node_modules/hubot-irc/src/irc.coffeeに適用しましょう
irc.coffeeに当ててmsg.noticeを使用可能にするパッチ

参考文献

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>