はじめに
こんにちは、18卒のおでんとよばれているものです。
今回は弊社で実際に使われているGASを使ってSlackのチャンネル情報を楽に共有する方法を紹介したいと思います。
こんな感じで共有しています
全社員がアクセスできるスプレッドシートにGASでチャンネルの情報を書き込んで共有をしています。
お見せできる例として、こんな感じでクラブ活動のチャンネルをまとめたシートをパッと一覧で見れるようにしてあります!
どうやってやるの?
手順としてこの3つことを行いました。
- 全てのプライベートチャンネルにシステム用のアカウントが入っている状態にする
- SlackAppの作成
- GASを実行
これに関してどうやってやったかを紹介させていただきます。
1. 全てのプライベートチャンネルにシステム用のアカウントが入っている状態にする
今回 conversations.list APIを使って実装をしたのですが、APIの仕様上Privateチャンネルの情報は、Access Tokenを発行したユーザーが入っているチャンネルしか獲得できなかったです。
Legacy tokenで対応することも検討したのですが、全ての権限を持っているtokenは、全てのSlackの操作ができてしまう危険な物なので、
channels:read (Publicチャンネルの情報)
と groups:read(Privateチャンネルの情報)
に絞ってAccess Tokenを発行しました。
皆さんに協力していただき、全てのプライベートチャンネルにシステム用のアカウントが入っている状態にした結果、Legacy tokenを使わずに、Privateチャンネルの情報も全社員が見ることができるようになりました。
2. Access Tokenの発行
次にAccess Tokenを発行するための準備をします。
Appの作成
システム用のアカウントでSlackにログインしていることを確認して、https://api.slack.com/ にアクセスして Start Buildingを選択します。
選択した後、Create a Slack Appが表示されますので、任意の名前と導入するワークスペースを選択して Creat Appで作成をします。
※ 2. Access Tokenの発行に載せている画像は自分のプライベートSlackにインストールした例になります。
Tokenの発行
OAuth & Permissions の Scopes で今回利用するchannels:read (Publicチャンネルの情報)
と groups:read(Privateチャンネルの情報)
を選択します。
Scopesで上記2つの権限が与えられていることを確認して、Install App to Workspace を選択します。
Install App to Workspaceを選択したら、許可しても良いかが表示されるので、許可するを選択してワークスペースにアプリをインストールします。
インストールが完了したら、画像のように xoxp-
から始まるAccess Tokenが発行されます。
APIを利用する際にこのAccess Tokenを利用します。
3. GASを実行
GASの準備
こんな感じでスプレッドシートを作成して、スクリプトエディタを開いてGASを作っていきます。
実行方法
利用する関数は3つです。
- slackApi //SlackのAPIから情報を取ってくる
- getChannelList //特定のシートにPublicチャンネルリストを書き込む
- getPrivateChannelList //特定のシートにPrivateチャンネルリストを書き込む
slackApi関数を用意しておけば、他のAPIを利用するときも使い回せるので一度作ってしまえば超便利です!!
プログラム
function slackApi(token, path, options) {
if (!options) options = {};
var url = "https://slack.com/api/" + path;
var q = "?token=" + encodeURIComponent( token );
for (var key in options) {
q += "&" + encodeURIComponent( key ) + "=" + encodeURIComponent( options[ key ] );
}
url += q;
var res = UrlFetchApp.fetch(url);
var ret = JSON.parse(res.getContentText());
if (ret.error) {
throw "GET " + path + ": " + ret.error;
}
return ret;
}
function getChannelList() {
const token = PropertiesService.getScriptProperties().getProperty("slackApiToken");
var options = { "limit" : 200 };
var channels = slackApi(token, "conversations.list", options);
const spreadsheet = SpreadsheetApp.openById('スプレッドシートのID入れてね!');
const sheet = spreadsheet.getSheetByName('PublicList');
const archivedSheet = spreadsheet.getSheetByName('アーカイブPublicList');
sheet.getRange("A1").setValue("チャンネル名");
sheet.getRange("B1").setValue("目的");
sheet.getRange("C1").setValue("トピック");
archivedSheet.getRange("A1").setValue("チャンネル名");
archivedSheet.getRange("B1").setValue("目的");
archivedSheet.getRange("C1").setValue("トピック");
var targetCellNumber = 2;
var targetArchivedCellNumber = 2;
while (true) {
channels.channels.forEach( function (ch) {
if(!ch.is_archived) {
sheet.getRange("A"+targetCellNumber).setValue(ch.name);
sheet.getRange("B"+targetCellNumber).setValue(ch.purpose.value);
sheet.getRange("C"+targetCellNumber).setValue(ch.topic.value);
targetCellNumber = targetCellNumber + 1;
} else {
archivedSheet.getRange("A"+targetArchivedCellNumber).setValue(ch.name);
archivedSheet.getRange("B"+targetArchivedCellNumber).setValue(ch.purpose.value);
archivedSheet.getRange("C"+targetArchivedCellNumber).setValue(ch.topic.value);
targetArchivedCellNumber = targetArchivedCellNumber + 1;
}
});
if (channels.response_metadata.next_cursor == "") break;
options = { "limit" : 200, "cursor" : channels.response_metadata.next_cursor };
channels = slackApi(token, "conversations.list", options);
}
}
function getPrivateChannelList() {
const token = PropertiesService.getScriptProperties().getProperty("slackApiToken");
var options = { "limit" : 200, "types" : "private_channel" };
var channels = slackApi(token, "conversations.list", options);
const spreadsheet = SpreadsheetApp.openById('スプレッドシートのID入れてね!');
const sheet = spreadsheet.getSheetByName('PrivateList');
const archivedSheet = spreadsheet.getSheetByName('アーカイブPrivateList');
sheet.getRange("A1").setValue("チャンネル名");
sheet.getRange("B1").setValue("目的");
sheet.getRange("C1").setValue("トピック");
archivedSheet.getRange("A1").setValue("チャンネル名");
archivedSheet.getRange("B1").setValue("目的");
archivedSheet.getRange("C1").setValue("トピック");
var targetCellNumber = 2;
var targetArchivedCellNumber = 2;
while(true) {
channels.channels.forEach( function (ch) {
if(!ch.is_archived) {
sheet.getRange("A"+targetCellNumber).setValue(ch.name);
sheet.getRange("B"+targetCellNumber).setValue(ch.purpose.value);
sheet.getRange("C"+targetCellNumber).setValue(ch.topic.value);
targetCellNumber = targetCellNumber + 1;
} else {
archivedSheet.getRange("A"+targetArchivedCellNumber).setValue(ch.name);
archivedSheet.getRange("B"+targetArchivedCellNumber).setValue(ch.purpose.value);
archivedSheet.getRange("C"+targetArchivedCellNumber).setValue(ch.topic.value);
targetArchivedCellNumber = targetArchivedCellNumber + 1;
}
});
if(channels.response_metadata.next_cursor == "") break;
options = { "limit" : 200, "types" : "private_channel", "cursor" : channels.response_metadata.next_cursor };
channels = slackApi(token, "conversations.list", options);
}
}
プログラムの注意事項
Access Tokenをコードに乗せるのは危ないので、GASのスクリプトのプロパティにTokenを置くようにして、getProperty
から読みだすようにしてあります。
const token = PropertiesService.getScriptProperties().getProperty("slackApiToken");
以下の画像のように【2. Access Token】の発行で獲得したAccess Tokenの値を入れてあげればプログラムを実行することができます。
トリガーを設定して自動で更新をしよう!
毎日手動で実行するのは手間なので、GASの特権であるトリガーで毎日実行するようにしましょう!!
画像のように、実行したい関数を選んで保存をすれば、毎日スプレッドシートにSlackのチャンネルのリストが更新されます。
終わりに
いかがでしたでしょうか。
GASは、サーバー代もかからないかつスプレッドシートと連携がしやすいので、一覧化して全社員に共有するのに凄く簡単にできます。
皆さんも是非試していただけると嬉しいです!!