SlackでHubotを使い回し別人(BOT)として発言する

# <i class="fa fa-cubes" aria-hidden="true"></i> 概要

Slackの各種APIによる発言時には、`username`や`emoji`を指定することで好きな名前やアイコンで発言することが出来ます。

HubotのSlack連携にもデフォルトのHubot設定を上書きして発言するメソッドがあります。
それを使えば一つのHubot連携でいろんなキャラが発言を拾い、返答している風を装えます。
複数のHubotを立てて管理するのも大変なので、
一つのHubotで機能ごとにキャラ分けしたりしています。

今現在どんな風にしてるのかをメモ的に残す。

**追記**
この記事はslackhq/hubot-slackのv3時代をもとに記述しています

# <i class="fa fa-sitemap" aria-hidden="true"></i> ファイルの置き場所

どこでもいいのですが、
`hubot\scripts\*.coffee`
に書くと自動的に読み込んでくれるので、機能やキャラごとに分けたりしてます。


# <i class="fa fa-user" aria-hidden="true"></i> キャラの関数化

カスタムメッセージは
`robot.adapter.customMessage {}`
の形式で送ります。
アイコンは事前に絵文字登録しておきます(`icon_url`で画像URLでもOKだったはずですが)

```coffeescript
module.exports = (robot) ->
    robot.hear /ほげほげ/i, (msg) ->
        robot.adapter.customMessage {username:'キャラクター', icon_emoji:':character:', text:'メッセージ', message:msg}
```

`msg`オブジェクトは発言先の部屋などに使います。

毎回オブジェクトを書くのは苦痛なので、text以外を固定にする関数を作ると体感楽に。

```coffeescript

character = (msg, text) ->
    {username:'キャラクター', icon_emoji:':character:', text:text, message:msg}

module.exports = (robot) ->
    robot.hear /ほげほげ/i, (msg) ->
        robot.adapter.customMessage character(msg, 'メッセージ')
```

`character()`内で発言するのは副作用っぽいのでやめました。
`robot.adapter.customMessage`が長いのがネック。

# <i class="fa fa-thumbs-down" aria-hidden="true"></i> `robot.adapter.customMessage`のデメリット

shellでのデバッグができません。(ちゃんとアダプターなどを指定しないデフォルト実行の場合)
Slack用設定はHerokuの方にしか設定していないため、手元ではshellでの動作になっています。
毎回アダプターエラーが出ますがshellで動きます。
なので`robot.adapter.customMessage`が無い状態です。
正規表現にマッチして`robot.adapter.customMessage`に到達するとエラー。
到達しなければ普通の`send`などの部分は引き続きshellでも動作を見れます。

# <i class="fa fa-reply" aria-hidden="true"></i> `robot.respond`風味に

```coffeescript

character = (msg, text) ->
    {username:'キャラクター', icon_emoji:':character:', text:text, message:msg}

module.exports = (robot) ->
    robot.hear /^\s*@?character\s*ほげほげ/i, (msg) ->
        robot.adapter.customMessage character(msg, 'メッセージ')
```

`@character`はユーザーとして存在しないので、`robot.hear`しか使えないのですが、正規表現につけることであたかもメンションに応える感じにします。
当然Slackのオートコンプリートには現れません。

## 関連
* [robot.respondでmsg.matchを使う場合は単一でもキーワードを()で囲まなければならない - Qiita]  
  `hear`も`respond`もおなじよどっちもおなじよ

# <i class="fa fa-repeat" aria-hidden="true"></i> cronで発言するときは

cronモジュールを使う場合は`msg`オブジェクトがありません。
`msg`はどのチャンネルで発言するかに使用していたので、
ソースコードを見ながらオブジェクトを模倣します。

余談ですが、`msg.random []`で使えた配列からランダムに取得する関数は
`random = require('hubot').Response::random`
で`msg`がなくても使えます。

```coffeescript
cron   = require('cron').CronJob

character = (msg, text) ->
    {username:'キャラクター', icon_emoji:':character:', text:text, message:msg}

module.exports = (robot) ->
    new cron('0 30 9 * * 1-5'
        , () ->
            robot.adapter.customMessage character({room: 'random'}, 'メッセージ')
        , null
        , true
    )
```

# <i class="fa fa-book" aria-hidden="true"></i> こんなものを読むよりコードを読もう

[hubot-slack/slack.coffee at v3.4.1 · slackhq/hubot-slack]

***

`robot`や`msg`を直接操作する方法も出来そうだが、用意されたメソッドを使ってみました。


[robot.respondでmsg.matchを使う場合は単一でもキーワードを()で囲まなければならない - Qiita]:http://qiita.com/khsk/items/bc5ea0381c335879bf30#comment-93d60a156fdbdd4c5727
[hubot-slack/slack.coffee at v3.4.1 · slackhq/hubot-slack]:https://github.com/slackhq/hubot-slack/blob/v3.4.1/src/slack.coffee#L286