【SlackAPI】無料版Slackワークスペースに所属している全ユーザーをAPIを利用して取得する

## 概要

>「あるチャンネルに全ユーザーを招待したいけど、一人ひとり招待するのは面倒くさい。」

こういった場面に直面したので、SlackAPIを用いて、ワークスペースに所属している全ユーザーのメンション名をスプレッドシートに出力する処理を[GAS](https://workspace.google.co.jp/intl/ja/products/apps-script/)(GoogleAppScript)で実装してみました。

https://qiita.com/baraobara/items/3cadc9f8bd1034b79e52

また、↑の記事を参考に
「 `#general` で `/who` というコマンドを打てば、招待できるんやん！」
とも思ったのですが、100人を超えると省略されてしまいます。
この記事で説明する方法は、**ワークスペースが100人以上いる**時に使う方法だと思ってもらえればと思います。


## 実装方針

実装方針はざっとこんな感じです。

① SlackAPIを利用する上で必要なトークン類を発行
② SlackAPI の [users.list](https://api.slack.com/methods/users.list) を叩く
③ 「削除済ユーザー」などの招待対象外のユーザーを弾く条件文を追加する
④ スプレッドシートに出力する

タイトルの「ワークスペースに所属している全ユーザーを取得する」だけを見ると、大分面倒くさそうですが、一つひとつはとてもシンプルです。非エンジニアでも全然実装できると思います。


## botトークンを発行

これは他所で何度も紹介されている内容なので省略します。

こちらの記事とか分かりやすかったのでおすすめです。

https://zenn.dev/kou_pg_0131/articles/slack-api-post-message

ただ、bot の scope の設定だけ、上の記事とは違うので補足します。
上の記事では、`chat:write`と設定していましたが、今回の実装では`users:read`を設定してください。

`Bot User OAuth Token`を生成するところまで出来たら、とりあえずこの章での目標は達成です。

## 実装
一つ前の章で、実装方針で言うところの①に相当する内容を達成できました。
残りの②〜④は一つのファイルにコードを書くだけなので、この章でまとめて紹介しちゃいます！

まずはスプレッドシートとGASを紐付けます。
スプレッドシートを新規作成して、`拡張機能 > AppScripts`を選択し、エディタを開きます。
![スクリーンショット 2021-11-30 7.21.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522217/37146582-58fa-d29e-6422-0e257bf6c533.png)


開いたエディタに以下のコードを貼り付けます。
`slack_app_token`に前章で作成したトークンを代入し、`実行`をクリックすればスプレッドシートに全メンション名が出力されます。

```javascript
function getSlackUser() {
  
  //  一つ前の章で作成した Bot User OAuth Token
  const slack_app_token = "xoxb-xxx...";
  
  const options = {
    "method" : "get",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : { 
      "token": slack_app_token
    }
  };
  
  // users.list(GET): ワークスペースの全ユーザーを取得する 
  const url = "https://slack.com/api/users.list";
  const response = UrlFetchApp.fetch(url, options);
  
  const members = JSON.parse(response).members;
  let arr = [];
  for (const member of members) {
    //削除済、botユーザー、Slackbotを除く
    if (!member.deleted && !member.is_bot && member.id !== "USLACKBOT") {
      // "表示名" もしくは "Slack名" を配列に格納
      let name = [member.profile.display_name || member.real_name]
      name[0] = '@' + name[0];
      arr.push(name);
    }
  }

  //スプレッドシートに書き込む
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheets()[0];
  const range = sheet.getRange(1, 1, arr.length);
  range.setValues(arr)
}

```

はい、以上です！
中身は気にせず、とりあえずメンション名を出力して招待したい人はここまでで大丈夫です。


ここからは、コードの重要な箇所を説明していきます。
興味がある人は是非！

***

### SlackAPIの users.list を叩く

ここは実装方針の`②SlackAPIの users.list を叩く`に該当します。

```javascript
  //  一つ前の章で作成した Bot User OAuth Token
  const slack_app_token = "xoxb-xxx...";
  
  const options = {
    "method" : "get",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : { 
      "token": slack_app_token
    }
  };
  
  // users.list(GET): ワークスペースの全ユーザーを取得する 
  const url = "https://slack.com/api/users.list";
  const response = UrlFetchApp.fetch(url, options);
```

作成したトークンを `payload` に忍ばせ、 `UrlFetchApp.fetch()` でAPIを叩きにいきます。
他にも細かいオブションを設定することも可能なので、詳しくは[公式docs](https://api.slack.com/methods/users.list)を参照してみてください。

また、 `url` , `options` の中身を変えれば、他の SlackAPI も叩けるので、色々応用も利かせられます。



### 招待対象外のユーザーを弾く条件文を追加する

次は`③「削除済ユーザー」などの招待対象外のユーザーを弾く条件文を追加する`についての実装です。

```javascript
  const members = JSON.parse(response).members;
  let arr = [];
  for (const member of members) {
    //削除済、botユーザー、Slackbotを除く
    if (!member.deleted && !member.is_bot && member.id !== "USLACKBOT") {
      // "表示名" もしくは "Slack名" を配列に格納
      let name = [member.profile.display_name || member.real_name]
      name[0] = '@' + name[0];
      arr.push(name);
    }
  }
```

for文で取得したユーザーを一つずつ取得し、招待対象外のユーザー以外を配列に追加する処理を書いています。
今回招待対象外としたユーザーは以下の3つです。

- 削除済ユーザー
- botユーザー
- idが`USLACKBOT`のユーザー


また、今回はチャンネルに招待することが目的なので、メンション名を出力する必要があります。
メンション名の仕組みは、基本的に`@+表示名`となりますが、表示名が設定されていない場合は`@+Slack名`となっているため、`let name = `ではor演算子を使用します。

member(user)のデータ構造については、公式docsの `ExampleResponse` を参照すれば、分かりやすいかと思います。

https://api.slack.com/methods/users.list#responses

### スプレッドシートに出力する

ここで最後です！
最後に↑でフィルターをかけたユーザーのメンション名をスプレッドシートに書き込みます。

```javascript
  //スプレッドシートに書き込む
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheets()[0];
  const range = sheet.getRange(1, 1, arr.length);
  range.setValues(arr)
```

ここはシンプルですね。
`arr.length`で書き込むセルの行数を設定し、`setValues()` で出力します。

それ以外は特に工夫点などはないので、「そもそも `getRange()` , `setValues()` とは何だ？」という方はGASの公式docsを参照してみてください！

https://developers.google.com/apps-script

## おわり

これにて解説は以上です！

SlackAPIやGAS関連は多くのシチュエーションで利用できると思うので、エンジニアの方も非エンジニアの方も是非一度触ってみてください！
意外と何でも効率化できるもんです(笑)