@todo fix me!
v1.0.1
  • Get Started
  • Templates
  • GitHub
  • Overview
  • B24Hook
  • Methods
  • callMethod
  • callFastListMethod
  • fetchListMethod
  • callBatch
  • callBatchByChunk
  • getTargetOrigin
  • getTargetOriginWithPath
  • getLogger
  • setLogger
  • destroy
  • getHttpClient
  • offClientSideWarning
  • Getters
  • auth
  • isInit
  • b24ui
  • b24icons
v1.0.1
  • Docs
  • Frame
  • Hook
  • OAuth
  • Templates

B24Hook.fetchListMethod()

Use B24Hook.fetchListMethod() for step-by-step stream processing of very large data lists. It returns an asynchronous generator that fetches data page by page, allowing processing to begin before the entire list has finished loading and conserving memory. It doesn
B24Hook
TypeB24
The B24Hook object is intended exclusively for use on the server.
  • A webhook contains a secret access key, which MUST NOT be used in client-side code (browser, mobile app).
  • For the client side, use B24Frame.

Quick Overview

To save memory, use fetchListMethod — the method returns an asynchronous generator for iterating through large lists. It doesn't count the total number of records.

The method returns an AsyncGenerator with the response data.

// Basic usage
import { B24Hook } from '@bitrix24/b24jssdk'

const $b24 = B24Hook.fromWebhookUrl('https://ваш_домен.bitrix24.ru/rest/1/webhook_код/')

try {
  for await (const chunk of $b24.fetchListMethod('crm.item.list', {
    entityTypeId: 2, // Entity type ID (e.g., 2 for Company)
    select: ['id', 'title']
  }, 'id', 'items')) {
    $logger.info(`Items received [${chunk.length}]`, { chunk })
  }
} catch (error) {
  $logger.error('some error', { error })
}

Method Signature

fetchListMethod<T = unknown>(
  method: string,
  params: {
    order?: any
    filter?: any
    [key: string]: any
  },
  idKey?: string,
  customKeyForResult?: string | null
): AsyncGenerator<T[]>

Parameters

ParameterTypeRequiredDescription
methodstringYesThe name of the REST API method to call (e.g., crm.item.list).
paramsobjectNoAn object with parameters to pass to the API method. Can contain order, filter, and other valid parameters. Important: Do not pass the start parameter — the method manages it automatically.
idKeystringNoID field name. Specifies the field used for filtering during optimized pagination. Default is 'ID'. Use 'id' (lowercase) if the API method returns IDs in that format.
customKeyForResultstringNoCustom key for data extraction. If the API method returns the result not in the main result field but in a nested one (e.g., result.tasks), specify the key here (e.g., 'tasks'). Default is null (data is taken from the root of result).

Return Value

AsyncGenerator<T[]> — возвращает данные ответа API.

Key Concepts

Optimized pagination without counting

fetchListMethod uses a special optimization for quickly retrieving large data volumes:

  1. Disabling total count: Uses the start: -1 parameter, which disables the calculation of the total number of items, significantly speeding up request execution.
  2. Filtering by ID: After receiving each page of data, the method updates the filter, adding a condition '>ID': lastId to get the next batch of data.
  3. Automatic completion: The process continues until an empty response is received.

Important Limitations

  • Mandatory sorting by ID: The method requires that the sorting order by the ID field be specified in the parameters (e.g., order: { id: 'asc' }). This is necessary for the filtering to work correctly.

Error Handling

In case of an error, the method throws an exception.

try {
  for await (const chunk of $b24.fetchListMethod('some.method', {}, 'id', 'items')) {
    $logger.info(`Items received [${chunk.length}]`, { chunk })
  }
} catch (error) {
  $logger.error('some error', { error })
}

Examples

Getting all companies with filtering

AllCrmItems.ts
import { B24Hook, EnumCrmEntityTypeId, LoggerFactory } from '@bitrix24/b24jssdk'

type Company = {
  id: number
  title: string
}

const devMode = typeof import.meta !== 'undefined' && (globalThis._importMeta_.env?.DEV || false)
const $logger = LoggerFactory.createForBrowser('Example:AllCrmItems', devMode)
const $b24 = B24Hook.fromWebhookUrl('https://your_domain.bitrix24.com/rest/1/webhook_code/')

try {
  for await (const chunk of $b24.fetchListMethod<Company>(
    'crm.item.list',
    {
      entityTypeId: EnumCrmEntityTypeId.company,
      filter: {
        // use some filter by title
        '=%title': 'Prime%'
      },
      select: ['id', 'title']
    },
    'id',
    'items'
  )) {
    $logger.info(`Items received [${chunk.length}]`, { chunk })
  }
} catch (error) {
  $logger.error('some error', { error })
}

Export all deals with the specific stage and the date of stage change.

ExportAllDealsByStage.ts
import type { ISODate } from '@bitrix24/b24jssdk'
import { B24Hook, EnumCrmEntityTypeId, LoggerFactory } from '@bitrix24/b24jssdk'
// import { createWriteStream } from 'node:fs'

