こんにちは。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のような形式でやりとりされます。実際のユーザー名をひいてくるためには、users.list を使うとよさそうです。
作ってみる
上記のSlack APIを使って集計できるように、以下のように書いてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
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でのコミュニケーションを活性化して、楽しく仕事ができるよう、工夫してみてはいかがでしょうか。
それでは。