要求仕様

  • GUI であること
  • 取得するチャンネルはパブリックチャンネルだけでよい

チャンネル一覧を取得する方法

札束で殴る

Slack の契約プランによっては管理者権限ですべてのチャンネル情報を取得できる (パブリック・プライベート問わずすべてのチャンネルが対象).

チャンネル管理ツールを使用する | Slack

誰がこの機能を利用できますか?

  • デフォルトでは、ワークスペースのオーナーまたは管理者(プラス)、および OrG プライマリーオーナー(Enterprise Grid)
  • プラスEnterprise Grid の各プラン

料金プラン | Slack

プラス アクティブユーザー 1 人当たり月額 ¥1,800(月払い)

プラスプランの料金を捻出できるならプラスプランで運用すればよい.しかし今回の案件ではプラスプランの契約は難しかったため別の案を考える.

API を叩く

パブリックチャンネルの取得だけであればプラスプラン未満の契約であっても API を叩けばよい.今回はこちらの方法を選択する.

conversations.list method | Slack

技術選定

下記の理由により Spreadsheet と Apps Script の組み合わせを採用した.

  • Web アプリとして様々な環境で使用できる可能性が高い
  • プログラムへのアクセス面でセキュリティを考える必要性が小さい
    • Google アカウントで認証できる
  • メンテナンスコストが小さい
    • インフラを自前で運用する必要がない
    • Apps Script はプログラミング経験があれば誰でも読み書きできる

実装

Slack

任意のアカウントでアプリを作成し,ワークスペースへのインストールとトークンの発行を行う.アプリの権限は channels:read のみを指定する. channels:read 権限があれば conversations.list メソッドを実行できる.

Apps Script

新規 Spreadsheet を作成する. Spreadsheet 作成後にスクリプトエディタを起動してスクリプトを作成する.コードは以下の通り.エラーや例外を処理していないため自己責任で実行すること.

const SLACK_ACCESS_TOKEN = "xoxp-your-token";
const SLACK_API_BASE_URL = "https://slack.com/api/";

/**
 * main
 */
function main() {
  const limit = "100";
  let cursor = "";
  let channelDetails = [["チャンネル名", "チャンネルの説明"]];
  do {
    const response = getSlackChannelList(limit, cursor);
    const channels = response.channels;
    for (let i = 0; i < channels.length; i++) {
      // 名称が hoge または fuga から始まるチャンネルを取得する
      if (/^(hoge|fuga)/.test(channels[i].name)) {
        channelDetails.push([channels[i].name, channels[i].purpose.value]);
      }
    }
    cursor = response.response_metadata.next_cursor;
  } while (cursor);
  writeChannelsToSheet(channelDetails);
}

/**
 * Slack のチャンネル一覧を取得する
 * https://api.slack.com/methods/conversations.list
 */
function getSlackChannelList(limit, cursor) {
  const headers = {
    "Authorization": Utilities.formatString("Bearer %s", SLACK_ACCESS_TOKEN)
  };
  const payload = {
    "limit": limit,
    "cursor": cursor,
    "exclude_archived": "true"
  };
  const options = {
    "method": "get",
    "headers": headers,
    "payload": payload
  };
  const url = SLACK_API_BASE_URL + "conversations.list";
  const response = UrlFetchApp.fetch(url, options);
  return JSON.parse(response);
}

/**
 * 引数 (配列) の中身をスプレッドシートに出力する
 * 
 * channelDetails = [
 *   [<channelName>, <channelDescription>],
 *   ...
 * ];
 */
function writeChannelsToSheet (channelDetails) {
  const sheetName = "result";
  const spreadsheet = SpreadsheetApp.getActive();
  let resultSheet = spreadsheet.getSheetByName(sheetName);
  if (resultSheet) {
    spreadsheet.deleteSheet(resultSheet);
  }
  resultSheet = spreadsheet.insertSheet(sheetName);
  const row = 1;
  const column = 1;
  const numRows = channelDetails.length;
  const numColumns = channelDetails[0].length;
  const range = resultSheet.getRange(row, column, numRows, numColumns);
  range.setValues(channelDetails);
}

Spreadsheet

スクリプトの実行ボタンを作成する.今回は適当に図形を描画して中に説明文を記載する.

button

上図のボタン (図形) に先述のスクリプトの関数 main を割り当てる.

assign-script

以上でボタン押下時に main が実行されるようになる.初回ボタン押下時に Google からスクリプト実行に関して認証を求められるため,画面の指示に従って認証する.認証後,改めてボタンを押下すると result シートが作成されてチャンネル一覧が出力される.