Как получить список поставщиков
Scope:
crmКто может выполнять методы: чтобы пройти сценарий целиком, нужно самое строгое из перечисленных прав — на чтение контактов или компаний в CRM
- crm.item.list — пользователь с правом на чтение элементов объекта CRM
- crm.category.list — любой пользователь
Выберите инструмент для разработки с AI-агентом:
- используйте Битрикс24 Вайбкод, чтобы создать приложение для Битрикс24 по описанию задачи без знания языков программирования. Агент напишет код и разместит приложение на сервере без ручной настройки хостинга
- используйте MCP-сервер, чтобы разрабатывать интеграцию через REST API в своем проекте. Агент будет обращаться к официальной REST-документации
Отдельного объекта «поставщик» в CRM нет. Поставщики — это контакты и компании из системной воронки с особым кодом:
-
CATALOG_CONTRACTOR_CONTACT— для контакта -
CATALOG_CONTRACTOR_COMPANY— для компании
Идентификатор этой воронки на каждом Битрикс24 свой, записать его в код константой нельзя. Поэтому сначала запросим идентификатор по коду воронки, а потом отфильтруем по нему элементы.
В результате сценария получим список поставщиков с их идентификаторами. Эти идентификаторы принимают методы складского учета — например, catalog.documentcontractor.add привязывает поставщика к складскому документу.
Сценарий состоит из двух шагов.
- Получить
idсистемной воронки поставщиков методом crm.category.list - Получить элементы этой воронки методом crm.item.list
Что нужно до начала
-
вебхук создан от имени пользователя с правом читать контакты и компании в CRM
-
в правах вебхука отмечен scope
crm -
в Битрикс24 включен складской учет: системные воронки поставщиков создаются вместе с ним
-
у пользователя вебхука есть доступ к воронке поставщиков. Шаг 1 возвращает только те воронки, которые пользователю разрешено читать, а шаг 2 — только видимые ему элементы
-
путь вебхука дает полный доступ в рамках своего scope. Храните путь в переменной окружения и не публикуйте его в открытом коде
-
вы решили, кого получаете: контактов или компании
|
Что передаем |
Контакт |
Компания |
|
|
|
|
|
Код системной воронки |
|
|
|
Поля названия в |
|
|
Дальше в примерах запрашиваются контакты. Что заменить для компаний, описано в блоке Что важно учитывать.
1. Получим идентификатор воронки поставщиков
Используем метод crm.category.list с параметрами:
-
entityTypeId— идентификатор типа объекта CRM, обязательный параметр. Укажем3— контакт -
filter[code]— фильтр по коду воронки. УкажемCATALOG_CONTRACTOR_CONTACT. Без фильтра метод вернет все воронки контактов, включая общую
Как использовать примеры в документации
import { B24Hook } from '@bitrix24/b24jssdk'
const $b24 = B24Hook.fromWebhookUrl(process.env.B24_HOOK)
// B24_HOOK = 'https://your-domain.bitrix24.ru/rest/USER_ID/TOKEN/'
const result = await $b24.actions.v2.call.make({
method: 'crm.category.list',
params: {
entityTypeId: 3,
filter: {
code: 'CATALOG_CONTRACTOR_CONTACT'
}
}
});
console.log(result.getData().result);
from b24pysdk import BitrixWebhook, Client
client = Client(
BitrixWebhook(
domain="your-domain.bitrix24.com",
webhook_token="user_id/webhook_key",
)
)
# обертка b24pysdk принимает только entity_type_id, поэтому отбираем воронку по коду в ответе
result = client.crm.category.list(
entity_type_id=3, # 3 — контакт
).response.result
categories = [
category
for category in result.get("categories", [])
if category.get("code") == "CATALOG_CONTRACTOR_CONTACT"
]
print(categories)
// composer require bitrix24/b24phpsdk:"^3.0"
require_once 'vendor/autoload.php';
use Bitrix24\SDK\Services\ServiceBuilderFactory;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$logger = new Logger('b24');
$logger->pushHandler(new StreamHandler('php://stdout'));
$serviceBuilder = (new ServiceBuilderFactory(new EventDispatcher(), $logger))
->initFromWebhook('https://your-domain.bitrix24.ru/rest/USER_ID/TOKEN/');
// у crm.category.list нет обертки в SDK — вызываем метод напрямую
$result = $serviceBuilder->core->call(
'crm.category.list',
[
'entityTypeId' => 3, // 3 — контакт
'filter' => [
'code' => 'CATALOG_CONTRACTOR_CONTACT' // Код системной воронки поставщиков
]
]
);
В результате получим идентификатор воронки. В примере id: 15. На вашем Битрикс24 значение будет другим — не переносите 15 в рабочий код, запрашивайте идентификатор этим шагом.
{
"result": {
"categories": [
{
"id": 15,
"name": "Контакты поставщика",
"sort": 500,
"entityTypeId": 3,
"isDefault": "N",
"isSystem": "Y",
"code": "CATALOG_CONTRACTOR_CONTACT"
}
]
},
"total": 1
}
Признак isSystem: Y подтверждает, что воронку создала система, а не пользователь. Сохраним id первого элемента массива categories — на шаге 2 он станет значением фильтра categoryId.
До вызова шага 2 проверьте, что массив categories не пустой. Если передать в фильтр categoryId: null, метод crm.item.list вернет не поставщиков, а контакты из общей воронки.
2. Получим список поставщиков
Отфильтруем элементы методом crm.item.list с параметрами:
-
entityTypeId— идентификатор типа объекта CRM, обязательный параметр. Укажем3— контакт -
filter[categoryId]— идентификатор системной воронки из шага 1. В примере15 -
select— список полей для вывода. Укажемid,name,lastNameиcategoryId. Полный набор полей объекта возвращает метод crm.item.fields с тем жеentityTypeId
const result = await $b24.actions.v2.call.make({
method: 'crm.item.list',
params: {
entityTypeId: 3,
select: ['id', 'name', 'lastName', 'categoryId'],
filter: {
categoryId: 15
}
}
});
console.log(result.getData().result);
result = client.crm.item.list(
entity_type_id=3,
select=["id", "name", "lastName", "categoryId"],
filter={
"categoryId": 15,
},
).response.result
$result = $serviceBuilder->getCRMScope()->item()->list(
3,
[],
[
'categoryId' => 15
],
['id', 'name', 'lastName', 'categoryId']
);
В результате получим список контактов-поставщиков.
{
"result": {
"items": [
{
"id": 2185,
"name": "Сергей",
"lastName": null,
"categoryId": 15
},
{
"id": 2443,
"name": "Иван",
"lastName": "Иванов",
"categoryId": 15
}
]
},
"total": 2
}
Поле lastName может быть пустым: у контакта обязательно только имя. При выводе списка склеивайте name и lastName через пробел и убирайте лишние пробелы.
Проверим результат
Сценарий выполнен, если у каждого элемента массива items поле categoryId совпадает с id воронки из шага 1.
-
поле
totalпоказывает, сколько поставщиков нашлось всего. За один вызов метод возвращает не больше 50 элементов. Еслиtotalбольше 50, в ответе только первая страница — остальные получите повторными вызовами с параметромstart:50,100и так далее -
в интерфейсе тот же список открывается в разделе CRM → Контакты. Переключитесь на воронку с названием из поля
nameшага 1 — по умолчанию это «Контакты поставщика». Количество элементов в ней совпадет сtotal
Если total равен нулю, метод отработал верно, а поставщиков в Битрикс24 нет. Создать поставщика можно по сценарию Как создать поставщика в CRM.
Ошибки и диагностика
Если метод вернул ошибку, проверьте данные запроса.
|
Код |
Причина и действие |
|
|
Передан |
|
|
На шаге 1 передан объект CRM, у которого нет воронок. Поставщики бывают только у контактов и компаний |
|
|
На шаге 2 в |
|
|
Вебхук создан от имени внешнего пользователя. Сценарий доступен только сотрудникам Битрикс24 |
Пустой массив categories на шаге 1 — не ошибка метода. Причин две:
-
в Битрикс24 не включен складской учет, поэтому системных воронок поставщиков нет
-
у пользователя вебхука нет доступа к воронке поставщиков
Чтобы различить причины, выполните шаг 1 вебхуком администратора. Если администратор воронку видит, а исходный вебхук нет, дело в правах его пользователя. Если не видит и администратор, складской учет не включен.
Пустой массив items на шаге 2 при непустом шаге 1 означает, что в воронке нет видимых пользователю элементов. Проверьте, что categoryId взят из ответа шага 1, а не записан в код числом с другого Битрикс24.
Оба метода только читают данные, поэтому после ошибки сценарий можно повторить с любого шага.
Что важно учитывать
-
чтобы получить компании-поставщиков, замените
entityTypeIdна4, код воронки — наCATALOG_CONTRACTOR_COMPANY, а поляnameиlastNameвselect— наtitle. МенятьentityTypeIdи код воронки нужно вместе: сentityTypeId:4код контактов вернет пустой массивcategories -
контакты и компании — разные объекты CRM, одним вызовом их не получить. Чтобы собрать общий список поставщиков, выполните сценарий дважды и объедините результаты в своем коде
-
воронку поставщиков нельзя создать или удалить через REST: crm.category.add запрещает добавление системных воронок, а crm.category.delete отвечает на удаление ошибкой
REMOVING_DISABLED
Пример кода
Код проходит оба шага и выводит список поставщиков. Заменить нужно путь вебхука, а для компаний — значения entityTypeId и кода воронки в первых строках примера.
import { B24Hook } from '@bitrix24/b24jssdk'
const $b24 = B24Hook.fromWebhookUrl(process.env.B24_HOOK)
// B24_HOOK = 'https://your-domain.bitrix24.ru/rest/USER_ID/TOKEN/'
const entityTypeId = 3; // 3 — контакт; для компании укажите 4
const categoryCode = 'CATALOG_CONTRACTOR_CONTACT'; // для компании укажите CATALOG_CONTRACTOR_COMPANY
const resultCategory = await $b24.actions.v2.call.make({
method: 'crm.category.list',
params: {
entityTypeId: entityTypeId,
filter: { code: categoryCode }
}
});
if (!resultCategory.isSuccess) {
console.error(resultCategory.getErrorMessages().join('; '));
} else {
const categories = resultCategory.getData().result.categories || [];
if (!categories.length) {
console.error('Воронка поставщиков не найдена');
} else {
const categoryId = categories[0].id;
const resultItems = await $b24.actions.v2.call.make({
method: 'crm.item.list',
params: {
entityTypeId: entityTypeId,
select: ['id', 'name', 'lastName', 'categoryId'],
filter: { categoryId: categoryId },
order: { id: 'DESC' }
}
});
if (!resultItems.isSuccess) {
console.error(resultItems.getErrorMessages().join('; '));
} else {
console.log(resultItems.getData().result);
}
}
}
from b24pysdk import BitrixWebhook, Client
from b24pysdk.errors import BitrixAPIError
client = Client(
BitrixWebhook(
domain="your-domain.bitrix24.com",
webhook_token="user_id/webhook_key",
)
)
entity_type_id = 3 # 3 — контакт; для компании укажите 4
category_code = (
"CATALOG_CONTRACTOR_CONTACT"
if entity_type_id == 3
else "CATALOG_CONTRACTOR_COMPANY"
)
try:
categories_response = client.crm.category.list(
entity_type_id=entity_type_id,
).response.result.get("categories", [])
categories = [
category
for category in categories_response
if category.get("code") == category_code
]
except BitrixAPIError as error:
print(error)
else:
if not categories:
print("Воронка поставщиков не найдена")
else:
try:
items_result = client.crm.item.list(
entity_type_id=entity_type_id,
select=["id", "name", "lastName", "categoryId"],
filter={"categoryId": categories[0]["id"]},
order={"id": "DESC"},
).response.result
except BitrixAPIError as error:
print(error)
else:
print(items_result)
<?php
// composer require bitrix24/b24phpsdk:"^3.0"
require_once 'vendor/autoload.php';
use Bitrix24\SDK\Services\ServiceBuilderFactory;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$logger = new Logger('b24');
$logger->pushHandler(new StreamHandler('php://stdout'));
$serviceBuilder = (new ServiceBuilderFactory(new EventDispatcher(), $logger))
->initFromWebhook('https://your-domain.bitrix24.ru/rest/USER_ID/TOKEN/');
$entityTypeId = 3; // 3 — контакт; для компании укажите 4
$categoryCode = 'CATALOG_CONTRACTOR_CONTACT'; // для компании укажите CATALOG_CONTRACTOR_COMPANY
try {
$resultCategory = $serviceBuilder->core->call(
'crm.category.list',
[
'entityTypeId' => $entityTypeId,
'filter' => [
'code' => $categoryCode
]
]
);
$categories = $resultCategory->getResponseData()->getResult()['categories'] ?? [];
if (empty($categories)) {
echo 'Воронка поставщиков не найдена';
return;
}
$categoryId = $categories[0]['id'];
$resultItems = $serviceBuilder->getCRMScope()->item()->list(
$entityTypeId,
[
'id' => 'DESC'
],
[
'categoryId' => $categoryId
],
['id', 'name', 'lastName', 'categoryId']
);
print_r($resultItems->getItems());
} catch (\Throwable $e) {
echo $e->getMessage();
}