【GAS】Slackのチャンネルリストを書き出すコード2通りとページ送りのメモ
概要
GASで、APIを利用してSlackのチャンネル情報を取得し、指定した情報をアクティブシートに書き出す関数を2通り書いたのでメモしてみました。記事の最後に、ページを巡回しながらfetchしていく考え方についてもメモしています。
実行結果
実行結果はこのような感じ。
特徴
チャンネル数が多くても、全ページを巡回し、すべてのチャンネルのリストを取得していくコードです。
前提
slackのBotへの権限付与やトークンの取得は済んでいるという前提です。
まだの場合は、slack APIのリファレンス、下記などを参考に設定が必要です。
コード
(1) 一体型のコード
/** Slackのチャンネル情報の一部を取得してアクティブシートに書き出す関数
*事前にslackのボットに権限を付与して、トークンを入手しておく必要あり
*'ここにトークンをベタ書きで入力'の部分にトークンを入力しておく必要あり
*/
function setSlackChannelInfoInSheet() {
const channelInfoArr = [];
let cursor; //whileの外で宣言だけして未定義undefinedにしておく(空文字にしないこと!そうするとwhileが最初からfalseになって実行されなくなってしまうので)
while (cursor !== '') { //最終頁ではnext_cursorが空文字列となることを利用したwhile文で全ページを巡回
const token = 'ここにトークンをベタ書きで入力'; // propertyストアの使い方が分かっている方はそれを使用
const url = 'https://www.slack.com/api/conversations.list';
const options =
{
method: "get",
contentType: "application/x-www-form-urlencoded",
headers: { "Authorization": "Bearer " + token },
"payload": {
"token": token,
"limit": 200,
//1ページ当たりのlimitの設定上限は1000だがメソッドによっては上限まで取れない可能性。
//slack推奨は1ページあたり100-200件(https://api.slack.com/docs/pagination)
"cursor": cursor
}
}
//fetchメソッドによる情報取得
const response = UrlFetchApp.fetch(url, options);
const conversationsListObj = JSON.parse(response);
//シートのヘッダーとなるレコードを配列に追加
channelInfoArr.push(['チャンネル名', 'チャンネルID', 'チャンネル概要','アーカイブ済'])
//取得したチャンネルごとに、チャンネル名、チャンネルID、チャンネル概要、アーカイブ済かどうかのレコードを配列に追加
conversationsListObj.channels.forEach(channel => channelInfoArr.push([channel.name, channel.id, channel.purpose.value, channel.is_archived]));
//次のページをリクエストするためのnext_cursorをレスポンスから抽出してcursorに代入(これがoptionsに入るため、次のページが取れる)
cursor = conversationsListObj.response_metadata.next_cursor;
}
//アクティブシートに書き出し
const sheet = SpreadsheetApp.getActiveSheet();
sheet.clear()
.getRange(1, 1, channelInfoArr.length, channelInfoArr[0].length)
.setValues(channelInfoArr);
}
(2) 関数切り分け型のコード
/**
*Slackのチャンネル情報の一部を取得してアクティブシートに書き出す関数
*事前にslackのボットに権限を付与して、トークンを入手しておく必要あり
*SLACK_BOT_USER_OAUTH_TOKENをプロパティストアに保存しておく必要あり
*NOTE:
*最終頁ではnext_cursorが空文字列となる。
*slackの推奨は1ページあたり100-200件の取得
*1ページあたりの最大は1000件だがこれはメソッドに依存し
*1000件指定してもその通りの実行が確保されるわけではない
*上記2点の出典:https://api.slack.com/docs/pagination
*youtube APIではページトークンが最終頁でundefinedになるが、slackでは空文字なので
*cursorを宣言するときは空文字で初期化せず、未定義にしておく(さもないとwhile文は一切実行されない)
*/
function setSlackChannelInfoInSheet() { // 実行関数
const channelInfoArr = [];
let cursor;
while (cursor !== '') {
const obj = fetchConversationsListObj(cursor);
extractChannelInfoAndPushIntoArr(obj, channelInfoArr);
cursor = getCursor(obj);
}
setArrInSheet(channelInfoArr, 'slackChannelList')
}
/**
* SlackのConversationsListをオブジェクトにして取得する関数
NOTE:slackの推奨は1ページあたり100-200件の取得(https://api.slack.com/docs/pagination)
* @param {string} cursor - whileの1周目ではundefinedが渡され、以降のは前頁で取得したnext_cursorが渡される
* @return {Object} fetchしたresponseをparseしたオブジェクト
*/
function fetchConversationsListObj(cursor) {
const token = PropertiesService.getUserProperties().getProperty('SLACK_BOT_USER_OAUTH_TOKEN');
const url = 'https://www.slack.com/api/conversations.list';
const options =
{
method: "get",
contentType: "application/x-www-form-urlencoded",
headers: { "Authorization": "Bearer " + token },
"payload": {
"token": token,
"limit": 200,
"cursor": cursor
}
}
const response = UrlFetchApp.fetch(url, options);
const conversationsListObj = JSON.parse(response);
return conversationsListObj;
}
/**
* fetchのレスポンスのオブジェクトから情報を抽出して配列に追加
* @param {Object} obj – fetchしたレスポンスのオブジェクト
* @param {Array} arr – 指定した情報を保存していく配列
*/
function extractChannelInfoAndPushIntoArr(obj, arr) {
arr.push(['チャンネル名', 'チャンネルID', 'チャンネル概要','アーカイブ済']) //シートのヘッダとなるレコードを配列の1要素目に入れる
obj.channels.forEach(channel => arr.push([channel.name, channel.id, channel.purpose.value, channel.is_archived]));
}
/**
* fetchのレスポンスのオブジェクトからnext_cursorを取り出して返す関数
* @param {Object}} obj – fetchしたレスポンスのオブジェクト
* @return {string} 次のページをfetchするためのnext_cursor(レスポンスオブジェクトに含まれる)
*/
function getCursor(obj) {
const cursor = obj.response_metadata.next_cursor;
return cursor;
}
/**
* 受け取った配列をアクティブシートに書き出す関数
* @param {Array}} arr – レスポンスから取得した情報を持つ二次元配列
* @param {string} sheetname - 出力先シートのシート名
*
*/
function setArrInSheet(arr) {
const sheet = SpreadsheetApp.getActiveSheet();
sheet.clear()
.getRange(1, 1, arr.length, arr[0].length)
.setValues(arr);
}
参考URL
Slack APIのconversations.listメソッド
[補足]APIのレスポンスのページを進んでいくコードについて
次のページ、次のページと自動的にリクエストするコードを書く時、私は以下のようにしています。
*今回、next_cursorがレスポンスオブジェクトのどの階層にあるかをログ出力して確認するには、上のコードで"limit":200と書いているところを、"limit":3などのように(テスト用に一時的に)少なく書き換えてからconsole.log(conversationsListObj)をするとよさそうに思います。
1ページあたり1000件といった状態でログ出力すると、出力の後半が省略されてしまい、階層構造の全体像が見られない可能性があるからです。
この記事が気に入ったらサポートをしてみませんか?