Help us understand the problem. What is going on with this article?

Hubot でホームページをつくろう

More than 5 years have passed since last update.

これは Hubot Advent Calendar 2014 の 10 日目の記事です。

また、今回は @bouzuya の Hubot 連載の第 8 回です。目次は、第 1 回の記事にあるので、そちらをどうぞ。

前回まで、そして今回は

前回は スクレイピングする Hubot スクリプトをつくろう ということで、npm パッケージ requestcheerio とを使って、Adventar をスクレイピングして Advent Calendar 一覧を返す Hubot スクリプトをつくりました。

前回は HTTP リクエストしたので、今回は HTTP レスポンスしましょう (?)。 Hubot で HTTP アクセスを待ち受けて、HTML を返しましょう。要するに Hubot でホームページ (Web サーバー) をつくりましょう

スクリプトの完成イメージ

まず、今回つくろうとしている Hubot スクリプトのイメージを共有しましょう。

今回は簡単なリンク集をつくります。チャットでの実行イメージはこんな感じです。

bouzuya> hubot homepage add bouzuya http://bouzuya.net/
hubot> added bouzuya http://bouzuya.net/

bouzuya> hubot homepage list
hubot> [0] bouzuya http://bouzuya.net/

bouzuya> hubot homepage remove 0
hubot> removed bouzuya http://bouzuya.net/

また Web ブラウザで http://<hubot url>/hubot-homepage/ を見るとリンク集が表示されます。

さっそくつくる

まずは Hubot スクリプトのテンプレートを generator-hubot で生成します。

$ mkdir hubot-homepage
$ cd hubot-homepage

$ yo hubot:script
...

説明不要ですね。

今回は追加パッケージは不要です。 Hubot は元々 express 3.x に依存しており、HTTP の待ち受けも標準でできるようになっているからです。

さっそく書いていきましょう。

src/homepage.coffee
# Description
#   A Hubot script for hosting your web page.
#
# Configuration:
#   None
#
# Commands:
#   hubot homepage list - list links in homepage
#   hubot homepage add <text> <url> - add link to homepage
#   hubot homepage remove <index> - remove link from homepage
#
# Author:
#   bouzuya <m@bouzuya.net>

module.exports = (robot) ->
  links = []

  robot.router.get '/hubot-homepage/', (req, res) ->
    li = links.map (i) ->
      """
        <li><a href="#{i.url}" target="_blank">#{i.text}</a></li>
      """
    .join '\n'
    html = """
      <html>
      <head><title>Links</title></head>
      <body>
        <h1>Links</h1>
        <ul>
        #{li}
        </ul>
      </body>
      </html>
    """
    res.type 'html'
    res.send html

  robot.respond /homepage li?st?/, (msg) ->
    msg.send links.map((i, index) -> "[#{index}] #{i.text} #{i.url}").join('\n')

  robot.respond /homepage add (.+) (https?:\/\/.+)/, (msg) ->
    text = msg.match[1]
    url = msg.match[2]
    item = { text, url }
    links.push item
    msg.send "added #{item.text} #{item.url}"

  robot.respond /homepage re?m(?:ove)? (\d+)/, (msg) ->
    index = msg.match[1]
    item = links.splice(index, 1)[0]
    msg.send "removed #{item.text} #{item.url}" if item?

解説

ええと、解説します。

links = []

リンクをここに保持します。永続化はしていないため、Hubot を再起動すると消えてしまいます。

本来は Hubot の brain で永続化すべきなのですが、それはまた別の機会に紹介します。

robot.router

https://github.com/github/hubot/blob/v2.10.0/src/robot.coffee#L265-L300

Node.js express に慣れたユーザーに説明するなら、これは express() です。express は Node.js のデファクトスタンダードな Web アプリケーションフレームワークです。Ruby の sinatra のような軽量のフレームワークです。

想像どおり express の解説をするときりがないので、簡単に。

robot.router.get(path, callback)GET メソッドを待ち受けて callback で処理できます。robot.router.post(path, callback) などもあります。詳しくは express の api reference を参照してください。

注意事項としては express のバージョンは 3.x なので、それに対応したドキュメントを参照し、コードを記述してください。

/homepage li?st?/ /homepage re?m(?:ove)? (\d+)/

細かいことですが、コマンドを省略できるようにしています。

listls でも認識されますし、removerm でも認識されます。

Hubot のコマンドはなるべく入力しやすく工夫すると良いと思います。

その他

あとは特にはないですね。list / add / remove をそれぞれ定義し、links を操作できるようにしています。

では、動かしてみましょう。

$ HUBOT_SHELL_USER_NAME='bouzuya' PATH="./node_modules/hubot/node_modules/.bin:$PATH" $(npm bin)/hubot -a shell -n hubot -r src
hubot> hubot homepage list

hubot> hubot homepage add bouzuya http://bouzuya.net/
added bouzuya http://bouzuya.net/
hubot> hubot homepage add blog http://blog.bouzuya.net/
added blog http://blog.bouzuya.net/
hubot> hubot homepage add google http://www.google.com/
added google http://www.google.com/
hubot> hubot homepage list
[0] bouzuya http://bouzuya.net/
[1] blog http://blog.bouzuya.net/
[2] google http://www.google.com/
hubot> hubot homepage rm 1
removed blog http://blog.bouzuya.net/
hubot> hubot homepage list
[0] bouzuya http://bouzuya.net/
[1] google http://www.google.com/
hubot> 

動きそうですね。

Web ブラウザで http://localhost:8080/hubot-homepage/ にアクセスしてみてください。以下のような Web ページが表示されます。

hubot-homepage.png

登録した links が表示されます。画像は 3 件登録した直後のものです。もちろん削除も反映されます。

まとめ

今回は robot.router を使って HTTP リクエストを待ち受けてみました。

Hubot はホームページもつくれるんですね!すごい!(のか?)

ちなみに、この機能を使って、外部サービスの Web hook へ対応したり、adapter の実装に使ったり、生成した画像を一時的にホストして返す、などができます。BOT は必ずしも HTTP の待ち受けの必要はないので、削除すべき、といった意見もありますが、互換性の問題もありますし、おそらく簡単には削除されないと思います。

ちなみに今回のサンプルは bouzuya/hubot-homepage にあります。うまく動かない、などがあれば参考にどうぞ。

最後に

サンプルをつくるのが大変になってきました。

あとは brain / adapter くらいですかね。起動スクリプトの動きとか、スクリプト読み込みとか、Hubot 本体の動きを追っていく感じになりますかね。

次回は brain かな。正直、クソ仕様が山ほどありますし、説明する上では準備が面倒なので、個人的には嫌いなんですが。

bouzuya
ぼく、ぼうずや。なさけはひとのためならず。たのしいはせいぎ。
http://bouzuya.net/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした