Мы всё ещё дорабатываем эту страницу. Некоторых данных здесь может не хватать — скоро дополним.
Цель
Выгрузить из портала Bitrix24 каждую сделку CRM, закрытую за период, и записать её в CSV-файл. Память не растёт независимо от числа подходящих сделок — FetchListV2.make() стримит страницы по 50 записей.
Стек и предпосылки
- Node.js 20+, ESM (
"type": "module"вpackage.json) @bitrix24/b24jssdk@^1.0.0- URL входящего вебхука Bitrix24 со scope
crm. Задайте его какB24_HOOKв окружении.
pnpm add @bitrix24/b24jssdk
export B24_HOOK="https://your-portal.bitrix24.com/rest/1/xxxxxxxxxxxxxxxx/"
Полный пример
scripts/deals-to-csv.mjs:
import { writeFile } from 'node:fs/promises'
import {
B24Hook,
EnumCrmEntityTypeId,
ParamsFactory,
Text
} from '@bitrix24/b24jssdk'
const hookUrl = process.env.B24_HOOK
if (!hookUrl) {
console.error('B24_HOOK is not set')
process.exit(1)
}
// Закрытые в предыдущем календарном месяце.
const now = new Date()
const from = new Date(now.getFullYear(), now.getMonth() - 1, 1)
const to = new Date(now.getFullYear(), now.getMonth(), 1)
const b24 = B24Hook.fromWebhookUrl(hookUrl, {
// Меньше нагрузка в секунду, чем у `getDefault()` — хорошо для отчётных задач,
// работающих рядом с живым пользовательским трафиком на том же портале.
restrictionParams: ParamsFactory.getBatchProcessing()
})
const generator = b24.actions.v2.fetchList.make({
method: 'crm.item.list',
params: {
entityTypeId: EnumCrmEntityTypeId.deal,
filter: {
'>=closedAt': Text.toB24Format(from),
'<closedAt': Text.toB24Format(to),
stageSemanticId: 'S' // закрыта-выиграна
},
select: ['id', 'title', 'opportunity', 'currencyId', 'closedAt', 'assignedById']
},
idKey: 'id',
customKeyForResult: 'items',
requestId: 'deals-to-csv'
})
const rows = ['id;title;amount;currency;closedAt;assignedById']
let count = 0
for await (const chunk of generator) {
for (const deal of chunk) {
rows.push([
deal.id,
JSON.stringify(deal.title ?? ''),
deal.opportunity ?? '',
deal.currencyId ?? '',
deal.closedAt ?? '',
deal.assignedById ?? ''
].join(';'))
}
count += chunk.length
process.stderr.write(`fetched: ${count}\r`)
}
const file = `deals-${from.toISOString().slice(0, 7)}.csv`
await writeFile(file, rows.join('\n'), 'utf8')
console.log(`\nwrote ${count} rows to ${file}`)
Запуск
node scripts/deals-to-csv.mjs
# fetched: 4350
# wrote 4350 rows to deals-2026-04.csv
Как это работает
B24Hook.fromWebhookUrl()разбирает URL вебхука и даёт готовый экземплярTypeB24— инициализация черезawaitне нужна.ParamsFactory.getBatchProcessing()меняет профиль rate limit по умолчанию на настроенный для долгих сканов, чтобы скрипт не конкурировал с живыми UI-запросами за очередь портала.actions.v2.fetchList.make()возвращаетAsyncGenerator<T[]>. Каждая итерацияfor awaitотдаёт доlimitзаписей (по умолчанию50) и использует курсорную пагинацию поidKeyпо возрастанию — SDK сам сшивает страницы.Text.toB24Format(date)преобразует JS-Dateв ISO-формат, который Bitrix24 ожидает в фильтрахcrm.item.list; передача сырогоDateне сработает.
Ограничения
crm.item.listвозвращает до 50 записей на страницу; это серверный лимит, а не настройка SDK.- Генератор не поддерживает пользовательский параметр
order— курсорная пагинация требует сортировки поidKeyпо возрастанию. Указаниеorderвparamsвызывает runtime-предупреждение и отбрасывается. idKeyпо умолчанию'ID'(в верхнем регистре) для v2-endpoint-ов. Методы CRM item возвращаютid(в нижнем регистре), поэтому переопределяйте его явно, как в примере.- Один экземпляр
B24Hookсоответствует одному пользователю портала. Если нужные сделки принадлежат другому пользователю, вебхук должен быть создан этим пользователем (или аккаунтом с межпользовательским доступом). - Для очень больших периодов, исчерпывающих дневной бюджет вызовов, разбейте диапазон дат на меньшие части и запускайте их последовательно.
См. также
FetchListV2.make()— полный справочник метода.- Установка Node.js +
B24Hook— аутентификация по вебхуку для серверных скриптов вроде этого. - Система ограничений — выбор пресета
restrictionParams.
Аналитика CRM
Стримит все сделки через actions.v2.fetchList.make, группирует по стадиям, печатает отчёт по воронке (количество, конверсия %, средний чек, win rate).
Обработка ошибок
Демонстрирует четыре слоя ошибок (SdkError / AjaxError / сетевые / soft) и настройки hardErrorCodes / softErrorCodes / retryOnNetworkError у менеджера ограничений.