べにやまぶろぐ

技術寄りの話を書くつもり

Slack で発言する Hubot にチャレンジしたらバージョン3系になっててちょっとハマった

最近流行りの ChatOps についていきたい!という純粋なミーハー心と日々のちょっとしたことを自動化したい(ミーティングのリマインダとか、ランチグループ分けとか)という思いから Hubot 使って Slack 連携をさせてみたのですが、最近バージョンが2系から3系に変わったということでウェブ上のドキュメントが微妙に古くなっててハマりました。

特に cron で robot.send() を呼んで定時に発言させたい、というだけだったのですが robot.send {room: "#general"}, "ハロー" とか robot. messageRoom "#general", "ハロー" とかいろいろ試したものの

[Sun Jan 18 2015 23:26:40 GMT+0900 (JST)] ERROR TypeError: Cannot call method 'send' of undefined
2015-01-18T14:26:40.609421+00:00 app[web.1]:   at SlackBot.send (/app/node_modules/hubot-slack/src/slack.coffee:181:16, <js>:216:33)

などとエラーが出てしまい、一瞬そもそも robot.send が呼べていないようにも見えつつ、追ってみると上記エラー内の slack.coffee で

channel = @client.getChannelGroupOrDMByName envelope.room

で channel を取得しているものの特に null チェックをすることなく

channel.send msg

に突入してしまっており、それはそれでまずいのですがそもそも channel が取得できていない様子。

で、色々調べてみると hubot-slack アダプタ v2 から v3 へ – 半月記 に大変よくまとめられていました。

v3 ではちょうど逆になって、ハッシュ(#)を付けないようになりました。これが付いていると正しく動作しません。

ということで cron の書き方もいろいろあって悩んだ挙句に最終的には

cronJob = require('cron').CronJob
module.exports = (robot) ->
  new cronJob
    cronTime: "0 58 9 * * 1-5"
    onTick: ->
      robot.send {room: "general"}, "朝会やりますよ ヽ(´・ω・`)/"
      return
    start: true
    timeZone: "Asia/Tokyo"

このように落ち着きました。npm の方で crontime のパッケージを足してあります。

ちなみに robot.send() が無い、という問題はそれはそれであるようで 橋本商会 » hubot-slackアダプタv3にアップデートしたら色々辛かった

websocket接続するまでrobot.sendが無い

と指摘されており、起動直後に send コマンドを実行するような場合は記事内に書かれている

return if typeof robot?.send isnt 'function'

のようなのを挟んでおくと良さそうです。

これから新規で slack 用 hubot 開発する場合は、まだまだ不安定なバージョン3系だということを意識して調査・開発したほうが良さそうです。