hubotでslackに参加しているユーザーからランダムに抽選するやつを書いた

More than 3 years have passed since last update.


はじめに

例えば進捗報告とか、朝会のときに、司会とかをランダムで選出する機能を実装したいとする。そのときに、ハードコーディングでメンバーを所持していてもいいのだが、それだと面倒くさいので、Slack APIから取ってこれたら便利だなあと思って書いた。ざっと調べたら、特にそういう記事が見当たらなかったので、メモがてらに書いておく。


言い訳

hubotとslackを連携させるためにはhubot-slackというライブラリが便利なのだけれども、正直見ていて良くわからなかったので諦めた(ひどい)。もっと言うと、hubot-slackは、node-slack-clientに依存しており、礼儀正しい方法としては、これらを経路するほうがベター。

とはいえ、SlackのAPI自体にアクセスする方法は、別段Wrapperを用意しなくても、比較的楽な方法で取ってくることができる。要するにトークンをパラメータに渡してあげれば良いだけである(参考)。なので、下のようにコードを取ってあげれば、一覧で取得は可能だ。

request = require('request')

request.get
url: "https://slack.com/api/users.list?token=#{process.env.HUBOT_SLACK_TOKEN}"
, (err, response, body) ->
console.log JSON.parse(body)

ただし、基本的にrequestでgetしたデータは文字列なので、そのままアクセスしようとすると、エラーが発生するので、JSON.parseを経路してやる必要がある。


些細なテクニック


リスト内包記法

実際のAPIのJSON構造についてはSlackの公式ドキュメントを見てもらうとして、リスト内包記法が便利なので、それを使っている:

members = (member_raw["name"] \

for member_raw in JSON.parse(body)["members"])

こういう感じに書くと、いい具合にidだけ取れるのでいい感じとなる。ただ、これについではunderscore.jsmapというのがあるけれど、場合によってはそっちのほうがいいかもしれない。今回はsampleだけの利用に止めた。


こういう感じ

全体像で見ると、下のようになる:

# Description:

# Slackの参加者からランダムで抽選する奴
# Author:
# esehara

_ = require 'underscore'
module.exports = (robot) ->
robot.respond /select-member/i, (msg) ->
request = require('request')
request.get
url: "https://slack.com/api/users.list?token=#{process.env.HUBOT_SLACK_TOKEN}"
, (err, response, body) ->
members = (member_raw["name"] \
for member_raw in JSON.parse(body)["members"])
msg.send "#{_.sample(members)}さんが選ばれました"

雑なHackではありますが、Slackを利用しているところで、何かこういうのを使いたいひという人がいれば、コピペして使うといいと思う。