0

Hubotでbotを3秒で作る

Slackでボットを5秒以内に作れるツールを作った – 波打際のブログさん


単語に反応して返事するbotをめっちゃ作りたいみたいなのはすごくある。
Hubotでなんとかしてる。

準備


まずHubotをGitHubにpushしたらTravis CIでテストされて、通ったらHerokuにデプロイされるようにしておく。テストといってもcoffeelintとjsonlintしかしてないけど。

リポジトリはOrganizationに置いてあるので、メンバーならGitHubのWeb上でbotを改変できて、保存したらすぐテスト走ってデプロイされる。gitでバージョン管理されてるからrevertもできる。
もちろん手元で編集してgit pushでもいい。最近Herokuはgithubやdropboxのhookからデプロイできるようになってた気がするのでそれもいいと思う。


こういうスクリプトを書く

https://github.com/masuilab/slack-hubot/blob/master/scripts/curry_meshi.coffee

ファイルの頭のあたりに反応する単語、返事(配列か関数で書ける)、返事する確率 を書けるようになっている。

config =
カレーメシ:
hear: [
/カレー/i
/curry/i
/(おなか|ハラ|はら|腹)/i
]
reply: [
'カレーメシ!!'
'ボーキメシ!!'
'ジャッスティス!!!'
'http://www.currymeshi.com'
'http://gyazo.com/fc6c4a6f74d41ee472948c35d7ab1d45.png'
'https://www.youtube.com/watch?v=vhSBtoviSKw'
]
ratio: 0.3
いくつ:
hear: [
/いくつ/
/何個/
]
reply: (msg) ->
"#{Math.floor(Math.random()*10)+1}個でじゅうぶんですよ"
ratio: 1

ところでHerokuがfreeプランだと1日18時間しか使えなくなるそうなので、毎日6時間寝るHubot scriptほしい

0

文字単位でgit diff (2)

Gitをhomebrewで2.3.6にアップデートしたら、行内の文字単位のdiffが完璧に出るようになってた。
以前は一応見れたけど3割ぐらい文字化けしてた → 文字単位でgit diff


1行が長い文章を書いている時は、変更された文字単位で背景色がつくとどこが変わったかわかりやすい


設定


diff-highlightにパスを通す
% brew install git
% ln -s /usr/local/Cellar/git/2.3.6/share/git-core/contrib/diff-highlight/diff-highlight /usr/local/bin/diff-highlight

~/.gitconfig でpagerを設定
[color]
ui = auto
[pager]
log = diff-highlight | less
show = diff-highlight | less
diff = diff-highlight | less
これでgit diffに色がつき、さらに文字単位でも差分が見れる。

0

gyazo gemを公式APIに対応させた

https://rubygems.org/gems/gyazo

今まではGyazo.appの中にあったスクリプトを見て勝手にアップロードしてるみたいな感じでやってたので、正式なOAuth APIのほうを使うように修正した。upload,list,deleteのAPIが使える。version 2.0.0になった。

以前のバージョンとはインタフェースが違うので1.0系のgyazo gemを使っている人は注意してほしい


使い方

applicationを登録するとAccess tokenが取得できるので、それを用意してから

require 'gyazo'

gyazo = Gyazo::Client.new 'your-access-token'
res = gyazo.upload 'my_image.png'
puts res['permalink_url'] # => "http://gyazo.com/a1b2cdef345"

とても簡単に使える。

ただ、OAuth使うように変更したのに伴って、今まで同梱してたgyazoコマンドは削除した。CLIアプリでtoken取得するのをどうやるべきか考えてる。


ほぼ同じインタフェースのnode.js版もある

0

詳しい人を教えてくれる「Hubot 教えて君」を作った

hubot-osietekunというhubot scriptを作った。

https://www.npmjs.com/package/hubot-osietekun
https://github.com/shokai/hubot-osietekun

誰に質問するべきか教えてくれる。
新参者に便利だし、他にもchat roomが複数あって見通せない時に誰が詳しいのか探せるので便利そう。


教えて

「hubot 教えて 単語」 で誰が詳しいか教えてくれる。



インストール


npm install hubot-osietekun -save

あとは普通にexternal-script.jsonに書けば読み込まれる。
外部サービスを一切使ってなくて、hubot内だけで完結してる。


実装

hubotが発言を全部kuromojiにかけて誰がどの名詞を使ったかカウントしてる。

形態素解析器kuromojiがnpmで提供されていたので使った。npmの中に辞書も入っていてrequireすればすぐ使えるのがすばらしい。おかげでherokuとかにも簡単にデプロイできる。

