読者です 読者をやめる 読者になる 読者になる

Aqutras Members' Blog

株式会社アキュトラスのメンバーが、技術情報などを楽しく書いています。

開発環境のhubotを、特定ルームでのみ反応するようにする

技術 Hubot

こんにちは、nechinechiです。
今回は、開発環境にあるhubotを、Slackの特定ルームでのみ反応する方法について書きたいと思います。

始めに

hubotで新しく機能を追加、あるいはバグの修正などを行う場合、実際にSlackで動作確認をする必要があると思います。
しかし、開発環境でhubotを起動させると、本番環境で起動しているhubotと合わせて、二重にhubotが起動することになると思います。
すると、当然Slackでもhubotは二重に反応を返すこととなります。
この二重起動を回避するため、開発環境にあるhubotは、Slackの特定ルームでしか反応しないようにしました。
図に表すと以下のようになります。

f:id:nechinechi:20160628141030p:plain

話は以下のように進めていきます。

  • 方法
  • 取得すべき情報
  • スクリプトの作成

方法

hubotではscripts下のスクリプトはすべて読み込まれます。
それぞれのスクリプトが実行され、反応が返される前に、環境を判定し、反応を返すルームを限定する処理を行わなければなりません。
そのために、環境判定、ルームの限定をするスクリプトは、他のスクリプトより先に読み込まれる必要があります。
hubotではscriptsの下に置かれてあるスクリプトを順に読み込んでいきます。
アルファベットの大文字、小文字、数字、_(アンダーバー)で調べてみたところ、012... ABC... _ abc...のような順序で読み込まれるようでした。
なので方法としては、1_room_limit.coffeeのような名前を付けたスクリプトで、hubotが反応を返すかどうかを判断します。(参考資料はこちら)

取得すべき情報

スクリプトの実行時に、以下の情報を得る必要があります。

  • hubotの起動環境(本番環境か開発環境か)
  • メッセージの送られたルームがどこであるか

hubotの起動環境

hubotの起動環境がどこであるかを取得するためには、環境変数で設定しておく必要があります。
初めは、hubotはexpressを標準で組み込んでいることから、express使おうとしてました。
ですが、app.get('env')とやっても、「appは定義されてない」と言われ、結局、expressモジュールをrequireする必要がありました。
なので、以下のような方法で環境変数から値を取得するようにしました。 

環境変数にHUBOT_ENVなどとして、hubotの実行環境をdevelopmentのように設定しておきます。ここで環境変数に設定する名前は、任意のもので大丈夫です。
このようにして設定した環境変数は、以下のようにして値を取得できます。

environment = process.env.HUBOT_ENV

メッセージの送られたルームの取得

以下のように、msgとして引数が与えられた場合、メッセージの送られたルームは、以下のように取得できます。

robot.respond /foo_bar/, (msg) -> 
  room = msg.message.user.room

上記では、msg.message.user.roomを使って、メッセージの送られたルームを取得していますが、 msg.message.room, msg.envelope.room, msg.envelope.user.roomの3つでも同じものが取得できるようです。(以下、参考サイト)

THE HUBOT MSG OBJECT
上記のサイトでは、引数に渡されたmsgオブジェクトの持つデータ構造について詳しく書かれているので、良ければ参照してみてください。

スクリプトの作成

以上のことを踏まえて、スクリプトは以下のように作成しました。
robot.hear/.*/としておけば、Slack上の全ての発言を拾い、その発言に対して以下のように判定をします。
environmentで取得したhubotの実行環境がdevelopment、かつ、roomで取得した値がbot-testの場合のみreturnしています。returnされると、このスクリプトのそれ以降の行は無視され、次のスクリプトを読み込みます。
もし、条件が満たされなければ、msg.finish()を実行しています。これを実行することで、他のスクリプトを読み込まなくなります。
このスクリプトを1_limit_room.coffeeなどのように、他のスクリプトより先に読み込まれるような名前を付けます。
そうすることで、開発環境下のhubotはSlackのbot-testチャンネルでしか反応しなくなります。

module.exports = (robot) ->
  environment = process.env.HUBOT_ENV

  robot.hear /.*/, (msg) ->
    room = msg.message.user.room

    if environment is 'development' and room is 'bot-test'
      return
    msg.finish()

終わりに

今回は、開発環境にあるhubotを、Slackの特定ルームでのみ反応する方法についてブログを書きました。
Slackでhubotが二重に反応していると、ただhubotを利用している人にとっては、煩わしいかと思います。
なので、hubotは特定のルームでしか反応しないようにしておくと良いと思います。