OTOBANK Engineering Blog

オトバンクはコンテンツが大好きなエンジニアを募集しています!

社内でHubotスクリプト勉強会を開催したよ

こんにちは。麦芽系エンジニアasmzです。麦芽は東北産を使用しています。そろそろビアガーデンとか行きたいです。誰か誘って下さい。よろしくお願いします。

さて、私はこれまで

engineering.otobank.co.jp

engineering.otobank.co.jp

とかでちょいちょい弊社Hubot(otobot君)に機能追加してきて、「この人Hubotばっかりやってるけど、実はオトバンクのHubot開発担当の人なのかしら?何なのかしら?窓際社員なのかしら?」と思われがちです。違います。何ですかHubot開発担当って。

まぁ主に仕事に疲れた時の気晴らしとかに、一人で勝手に作ってます。何故か深夜にプルリク出ることが多いやつです。

otobot君も最初はそんなに社内で活用されてたわけでも無いのですが、otobot image me でおもしろ画像表示して遊ばれたり(専用のSlackチャンネルまである)、ランチ情報を取ってこれるようにしたりしたおかげか、最近になってやっと社内でも日の目を見始めてきました。

で、「お前、ちょっとHubotのこと教えろや」と興味を持つ人が出てきたので、こないだ社内の開発チーム向けにHubotスクリプト勉強会を開催しました。ちなみに、勉強会はエンジニアだけでなくデザイナーさんとかも出席してくれているので、内容としてはだいぶ入門編的なものになっています。

そういう経緯なので、既にご存知の方は物足りない内容だと思いますし、ググればいろいろ似たような記事はあるんですが、せっかく作った資料が埋もれるのも勿体無いのでここで公開してみます。誰かの参考になれば幸いです。

それでは、はりきってどうそー


はじめに

Hubotとは

Hubot is your company's robot.

某Pep◯erさんとは無関係です。念のため。

Hubotのインストール

以下のドキュメントが参考になりますので、各自の環境に導入してみてください。

otobotはちょっとバージョン低いので若干違いますが、導入後の仕組みは概ね同じと思ってもらってよいです。

Hubotの構成と仕組み

Hubotプロジェクトは基本的に以下のようなディレクトリ構成

otobot(例)
├── Procfile
├── README.md
├── bin
│   ├── hubot
│   └── hubot.cmd
├── external-scripts.json
├── hubot-scripts.json
├──node_modules
│   └── ...
├── package.json
└── scripts
    └── *.coffee

Hubotの実行

./bin/hubot が起動スクリプト

$ ./bin/hubot --adapter shell

--adapterは「アダプター」(後述)を指定するオプション

まずは自分のターミナルで実行してみるためにshellを指定(まぁデフォルト値なんですけど)

$ ./bin/hubot --adapter shell
myhubot> (幾つかメッセージ出るけど、今はとりあえず無視)
myhubot> myhubot ping
PONG
myhubot> 

Hubotアダプター

  • 特定のチャットに依存しないための仕組み
  • チャットに対応したアダプターを用いることで、そのチャットと連携することができる(下図真ん中辺りの紫色の部分)
  • otobotはSlack上で動作するので、実際は ./bin/hubot --adapter slack みたいな感じで実行

f:id:asmz0:20160212111147p:plain

POINT

  • アダプターが実行環境周りのコトを吸収してくれる
  • 実際のHubotの処理(図の緑色の部分)を作るときには環境のことは気にしなくていい

Hubotスクリプトを作ってみよう

Hubotスクリプトを作る前に

どうやってHubotスクリプトが読み込まれているのかを理解しましょう

./bin/hubot実行後

  • scriptsディレクトリ以下にある「*.coffee」読み込み
  • external-scripts.jsonを読み込み、そこに記載のあるパッケージをnode_module配下から読み込み

 つまり↓

  • 以下のどちらかの方法で使用可
  • scriptsディレクトリにそのまま*.coffeeを置く
  • node_module配下にnpmパッケージ形式で配置しexternal-scripts.jsonにパッケージ名記載

