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

Swa*_*thi 1 node.js slack-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}
Run Code Online (Sandbox Code Playgroud)

该问题是由于松弛的速率限制造成的。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);} } } }
Run Code Online (Sandbox Code Playgroud)

Ank*_*kur 6

可靠地做到这一点的一种方法是使用Node Slack SDKWebClient它可以对光标分页方法(如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);
})();
Run Code Online (Sandbox Code Playgroud)

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