ただ一箇所npmjs.orgのドキュメントが間違ってて、build(function(tokenizer){ ~~ })じゃなくてbuild(function(err, tokenizer){ ~~ })だった所でちょっと詰まった。

複数単語のスコアの計算

単純に掛け算している。

複数の単語について質問した場合、例えばreactについて
shokai 5
nikezono 10
zakuni 0

で、coffeeについて
shokai 5
nikezono 2
zakuni 10

という回数だけ発言していた場合、「react coffee」については
shokai 25
nikezono 20
zakuni 0

になるので、それぞれの単語についてバランスよく言及している人のスコアが上がる。どれかがゼロ回の人は0になる。


教えます

しばらく使っていたら、教えたいという人がいたので「hubot 教えます (名詞)」で登録できるようにした。


教えたいと言った人は詳しい人のついでに推薦される。

Javaについて質問したら、keroxpが教えたいと言っていた。


拡張


教えて君の機能を拡張できる。

レスポンスの拡張


Gyazz(増井先生の作ったWiKi)のページを推薦している。これは教えて君の機能には含まれていない。hubot側で教えて君を拡張している。



“osietekun:ready”イベントの後で”response”イベントを登録しておくと拡張できる。
こんな感じ
robot.on 'osietekun:ready', (osietekun) ->

osietekun.on 'response', (msg, res) ->
if res.masters.length < 1
for word in res.words
msg.send "#{word}については http://your-great-wiki-site.com/#{word} を見るといいかも"

scripts/osietekun-gyazz.coffeeの中で書いてて、ページが存在するかとか色々チェックしてからレスポンス返してるので長くなってるけどまあこんな感じ


「教えます」の拡張

他にも、「教えます」も拡張できる。WiKiにページが無い時に書くことを依頼したりできる。


robot.on 'osietekun:ready', (osietekun) ->

osietekun.on 'register:teacher', (msg, query) ->
msg.send "http://your-great-wiki-site.com/#{query.word} に書いてもいいんだよ"

0

watchifyでcjsxをビルド

Gruntでwatchしてbrowserifyでcjsx(coffeeで書いたReactのjsx)をビルドしてるって書いたけど
WEB+DB PressのReactの記事が良かったのでcoffeeで書きなおした

たくさんnpmをrequireする様になったら毎回5〜6秒かかって遅くなったので、gulpにしなければならないのか?とか思ったけどgulpのデバッグが難しすぎて挫折した。


watchify

watchifyはbrowserifyのラッパーで、ファイル更新を検知してbrowserifyしなおしてくれる。
ただ更新見てるだけだろって思ってスルーしてたんだけど、よく見たら更新されたファイルだけを変換しなおしてた。
速い。2回目のビルドから1秒弱になる。


オプション

verbose指定しないとビルドした事すら表示されないので付ける。
あとはbrowserifyに付けるオプションと同じものが使えて、–debugでインラインSourceMapを出力、extensionで.js以外にも探す拡張子を追加、coffee-reactifyをtransformに指定してcjsxをコンパイルしてbundle.jsに書き出す。

watchify --verbose --debug --extension=.cjsx --extension=.coffee -t coffee-reactify client/app.cjsx -o public/js/bundle.js

watch先はclinet/app.cjsxしか書いていないが、require先のファイルを全て監視してくれている。

npm run

watchifyはオプションが長くて毎回打つの無理なので、package.jsonのscriptsにコマンドを書いておく。
「npm run コマンド名」で実行できる。

{
"name": "node-flux-boilerplate",
"private": true,
"version": "0.0.1",
"description": "react+fluxxor+socket.io chat",
"main": "server/app.coffee",
"scripts": {
"start": "coffee server/app.coffee",
"build": "grunt build",
"watchify": "watchify --verbose --debug --extension=.cjsx --extension=.coffee -t coffee-reactify client/app.cjsx -o public/js/bundle.js",
"test": "grunt"
},
〜〜(略)〜〜

この中は./node_modules/.bin/にPATHが通った状態になっているのでwatchifyやgruntがグローバルインストールする必要も無くなって便利。



flux-boilerplate

grunt-contrib-watchで監視するのやめて、watchifyを使うようにした。

https://github.com/shokai/node-flux-boilerplate

React+Fluxxor+socket.ioでfluxなチャットを作った


他のビルドタスク

cssとかも、cssメタ言語で作って各DOMにクラスを振るのじゃなくて、React内のInline Stylesで書いてmixinする方がいい気がしたのでbrowserify以外に継続的なビルドタスクが必要無い気がする。

参考:reactjs – React.js + CSS – Qiita