ちなみにnpmパッケージとして配布するやり方はこちらのエントリにちょっと書いてあるので、参考にしてもらえるとよいですね。

Hello Worldスクリプトを作る

とりあえずscriptsディレクトリに置く方法でやってみましょう

scripts/hello.coffee

# Description:
#   Hello World!
#
# Commands:
#   hubot hello : Returns "world!"

module.exports = (robot) ->
  robot.respond /hello/i, (msg) ->
    msg.send "world!"

実行結果

myhubot> myhubot hello
world!
myhubot> 

# ちなみにスクリプト内のコメントに書いた「Commands:」の内容は、helpに表示されます
myhubot> myhubot help
...
myhubot hello : Returns "world!"
...
myhubot> 

コード解説

他の人の発言に反応する系(入力)

respond [正規表現]

話しかけられた発言が正規表現にマッチしたらに反応する(bot名 なんちゃらなんちゃらとマッチング)

自分で発言する系(出力)

send

タイムライン上に発言する

ちなみに

CoffeeScriptなので省略されてますが、実際には以下の様なJavaScriptの意味になります

# CoffeeScript
module.exports = (robot) ->
  robot.respond /hello/i, (msg) ->
    msg.send "world!"
# JavaScript
module.exports = function(robot) {
  robot.respond(/hello/i, function(msg) {
    msg.send('World!');
  });
};
  • robot.respond(pattern, callback)patternに指定した正規表現をリスナーとして登録し、マッチしたらcallbackを実行するメソッド
  • msg.send(message)messageを送信するメソッド

その他基本的な機能

他の人の発言に反応する系(入力)

hear [正規表現]

発言が正規表現にマッチしたら(Hubotに呼びかけなくても勝手に)反応する

自分で発言する系(出力)

reply

Hubotを呼び出した人に対してタイムライン上で返信する

hear, replyの例

robot.hear /カレー/i, (msg) ->
  msg.reply "カレー食べたいよねー"

## preview

myhubot> そういえば、今晩はカレーだった
Shell: カレー食べたいよねー
myhubot> 誰だ貴様!

発言された内容をスクリプトで使う(パラメータ)

match

正規表現で括弧で囲んだ部分がmsg.matchに配列として格納される

robot.respond /santaku (.*) (.*) (.*)/i, (msg) ->
  msg.send msg.match[0] # <- マッチした発言全体が格納される
  msg.send msg.match[1] # <- 括弧の1つ目
  msg.send msg.match[2] # <- 括弧の2つ目
  msg.send msg.match[3] # <- 括弧の3つ目
  msg.send msg.match.length

## preview

myhubot> myhubot santaku aaa bbb ccc
myhubot santaku aaa bbb ccc
aaa
bbb
ccc
4
myhubot> 
random

配列からランダムに1つ取り出す

robot.respond /santaku (.*) (.*) (.*)/i, (msg) ->
  if msg.match.length != 4
    return           
                       
  choices = [msg.match[1], msg.match[2], msg.match[3]]
  choice = msg.random choices

  msg.send "これがいいんじゃない?"
  msg.send choice

## preview

myhubot> myhubot santaku そば うどん ラーメン
これがいいんじゃない?
そば
myhubot> 

これくらいの機能を覚えれば、とりあえず簡単な機能は作れるんじゃないかなーと思います。あとはアイデア次第!

CoffeeScriptの構文

時間切れです。この辺をご参照くださいな。


以上が社内勉強会の内容です。まぁ内容どうこうより、こういった勉強会が毎週行われて日々切磋琢磨しているんだよ、という文化をお伝えできればいいですね。

ちなみにこの勉強会を受講した皆さんに「一人一つ機能追加してプルリク出して!」という宿題を課したはずだけど、まだ一件も来ないなぁ。おかしいなぁ。みんな体調でも悪いのかなぁ。

まとめ

これだけ言っておいてなんですが、Hubotに興味なくてもいいんで、Webサービスやスマホアプリの開発に興味ある方を募集中です! とりあえずビアガーデン一緒に行きましょう!

あわせて読みたい

engineering.otobank.co.jp

engineering.otobank.co.jp