Как получить все каналы в рабочем пространстве Slack с API для разговора? - PullRequest
1 голос
/ 07 марта 2019

Когда я делаю пагинацию через next_cursor, я получаю разное количество каналов каждый раз, когда нажимаю на URL через функцию NodeJS.

Как только общее количество выбранных каналов равно 7488, в другой раз оно равно 300. Оно отличается каждый раз, когда я запускаю программу.

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

Проблема связана с ограничением скорости провала.Разговор по списку разговоров ограничен уровнем 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);} } } }

1 Ответ

0 голосов
/ 10 марта 2019

Один из способов сделать это надежно - использовать 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);
})();

PS.В версии v5.0.0 мы планируем включить вспомогательный метод, который сделает это намного проще .На данный момент второй пример является наиболее совместимым способом, и я рекомендую реорганизовать его для использования помощника после выпуска v5.0.0.

...