[小ネタ] 参加している Slack のチャンネル一覧を API + jq で取得する

いま現在参加している Slack のチャンネル一覧って TXT データで欲しくなりませんか? ぼくはなったのですが、他に方法を思いつかなかったので API を叩いてみました。
2019.09.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

みなさん、Slack 使ってますか!(挨拶

弊社でも社内標準のチャットツールとして Slack が使われています。
先日、自分が参加しているチャンネルとユーザーグループの一覧を棚卸しする個人的な需要が発生したのですが、「API 叩けばええんやろ」と思ったところその通りだったので共有します。

叩かなくてもいいやり方があるかも知れないので、叩きたくない方は別途探してみて下さい。
ぼくはむしろ叩くことが目的になったのでそのまま行きます。

手順

大きく 2 段階に分かれます。

  1. 自分のアカウントの ID を取得
  2. その ID がメンバーに含まれるチャンネル・ユーザーグループの一覧を取得する
    • パブリックチャンネル
    • プライベートチャンネル
    • ユーザーグループ

準備

API を叩くためには Legacy token が必要と言うことなので、それも準備します。下記の URL にアクセスして生成してください。

xoxp- で始まる 74 桁の文字列がそれです。

このトークンは Legacy と言われるだけあって権限設定が大きく、漏洩した日には結構影響が大きそうに思えたので、扱いは慎重にしたほうが良さそうです。
(どのくらい大きいか、は、先を読んで頂ければわかるかなと思います)

それから、こういう作業のときにはかかせない curljq もご用意下さい。

アカウント ID の取得

APIで該当Slackプロジェクトに所属している全ユーザのリストを JSON で取得し、そこから自分の ID を jq で探します。

自分を探す決め手としては、名前や表示名なども使えるのですが、とりあえず一意に分かりやすくなるという理由でメールアドレスを検索しています。
プロフィールにメールアドレスを入力していない場合は、適宜別のフィールドで検索してみて下さい。

SlackMyToken="xoxp-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxxxxxxxxxxxxx"
SlackMyEMail="watanabe.seigo@classmethod.jp"

## 自分のID取得
SlackMyId=$(
  curl -s \
    -H 'Authorization: Bearer '${SlackMyToken} \
    -H 'Content-type: application/x-www-form-urlencoded' \
    https://slack.com/api/users.list | \
    jq -r '
      .members[]
      | select( .profile.email == "'"${SlackMyEMail}"'" )
      | .id'
) && echo $SlackMyId

取得した ID は環境変数 SlackMyId に入っています。

パブリックチャンネル

パブリックチャンネルとプライベートチャンネルは、一覧を取得するのにそれぞれ API が違います。

まずはパブリックチャンネルです。いったん全チャンネル情報を取得し、そのなかから、前に取得した ID が含まれるものを抽出します。

## SlackMyToken = Legacy token
## SlackMyId = 自分の ID

curl -s \
  -H 'Authorization: Bearer '${SlackMyToken} \
  -H 'Content-type: application/x-www-form-urlencoded' \
  https://slack.com/api/channels.list | \
  jq -r '
    .channels[]
    | select( .members[]|in({"'${SlackMyId}'":null}) )
    | select( .is_archived == false )
    | .name'

一応条件をつけて、既にアーカイブされているチャンネルは除外しています。
もしそちらも必要であれば、 | select( .is_archived == false ) の部分を削除して実行してみて下さい。

プライベートチャンネル

パブリックチャンネルとほぼ同様のやり方ですが、以下の点が異なります:

  • 前述の通り叩く API が違う
  • 自分の所属しないチャンネルは取得できない = ID で絞り込む必要がない
curl -s \
  -H 'Authorization: Bearer '${SlackMyToken} \
  -H 'Content-type: application/x-www-form-urlencoded' \
  https://slack.com/api/groups.list | \
  jq -r '
    .groups[]
    | select( .is_archived == false )
    | .name'

ユーザーグループ

こちらもほぼ同じなんですが、単にグループ名だけ出されてもよく分からないので、 column コマンドで整形しながら出力しています。
所属人数まで含めたのは、チームひとり状態だと抜けるに抜けられないためです。

curl -s \
  -H 'Authorization: Bearer '${SlackMyToken} \
  -H 'Content-type: application/x-www-form-urlencoded' \
  'https://slack.com/api/usergroups.list?include_users=true' | \
  jq -r '
    .usergroups[]
    | select( .users[]|in({"'${SlackMyId}'":null}) )
    | [.handle,.user_count,.name,.description]
    | @tsv' | \
  column -t -s$'\t'

ポイントは URL の後ろに、クエリパラメータとして include_users=true を指定しているところでしょうか。
これを指定しないと、ユーザーグループに所属するユーザーが取得できないためです。

まとめ

Slack の API を叩いて、自分の所属するチャンネルやユーザーグループを入手する方法でした。

この方法は Legacy token を使うということで、非推奨な方法と言えますが、、ブラウザからコピペで持ってきたり HTML を加工したりといった手間ナシに入手できるのはいいですね!