Slackで新しく追加されたCustom Emojiを教えてくれるボットを作った

こんにちは、[@hico_horiuchi](https://twitter.com/hico_horiuchi)です。
この記事は[チャットボット Advent Calendar 2016](http://qiita.com/advent-calendar/2016/chatbot)の10日目です。

[Slack](http://slack.com)は、今一番人気のチャットサービスですよね。
私も、大学時代は研究室にサークルにバイト、今は仕事やコミュニティ活動で毎日使っています。

Slackには、ユーザが独自の絵文字を追加できる「Custom Emoji」の機能があります。
[slack-reaction-decomoji](https://github.com/oti/slack-reaction-decomoji)は、どこのチームでも使われている人気の絵文字ですよね。

- [Create custom emoji – Slack Help Center](https://get.slack.help/hc/en-us/articles/206870177-Create-custom-emoji)
- [Emoji and emoticons – Slack Help Center](https://get.slack.help/hc/en-us/articles/202931348-Emoji-and-emoticons)


私の入っているチームでは、「絵文字職人」と呼ばれる人がどんどん登録しているのですが、
Slackで通知されたりしないため、新しい絵文字が追加されても分からないことがほとんどです。
そこで、追加された絵文字を定期的に教えてくれるボットをHubotで実装したので紹介します。

<img title="changelog.png" alt="changelog.png" src="https://qiita-image-store.s3.amazonaws.com/0/58742/9290bdb1-a848-3978-8ae6-f38c4197f632.png" width="512px" />

## Custom Emojiの一覧を取得する

SlackはAPIが充実しているので、Custom Emojiの一覧も簡単に取得できます。

- [emoji.list method | Slack](https://api.slack.com/methods/emoji.list)

Hubotの用Slackアダプタの[hubot-slack](https://github.com/slackapi/hubot-slack)では、以下のようにしてAPIを呼び出せます。
(絵文字には別名が設定されていることがあるので、ここでは取り除いています。)

```coffeescript
robot.adapter.client.web.emoji.list (err, info) ->
  if err?
    return console.log(err)
  unless info.ok
    return console.log(info.error)

  emoji_list = []

  for name, url of info.emoji
    if url.match(/^alias:/)
      continue
    emoji_list.push(name)

  console.log(emoji_list)
```

## 追加されたCustom Emojiを抽出する

[node-cron](https://github.com/ncb000gt/node-cron)を使って毎日0時にCustom Emojiのリストを取得し、[hubot-redis-brain](https://github.com/hubot-scripts/hubot-redis-brain)に保存しています。
簡単に配列の差分を取るために、関数型プログラミング用ライブラリの[Underscore.js](http://underscorejs.org)を使っています。

```coffeescript
updateEmojiList = (emoji_list) ->
  robot.brain.set('slack-emoji-list', emoji_list)

changelogCron = new cronJob
  cronTime: '0 0 0 * * *'
  onTick: ->
    updateEmojiList(emoji_list)
  start: true
  timeZone: 'Asia/Tokyo'
```

Brainを更新する前に、取得したリストと保存されていたリストと比較することで、その日に追加された絵文字を抽出しています。

```coffeescript
postChangelog = (channel_id, next_list) ->
  previous_list = robot.brain.get('slack-emoji-list') ? []

  diff = _.difference(next_list, previous_list)
  diff = diff.map (name) ->
    ":#{name}:"

  if diff.length is 0
    robot.send({ room: channel_id }, '今日追加された絵文字はないよ! 職人さん頑張って!')
  else
    msg =  "昨日追加された絵文字は *#{diff.length}個* です!\n"
    msg += "#{diff.slice(0, 10).join(' ')}#{' ...' if diff.length > 10}\n"
    robot.send({ room: channel_id }, msg)
```

## 今回開発したボットの紹介

今回開発した「Slackで新しく追加されたCustom Emojiを教えてくれるボット」はGitHubで公開しています。
使い方や、Herokuへのデプロイ方法をREADMEに書いているので、ぜひ使ってみて下さい!

- [hico-horiuchi/emojiner: I am a slack custom emoji craftsman.](https://github.com/hico-horiuchi/emojiner)

追加されたCustom EmojiをWebで表示する機能も持っていたりします。

<div style="overflow: hidden; height: 256px; position: relative;"><img title="changelog_web.png" alt="changelog_web.png" src="https://qiita-image-store.s3.amazonaws.com/0/58742/8da88c54-5e86-0b59-ef8a-fa80e756332f.png" width="512px" /></div>

今後は、ボットに絵文字にしたい言葉やフォントなどを伝えると、バックエンドで生成してSlackに登録してくれる機能も付けたいです。
PythonやImageMagickを使ってテキスト絵文字を生成する実装が既にあるので、参考になりそうです。

- [絵文字ジェネレーター](https://emoji.pine.moe/)
  - [emoji-gen/Emoji-Web: Ultimate Emoji Generator](https://github.com/emoji-gen/Emoji-Web)
  - [Emoji-Web/String2emoji.py at master · emoji-gen/Emoji-Web](https://github.com/emoji-gen/Emoji-Web/blob/master/apps/String2emoji.py)
- [Slackのリアクションで使うテキスト絵文字を作成する - Qiita](http://qiita.com/Will_meaning/items/ebfc5c02842c002acfab)

## Hubot×ChatOps勉強会の紹介

学生時代に大阪と神戸で開催したHubot×ChatOps勉強会を、東京でも開催したいと思っています。
第3回は2月上旬に田町で開催予定なので、発表して頂ける方は[@hico_horiuchi](https://twitter.com/hico_horiuchi)です。までご連絡頂けると嬉しいです。

- [Hubot×ChatOps勉強会 - connpass](https://hubot-chatops.connpass.com/)