はじめに
インターン先であるとき、Slackのチャンネル一覧と所属しているメンバー一覧のデータがほしい、となり、ちゃちゃっとプログラムでぱぱっとデータを取得するために色々試行錯誤したので、その結果をまとめます。
Slack APIは、legacy tokenとoauth2.0によるtokenの2種類の方式があるのですが、legacy tokenのほうが2020年5月に廃止になってしまうということで、本記事は新しいoauth2.0による方式で実行しました。
tokenを発行するために、若干つまずいたので、そこらへんも丁寧に解説します!
本記事でやらないこと
- bot作成
- webhookを使ってうんちゃらかんちゃら
- slackのアクションにsubscribeして何かを実行する
- サーバーを立てる
とりあえずローカル環境でslackのAPI叩いて、データをゲットしたよね、ってぐらいのノリ。
Slack連携のやり方
まず、トークンを発行するために、slackと連携します。
アプリの名前とワークスペースを選択して次に行きます。
次、↑の画像のように、「Oauth & Permissions」というところに行き、「Scope」の設定をします。
SlackのAPIでは、作成したアプリごとにscopeをわけて、権限を管理します。
今回は、
- チャンネルの取得
- ユーザーの取得
ができればいいので、設定する必要があるscopeは2つ、users:read
とchannels:read
です。
↑のように設定したら、スクリプトを実行するのに必要な権限が設定できました。次にトークンを発行します!
Settingsの「Install App」にいき、アプリをインストールします。これを実行しないとトークンが発行できないです。
「Install App to Workspace」をクリックします。
こんな感じでOauth Access Token
が発行できました。これを使うと、SlackのAPIが実行できます!
スクリプト
と、その前に発行されたトークンが正しく機能しているか実験してみましょう。
curl https://slack.com/api/conversations.list?token=発行したトークン
で、それっぽいレスポンスが返ってきたら成功です!
さて、チャンネル一覧と、各チャンネルに所属しているメンバー一覧を出力するスクリプトは以下のようになります。
なお、Rubyで書いてあるので、各自で言語は読み替えてください!
touch slack.rb
require 'net/http'
require 'uri'
require "json"
require 'pp'
TOKEN = "発行したトークン"
SLACK_API_BASE = 'https://slack.com/api'
# チャンネル一覧を取得するAPI
fetch_all_channels_url = "https://slack.com/api/conversations.list?token=#{TOKEN}"
res = Net::HTTP.get(URI.parse(fetch_all_channels_url))
channel_hash = JSON.parse(res)
channels = channel_hash["channels"]
channels = channels.select { |channel| !channel['is_archived'] && !channel['num_members'].zero? } # 削除されたチャンネルや所属人数が0のチャンネルを除外
# メンバー一覧を取得するAPI
fetch_all_members_url = "#{SLACK_API_BASE}/users.list?token=#{TOKEN}"
res = Net::HTTP.get(URI.parse(fetch_all_members_url))
members_hash = JSON.parse(res)
members = members_hash["members"]
members = members.reject { |m| m["deleted"] } # 削除されたユーザーを除外
channels.each do |channel|
# あるチャンネルに入っているユーザー一覧を取得
fetch_members_in_channel_url = "#{SLACK_API_BASE}/conversations.members?token=#{TOKEN}&channel=#{channel['id']}"
res = Net::HTTP.get(URI.parse(fetch_members_in_channel_url))
next unless res["ok"]
user_hash = JSON.parse(res)
user_ids = user_hash["members"]
user_list = []
user_ids.each do |id|
member = members.detect { |m| m["id"] == id }
user_list << member["real_name"] if member
end
# csvで出力
puts "#{channel['id']},#{channel['name']},#{user_list.join(",")}"
end
あとは、実行するだけです
bundle install
ruby slack.rb > data.csv
実行結果はこんな感じ
C40DMBLHX,general,山田花子,山田太郎,hoge,fuga(以下チャンネルに所属するメンバーすべて)
...
githubでコードは公開しているので、そちらもご参照ください!
今回使用するAPIの説明
蛇足ですが、せっかくけっこう調べたので、アウトプットをしておきます。SlackのAPIの中にも、deprecated
になっているエンドポイントがちょいちょいあります。
僕が今回公開しているコードも、元のコードは別のQiitaの記事から取ってきたのですが、使用しているエンドポイントが非推奨になっていたため、そこは変更しました。
今回叩いているエンドポイントは以下のとおりです。
ユーザー一覧を取得するAPI
https://slack.com/api/users.list
チャンネル一覧を取得するAPI
https://slack.com/api/conversations.list
チャンネルに所属するユーザーを取得するAPI
https://api.slack.com/methods/conversations.members
詳しくはドキュメントに書いてあるのですが、APIのリミットレートもありまして、Tier1
からTier4
まで。今回使用しているエンドポイントはどれもTier4
のもので、100 requests per minute
の制限がかかっております。
最後に
退屈なことはプログラムにやらせましょう!
このプログラムを実行すれば、数分ですべてのデータが出ますが、同じ作業を手作業でやるとなると、途方にくれますよね。viva プログラミングです!