如何使用conversation.list API获取Slack工作区中的所有频道?



当我通过next_cursor分页时,每次通过 NodeJS 函数点击 URL 时,我都会得到不同数量的通道。

一旦获取的总通道数为 7488,则再次为 300。每次运行程序时都会有所不同。

URL : https://slack.com/api/conversations.list?types=public_channel&cursor={cursor}=&exclude_archived=true&token={token}

该问题是由于 slack 的速率限制造成的,conversation.list 属于第 2 层速率限制。每分钟最多只有 20 个请求。

function fetchData(){
getResponse(url);
function getResponse(url) {
let tempData = '';
https.get(url, (resp) => {

resp.on('data', (chunk) => {
tempData += chunk;
});
resp.on('end', () => {
try{
tempData = JSON.parse(tempData);
if(tempData.channels){
resultData.push(tempData.channels);
}
if (tempData.response_metadata && tempData.response_metadata.next_cursor) {
if(tempData.response_metadata.next_cursor === ''){
return resultData;
}
let cursorIndex = url.indexOf('cursor');
let newUrl = url.slice(0,cursorIndex);
let token = apiConstants.SLACK_API['ACCESS_TOKEN'];
let nextCursor = tempData.response_metadata.next_cursor.slice(0,tempData.response_metadata.next_cursor.length-1);
nextCursor = nextCursor + "%3D";
newUrl = newUrl + 'cursor=' + nextCursor + '&token='+ token;
getResponse(newUrl);
} else {
return resultData;
}
}catch(err){ console.log(err);} } } }

可靠地做到这一点的一种方法是使用 Node Slack SDK 的WebClient,它对游标分页方法(如conversations.list)具有自动分页功能。它还通过对来自 Slack 的响应指示的时间量的请求进行排队来自动处理速率限制。免责声明:我在 Slack 工作并为这个包做出贡献。

该文档介绍了自动分页支持的详细信息:https://slack.dev/node-slack-sdk/web_api#pagination。第一个示例可用于获取频道的完整列表,如果您只是将web.conversations.history()替换为web.conversations.list()

我们不建议再使用此技术,因为您很少需要整个列表。事实上,自动分页将在即将发布的下一个主要版本(v5.0.0)中删除。但是,如果这确实是您想要做的(如您的问题所示),那么您应该查看该部分中的第二个示例。我在下面复制了它:

const { WebClient } = require('@slack/client');
// An access token (from your Slack app or custom integration - xoxp, or xoxb)
const token = process.env.SLACK_TOKEN;
const web = new WebClient(token);
async function getAllChannels(options) {
async function pageLoaded(accumulatedChannels, res) {
// Merge the previous result with the results in the current page
const mergedChannels = accumulatedChannels.concat(res.channels);
// When a `next_cursor` exists, recursively call this function to get the next page.
if (res.response_metadata && res.response_metadata.next_cursor && res.response_metadata.next_cursor !== '') {
// Make a copy of options
const pageOptions = { ...options };
// Add the `cursor` argument
pageOptions.cursor = res.response_metadata.next_cursor;
return pageLoaded(mergedChannels, await web.conversations.list(pageOptions));
}
// Otherwise, we're done and can return the result
return mergedChannels;
}
return pageLoaded([], await web.conversations.list(options));
}
(async () => {
const allChannels = await getAllChannels({ exclude_archived: true, types: 'public_channel' });
console.log(allChannels);
})();

附言。在 v5.0.0 版本中,我们计划包含一个帮助程序方法,使此操作变得更加简单。目前,第二个示例是最向前兼容的方式,我建议您重构它以在 v5.0.0 发布后使用帮助程序。

最新更新