type Deal = {
  id: number
  title: string
  opportunity: number
  stageId: string
  createdTime: ISODate
}

const devMode = typeof import.meta !== 'undefined' && (globalThis._importMeta_.env?.DEV || false)
const $logger = LoggerFactory.createForBrowser('Example:ExportAllDealsByStage', devMode)
const $b24 = B24Hook.fromWebhookUrl('https://your_domain.bitrix24.com/rest/1/webhook_code/')

// const outputFile = createWriteStream('deals_export.jsonl', { flags: 'a' })

let totalExported = 0

try {
  const sixMonthAgo = new Date()
  sixMonthAgo.setMonth((new Date()).getMonth() - 6)
  sixMonthAgo.setHours(0, 0, 0)

  for await (const chunk of $b24.fetchListMethod<Deal>(
    'crm.item.list',
    {
      entityTypeId: EnumCrmEntityTypeId.company,
      filter: {
        '>createdTime': sixMonthAgo.toISOString(), // Created at least 6 months ago
        '=stageId': 'WON' // Only winning deals
      },
      select: ['id', 'title', 'stageId', 'opportunity', 'createdTime']
    },
    'id',
    'items'
  )) {
    // Write each transaction to the file line by line
    for (const deal of chunk) {
      // outputFile.write(JSON.stringify(deal) + '\n')
    }

    totalExported += chunk.length
    $logger.debug(`Exported deals: ${totalExported}`)
  }

  $logger.info(`Export complete`, {
    total: totalExported
  })
} catch (error) {
  $logger.error('some error', { error })
} finally {
  // outputFile.end()
}

Task processing

ProcessAllTasks.ts
import type { NumberString, ISODate } from '@bitrix24/b24jssdk'
import { B24Hook, LoggerFactory } from '@bitrix24/b24jssdk'

type Task = {
  id: NumberString
  title: string
  responsibleId: NumberString
  deadline: null | ISODate
}

const devMode = typeof import.meta !== 'undefined' && (globalThis._importMeta_.env?.DEV || false)
const $logger = LoggerFactory.createForBrowser('Example:ProcessAllTasks', devMode)
const $b24 = B24Hook.fromWebhookUrl('https://your_domain.bitrix24.com/rest/1/webhook_code/')

const overdueTasks: any[] = []
const today = new Date()

try {
  for await (const chunk of $b24.fetchListMethod<Task>(
    'tasks.task.list',
    {
      filter: {
        REAL_STATUS: [2, 3] // Tasks in progress and pending execution
      },
      select: ['ID', 'TITLE', 'DEADLINE', 'RESPONSIBLE_ID']
    },
    'ID',
    'tasks' // The key under which the tasks are located in the response
  )) {
    // Filter overdue tasks
    const overdueInChunk = chunk.filter((task) => {
      if (!task.deadline) {
        return false
      }
      const deadline = new Date(task.deadline)
      return deadline < today
    })

    overdueTasks.push(...overdueInChunk)

    $logger.info('stat', {
      processed: chunk.length,
      expired: overdueInChunk.length
    })

    // You can perform intermediate actions on the overdue tasks found
    if (overdueInChunk.length > 0) {
      // For example, send notifications or update status
      await processOverdueTasks(overdueInChunk)
    }
  }

  $logger.info(`Total number of overdue tasks found: ${overdueTasks.length}`)
} catch (error) {
  $logger.error('some error', { error })
}

async function processOverdueTasks(overdue: Task[]) {
  // some process
  $logger.info('Process overdue', { overdue })
}

Alternatives and Recommendations

  • For batch operations: Use callBatch to execute up to 50 commands in a single request.
  • When you need the total item count: Use the regular callMethod with manual pagination.
  • To get the entire list in memory: Use callFastListMethod, which returns the entire array of data.
  • On the client (browser): Use the built-in B24Frame object instead of B24Hook.

References

  • Official Bitrix24 REST API Documentation — Reference for all available methods.
  • Working with Large Volumes of Data — Recommendations for optimizing code to retrieve large data.

callFastListMethod

Use `B24Hook.callFastListMethod()` to quickly fetch all list items from the Bitrix24 REST API. The method automatically performs all necessary requests to retrieve the complete dataset using an optimized approach that does not count the total number of items, significantly speeding up the process when working with large data volumes. Works only in server environment.

callBatch

Use B24Hook.callBatch() to execute batch requests to the Bitrix24 REST API. This allows you to execute up to 50 different commands in a single HTTP request, significantly increasing performance for bulk data operations. Works only in server environment.

On this page

  • Quick Overview
  • Method Signature
    • Parameters
    • Return Value
  • Key Concepts
    • Important Limitations
    • Error Handling
  • Examples
    • Getting all companies with filtering
    • Export all deals with the specific stage and the date of stage change.
    • Task processing
  • Alternatives and Recommendations
  • References
Releases
Published under MIT License.

Copyright © 2024-present Bitrix24