Slackで全員を招待するためのメンションを生成するAPIを作る


はじめに

こんにちは、アドベントカレンダー17日目担当の避雷です。所属サークルが各種インフラを整えないまま大量の新入生を迎えてしまい、情報の透明性が最悪なことになってしまいました。特にSlackのChannelによる情報の分断が大変悪質で、全員に周知が必要であろう情報が少数しかjoinしてないchannelで行われ、「聞いてないんだけど!?!?!?!?」みたいな現象が100万回ぐらい発生してしまいました。流石に業を煮やした僕は「チャンネルは基本全員招待する」というルールを設けようとしました。しかしここで問題が一つ。
Slackには自動でメンバー全員を招待する設定がありません。一般的に言われる一番楽に全員招待する方法は、

  • /who をgeneralで打って全員分のメンション文をコピー
  • 招待したいチャンネルでコピーしたメンションを送信
  • 一括Inviteするかしないか聞かれるので肯定する

と言うものです。channel未加入のメンバにメンションを飛ばすと招待することができる、という仕様を利用した方法ですね。
これは一見合理的な手段に見えますが、一つ大きな問題があります。
「100人以上のメンバーがいるchannelだとメンバ表示が省略される」

他39人のメンバーです!じゃなくてさ…という感じですが、だからと言って新しくbotを作るのも微妙に大変です。
しょうがないので、 /who と同じ感じでメンションを全メンバ分列挙した文章を生成する何らかの方法を考えましょう。Slackでは、ユーザーにAPIを提供していて、各ワークスペース毎の情報を取得することができます。僕はこの問題を解決するために、WebAPIを作ることにしました。

使う技術

  • SlackAPI … Keyを作成できれば全メンバの情報をjson形式でfetch出来る。
  • Google Apps Script … JSでWebAPIを作ることができる。別個でサーバーを立てる必要とかもなく、書けばそのまま公開出来て、動く(すごい)

実装

SlackAPIを使う準備

まずはSlack API 用のAuthenticationをします。

Legacy tokensの取得

https://api.slack.com/custom-integrations/legacy-tokens へ移動してSlack API 用のLegacyTokenを取得します。
Slackにログインすると自分がゲストではないすべてのワークスペースの一覧がこの下に表示されるので

Legacy、と書いてあるように古いVersionのようですし、何か個人用だよ、みたいなことも書いてあるけど、今回はあくまで狭い規模の利用なのでこれを使います。
その中から全メンバを取得したいワークスペースを選択してtokenを発行します。

上記のボタンを押すとパスワードの再入力を要求され、その後tokenが発行されます。これは後述のGoogle Apps Scriptで使うのでメモっておきましょう。

Google Apps Scriptの実装

function doGet(e) {
  //SlackAPIをたたく
  var URL = 'https://slack.com/api/users.list?token=【ここにTokenを代入】';
  //URLの取得
  var responce = UrlFetchApp.fetch(URL);
  //Jsonの生成
  var data = JSON.parse(responce.getContentText());

  var out = ContentService.createTextOutput();
  var resultText = "";
  for(var i = 0; i < data["members"].length; i++){
    resultText += "@" + data["members"][i]["profile"]["real_name"] + " ";
  }
  out.setMimeType(ContentService.MimeType.TEXT);

  out.setContent(resultText);
  return out;

}

やってることは一般的なWebAPIと同じで、ほぼJsonからデータを取り出すところでちょっとだけ複雑なコードを書いているだけです。メンションを生成するためには@Hogehoge に該当するHogehogeを上手く取得する必要があります。APIで吐き出されるjsonを読めばわかるのですが、それっぽいuser_nameっぽいものがたくさんありますが、その中でreal_nameを選択すると上手くメンション文を生成することができます。

最後に

コレでアクセスすればメンション文が手に入るWebAPIが完成しました。平でURLにアクセスするのがはばかられるなら何か他のツールで包むと良いと思います。ウチのサークルではそのまま利用しています。