はじめに
こんにちは。yoshitsuguといいます。 しくみブログでは初寄稿です。
この記事は 『Slack Advent Calendar 2016』14日目の記事です。
皆さんはチャットツールをどのくらい活用されているでしょうか?
フルリモートワークの弊社にとって、SlackでのやりとりはDiscordと同様、なくてはならないものとなっています。
SlackではEmoji reactionsという、発言に対してEmojiで反応できる機能があります。 弊社でもEmoji reactionsはよく活用されていて、独自のEmojiもたくさん追加されています。
日頃頻繁にreactionのやりとりをしていると、誰がどのくらいreactionを受け取ったんだろう?というのが気になってきませんか?
受け取ったreactionの数を見せることで次のreactionの動機にもつながりそうです。 そこで今回は、誰がどのくらいのreactionを受け取ったのか、可視化してみることにしました。
今回のゴール
今回はhubotに組み込む形でEmoji reactionsの集計と集計結果を出力をすることにします。
どう集計するか、についてですが、例えば、「昨日、yoshitsuguは :ok: 2個、 :+1: 1個もらった」という感じの出力を想定します。
hubotの活用
弊社Slackにはkibotという名前のbotが住んでいます。彼(彼女?)はDocomo雑談APIなど、巷にあふれるhubotプラグインを搭載しており、Slackを和やかにするという大切な役目を担っています。
今回はこのkibotに組み込んでいきます。
Slack APIの確認
さて、reactionの集計にはどのような情報が必要になるでしょうか?
Emoji reactionsは発言にひもづく形式なので、
- 昨日の発言一覧
- 各発言に対するreaction一覧
が必要そうです。
Slack APIのドキュメントを眺めてみると、channels.history で上にあげた両方がとれそうです。
また、Slack API上はユーザーがSlack内部IDのような形式でやりとりされます。実際のユーザー名をひいてくるためには、
を使うとよさそうです。
作ってみる
上記のSlack APIを使って集計できるように、以下のように書いてみました。
cron = require('cron').CronJob
dateformat = require('dateformat')
Q = require('q')
Slack = require('slack-node')
to_unixtime = (time) -> Math.floor(time.getTime()/1000)
module.exports = (robot) ->
slack = new Slack(process.env.HUBOT_SLACK_TOKEN)
weekdays = [ "日", "月", "火", "水", "木", "金", "土" ]
countEmoji = ->
today = new Date()
yesterday = new Date(new Date(today.toString()).setDate(today.getDate() - 1))
# 月曜なら金曜日をみる
if today.getDay() is 1
yesterday = new Date(new Date(today.toString()).setDate(today.getDate() - 3))
date = dateformat(yesterday, 'yyyymmdd')
date_str = "#{dateformat(yesterday, 'yyyy/mm/dd')}(#{weekdays[yesterday.getDay()]})"
yesterday_begin = new Date(dateformat(yesterday, 'yyyy/mm/dd') + " 00:00:00")
yesterday_end = new Date(dateformat(yesterday, 'yyyy/mm/dd') + " 23:59:59")
api = Q.denodeify slack.api
apis_by_channel = []
apis_by_channel_options = []
result = {}
api("channels.list").then (response) ->
for c in response.channels
option = {channel: c.id, latest: to_unixtime(yesterday_end), oldest: to_unixtime(yesterday_begin), count: 1000}
apis_by_channel_options.push(option)
apis_by_channel.push(api("channels.history", option))
return Q.all(apis_by_channel)
.then (values) ->
for i in [0..(values.length-1)]
reactions_get_qs = []
v = values[i]
for m in v.messages
reactions = m.reactions
reactions = m.file.reactions if m.file?.reactions
if reactions
user = robot.adapter.client.rtm.dataStore.getUserById(m.user)?.name
result[user] = {} unless result[user]
for r in reactions
result[user][r.name] = 0 unless result[user][r.name]
result[user][r.name] += r.count
results_str = "#{date_str}の集計結果です。\r\n"
for name, r of result
results_str += "#{name}: \t"
for emoji, count of r
results_str += ":#{emoji}:: #{result[name][emoji]}, "
results_str += "\r\n"
robot.send {room: '#general'}, results_str
.catch (err) ->
robot.logger.error(err)
robot.send {room: '#general'}, '集計中にエラーがおきました'
# 平日のみ、12時に集計
new cron '0 0 12 * * 1-5', () ->
countEmoji()
, null, true, "Asia/Tokyo"
試してみる
実際にこのコードを動かしてみると以下のようにkibotが集計結果を投げてくれるようになります。
人ごとに絵文字が集計されていることがわかります。 次のコミュニケーションにつながりそうですね。
今後の展望
現状、誰の発言が盛り上がったか、という点で可視化できましたが、以下のような問題もあります。
- 集計結果をテキストで並べるだけだとわかりにくい
- 誰の発言だけではなく、どの発言に注目が集まったかも見たい
今後の展望として、少しフォーマットを変えて提供してみることを検討しています。
検討中のフォーマットの例をあげると、以下のように、「今日の神」を表示する、というものです。
弊社ではよくカスタムEmojiの :kami: を使います。
これは「すごく助かった」、「すごく有用」、「すばらしい仕事」などをあらわす時に使います。 この「神」reactionをたくさんもらった人を「今日の神」として崇めるようなフォーマットを提供できると楽しそうだなーと思っています。
最後に
今回、hubotをベースに、SlackのEmoji reactionsを集計した話をご紹介しました。
皆さんもSlackでのコミュニケーションを活性化して、楽しく仕事ができるよう、工夫してみてはいかがでしょうか。
それでは。