Блог Горошко Андрея Bitrix24,PHP Создать пользовательское поле для контактов crm.contact.userfield.add

Создать пользовательское поле для контактов crm.contact.userfield.add

Каждый PHP-разработчик, работающий с экосистемой Bitrix Framework, должен глубоко понимать работу её ключевых компонентов. В этой статье мы проведем подробный аудит темы «Создать пользовательское поле для контактов crm.contact.userfield.add», проанализируем лучшие практики и покажем, как правильно использовать crm.contact.userfield.add в реальных задачах.

Создать пользовательское поле для контактов crm.contact.userfield.add

> Scope: crm
>
> Кто может выполнять метод: администратор

Метод crm.contact.userfield.add создает новое пользовательское поле для контактов.

Параметры метода

Название
тип
Описание
fields
[object][1]
Объект формата:

{
    field_1: value_1,
    field_2: value_2,
    ...,
    field_n: value_n,
}

где:
— field_n — название поля
— value_n — значение поля

Список доступных полей описан ниже.

Некорректное поле в fields будет проигнорировано

Параметр fields {#parameter-fields}

Название
тип
Описание
USER_TYPE_ID
[string][1]
Тип данных пользовательского поля. Возможные значения:
— string — строка
— integer — целое число
— double — число
— boolean — да/нет
— datetime — дата/время
— date — дата
— money — деньги
— url — ссылка
— address — адрес
— enumeration — список
— file — файл
— employee — привязка к сотруднику
— crm_status — привязка к справочнику CRM
— iblock_section — привязка к разделам инф. блоков
— iblock_element — привязка к элементам инф. блоков
— crm — привязка к элементам CRM
— пользовательские типы полей
FIELD_NAME*
[string][1]
Код поля. Уникальное.

Системное ограничение на код поля составляет 20 знаков. К названию пользовательского поля всегда добавляется префикс UF_CRM_, то есть реальная длина названия 13 знаков.

Допустимые символы: A-Z, 0-9 и _

LABEL
[string][1]
Название пользовательского поля по умолчанию.

Переданное значение будет выставлено в следующие поля: LIST_FILTER_LABEL, LIST_COLUMN_LABEL, EDIT_FORM_LABEL, ERROR_MESSAGE, HELP_MESSAGE, если в них не передано значение

XML_ID
[string][1]
Внешний код
LIST_FILTER_LABEL
[string][1]\
lang_mapПодпись фильтра в списке.

При передаче строки она будет проставлена для всех идентификаторов языка.

При передаче значения типа lang_map для всех непереданных языков будет проставлено значение из LABEL.

По умолчанию значение, переданное в LABEL, проставляется для всех идентификаторов языка

LIST_COLUMN_LABEL
[string][1]\
lang_mapЗаголовок в списке.

При передаче строки она будет проставлена для всех идентификаторов языка.

При передаче значения типа lang_map для всех непереданных языков будет проставлено значение из LABEL.

По умолчанию значение, переданное в LABEL, проставляется для всех идентификаторов языка

EDIT_FORM_LABEL
[string][1]\
lang_mapПодпись в форме редактирования.

При передаче строки она будет проставлена для всех идентификаторов языка.

При передаче значения типа lang_map для всех непереданных языков будет проставлено значение из LABEL.

По умолчанию значение, переданное в LABEL, проставляется для всех идентификаторов языка

ERROR_MESSAGE
[string][1]\
lang_mapСообщение об ошибке.

При передаче строки она будет проставлена для всех идентификаторов языка.

При передаче значения типа lang_map для всех непереданных языков будет проставлено значение из LABEL.

По умолчанию значение, переданное в LABEL, проставляется для всех идентификаторов языка

HELP_MESSAGE
[string][1]\
lang_mapПомощь.

При передаче строки она будет проставлена для всех идентификаторов языка.

При передаче значения типа lang_map для всех непереданных языков будет проставлено значение из LABEL.

По умолчанию значение, переданное в LABEL, проставляется для всех идентификаторов языка

MULTIPLE
[boolean][1]
Является ли поле множественным. Возможные значения:
— Y — да
— N — нет

Поля типа boolean не могут быть множественными.

По умолчанию N

MANDATORY
[boolean][1]
Является ли поле обязательным. Возможные значения:
— Y — да
— N — нет

По умолчанию N

SHOW_FILTER
[boolean][1]
Показывать ли поле в фильтре. Возможные значения:
— Y — да
— N — нет

По умолчанию N

SETTINGS
[object][1]
Дополнительные параметры поля. Для каждого типа поля (USER_TYPE_ID) существует свой пул доступных настроек, они описаны ниже
LIST
uf_enum_element[]
Список возможных значений для пользовательского поля типа enumeration. Для пользовательских полей другого типа данный параметр не несет смысла.

По умолчанию []

SORT
[integer][1]
Индекс сортировки. Обязательно больше нуля.

По умолчанию 100

SHOW_IN_LIST
[boolean][1]
Показывать ли пользовательское поле в списке.

Данный параметр ни на что не влияет в рамках crm.

Возможные значения:
— Y — да
— N — нет

По умолчанию N

EDIT_IN_LIST
[boolean][1]
Разрешать ли редактирование пользователем. Возможные значения:
— Y — да
— N — нет

По умолчанию Y

IS_SEARCHABLE
[boolean][1]
Участвуют ли значения поля в поиске.

Данный параметр ни на что не влияет в рамках crm.

Возможные значения:
— Y — да
— N — нет

По умолчанию N

Параметр SETTINGS {#settings}

У каждого типа пользовательских полей существует свой набор дополнительных настроек. Данный метод поддерживает лишь те, что описаны ниже.

  • string
Название
тип
Описание
DEFAULT_VALUE
[string][1]
Значение по умолчанию.

По умолчанию ''

ROWS
[integer][1]
Количество строк в поле ввода. Обязательно больше 0.

По умолчанию 1

  • integer
Название
тип
Описание
DEFAULT_VALUE
[integer][1]
Значение по умолчанию
  • double
Название
тип
Описание
DEFAULT_VALUE
[double][1]
Значение по умолчанию
PRECISION
[integer][1]
Точность числа. Обязательно больше или равно 0.

По умолчанию 2

  • boolean
Название
тип
Описание
DEFAULT_VALUE
[integer][1]
Значение по умолчанию, где 1 — да, 0 — нет.

Возможные значения:
— >= 1 -> 1
— <= 0 -> 0

По умолчанию 0

DISPLAY
[string][1]
Внешний вид. Возможные значения:
— CHECKBOX — флажок
— RADIO — радиокнопки
— DROPDOWN — выпадающий список

По умолчанию CHECKBOX

  • date|datetime
Название
тип
Описание
DEFAULT_VALUE
[object][1]
Значение по умолчанию.

Объект формата:

    {
        VALUE: datetime|date,
        TYPE: 'NONE'|'NOW'|'FIXED',
    }

где:
— VALUE — значение по умолчанию типа datetime или date
— TYPE — тип значения по умолчанию:
— NONE — не выставлять значение по умолчанию
— NOW — использовать текущее время/дату
— FIXED — использовать время/дату из VALUE

Значение по умолчанию:

    {
        VALUE: '',
        TYPE: 'NONE',
    }
  • enumeration
Название
тип
Описание
DISPLAY
[string][1]
Внешний вид. Возможные значения:
— LIST — список
— UI — набираемый список
— CHECKBOX — флажки
— DIALOG — диалог выбора сущностей

По умолчанию LIST

LIST_HEIGHTВысота списка. Обязательно больше 0.

Доступен только при DISPLAY = LIST или DISPLAY = UI.

По умолчанию 1

  • iblock_section|iblock_element
Название
тип
Описание
IBLOCK_TYPE_ID
[string][1]
Идентификатор типа инфоблока.

По умолчанию ''

IBLOCK_ID
[string][1]
Идентификатор инфоблока.

По умолчанию 0

DEFAULT_VALUE
[string][1]
Значение по умолчанию.

По умолчанию ''

DISPLAY
[string][1]
Внешний вид. Возможные значения:
— DIALOG — диалог
— UI — набираемый список
— LIST — список
— CHECKBOX — флажки

По умолчанию LIST

LIST_HEIGHT
[integer][1]
Высота списка. Обязательно больше 0.

По умолчанию 1

ACTIVE_FILTER
[boolean][1]
Показывать ли элементы с включенным флагом активности. Возможные значения:
— Y — да
— N — нет

По умолчанию N

  • crm_status
Название
тип
Описание
ENTITY_TYPE
[string][1]
Идентификатор типа справочника.

Используйте crm.status.entity.types, чтобы узнать возможные значения.

По умолчанию ''

  • crm

Если не передать ни одну из следующих опций, то по умолчанию будет включена привязка к лидам (LEAD = Y).

Название
тип
Описание
LEAD
[boolean][1]
Включена ли привязка к Лидам. Возможные значения:
— Y — да
— N — нет

По умолчанию N

CONTACT
[boolean][1]
Включена ли привязка к Контактам. Возможные значения:
— Y — да
— N — нет

По умолчанию N

COMPANY
[boolean][1]
Включена ли привязка к Компаниям. Возможные значения:
— Y — да
— N — нет

По умолчанию N

DEAL
[boolean][1]
Включена ли привязка к Сделкам. Возможные значения:
— Y — да
— N — нет

По умолчанию N

Тип uf_enum_element {#uf_enum_element}

Название
тип
Описание
VALUE
[string][1]
Значение элемента списка.

Элементы списка с пустым или отсутствующим VALUE будут проигнорированы

SORT
[integer][1]
Индекс сортировки. Обязательно больше или равно 0.

По умолчанию 0

DEF
[boolean][1]
Является ли элемент списка значением по умолчанию. Возможные значения:
— Y — да
— N — нет

Для множественного поля допустимо несколько DEF = Y. Для не множественного значением по умолчанию будет считаться первый переданный элемент списка с DEF = Y.

По умолчанию N

XML_ID
[string][1]
Внешний код значения. Обязательно уникальный в рамках элементов списка пользовательского поля

Примеры кода

Пример создания пользовательского поля типа Строка

  • cURL (Webhook)
    curl -X POST \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"fields":{"LABEL":"Поле \'Привет, мир!\'","USER_TYPE_ID":"string","FIELD_NAME":"HELLO_WORLD","MULTIPLE":"Y","MANDATORY":"Y","SHOW_FILTER":"Y","SETTINGS":{"DEFAULT_VALUE":"Привет, мир! Значение по умолчанию","ROWS":3},"SORT":1000,"EDIT_IN_LIST":"Y","LIST_FILTER_LABEL":"Привет, мир! Фильтр","LIST_COLUMN_LABEL":{"en":"Hello, World! Column","ru":"Привет, мир! Колонка","de":"Hallo, Welt! Spalte"},"EDIT_FORM_LABEL":{"en":"Hello, World! Edit","ru":"Привет, мир! Редактировать","de":"Hallo, Welt! Bearbeiten"},"ERROR_MESSAGE":{"en":"Hello, World! Error","ru":"Привет, мир! Ошибка","de":"Hallo, Welt! Fehler"},"HELP_MESSAGE":{"en":"Hello, World! Help","ru":"Привет, мир! Помощь","de":"Hallo, Welt! Hilfe"}}}' \
    https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webbhook_here**/crm.contact.userfield.add
  • cURL (OAuth)
    curl -X POST \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"fields":{"LABEL":"Поле \'Привет, мир!\'","USER_TYPE_ID":"string","FIELD_NAME":"HELLO_WORLD","MULTIPLE":"Y","MANDATORY":"Y","SHOW_FILTER":"Y","SETTINGS":{"DEFAULT_VALUE":"Привет, мир! Значение по умолчанию","ROWS":3},"SORT":1000,"EDIT_IN_LIST":"Y","LIST_FILTER_LABEL":"Привет, мир! Фильтр","LIST_COLUMN_LABEL":{"en":"Hello, World! Column","ru":"Привет, мир! Колонка","de":"Hallo, Welt! Spalte"},"EDIT_FORM_LABEL":{"en":"Hello, World! Edit","ru":"Привет, мир! Редактировать","de":"Hallo, Welt! Bearbeiten"},"ERROR_MESSAGE":{"en":"Hello, World! Error","ru":"Привет, мир! Ошибка","de":"Hallo, Welt! Fehler"},"HELP_MESSAGE":{"en":"Hello, World! Help","ru":"Привет, мир! Помощь","de":"Hallo, Welt! Hilfe"}},"auth":"**put_access_token_here**"}' \
    https://**put_your_bitrix24_address**/rest/crm.contact.userfield.add
  • JS
    BX24.callMethod(
        'crm.contact.userfield.add',
        {
            fields: {
                LABEL: "Поле \'Привет, мир!\'",
                USER_TYPE_ID: "string",
                FIELD_NAME: "HELLO_WORLD",
                MULTIPLE: "Y",
                MANDATORY: "Y",
                SHOW_FILTER: "Y",
                SETTINGS: {
                    DEFAULT_VALUE: "Привет, мир! Значение по умолчанию",
                    ROWS: 3,
                },
                SORT: 1000,
                EDIT_IN_LIST: "Y",
                LIST_FILTER_LABEL: "Привет, мир! Фильтр",
                LIST_COLUMN_LABEL: {
                    "en": "Hello, World! Column",
                    "ru": "Привет, мир! Колонка",
                    "de": "Hallo, Welt! Spalte"
                },
                EDIT_FORM_LABEL: {
                    "en": "Hello, World! Edit",
                    "ru": "Привет, мир! Редактировать",
                    "de": "Hallo, Welt! Bearbeiten"
                },
                ERROR_MESSAGE: {
                    "en": "Hello, World! Error",
                    "ru": "Привет, мир! Ошибка",
                    "de": "Hallo, Welt! Fehler"
                },
                HELP_MESSAGE: {
                    "en": "Hello, World! Help",
                    "ru": "Привет, мир! Помощь",
                    "de": "Hallo, Welt! Hilfe"
                },
            },
        },
        (result) => {
            result.error()
                ? console.error(result.error())
                : console.info(result.data())
            ;
        },
    );
  • PHP
    require_once('crest.php');

    $result = CRest::call(
        'crm.contact.userfield.add',
        [
            'fields' => [
                'LABEL' => "Поле 'Привет, мир!'",
                'USER_TYPE_ID' => "string",
                'FIELD_NAME' => "HELLO_WORLD",
                'MULTIPLE' => "Y",
                'MANDATORY' => "Y",
                'SHOW_FILTER' => "Y",
                'SETTINGS' => [
                    'DEFAULT_VALUE' => "Привет, мир! Значение по умолчанию",
                    'ROWS' => 3,
                ],
                'SORT' => 1000,
                'EDIT_IN_LIST' => "Y",
                'LIST_FILTER_LABEL' => "Привет, мир! Фильтр",
                'LIST_COLUMN_LABEL' => [
                    'en' => "Hello, World! Column",
                    'ru' => "Привет, мир! Колонка",
                    'de' => "Hallo, Welt! Spalte"
                ],
                'EDIT_FORM_LABEL' => [
                    'en' => "Hello, World! Edit",
                    'ru' => "Привет, мир! Редактировать",
                    'de' => "Hallo, Welt! Bearbeiten"
                ],
                'ERROR_MESSAGE' => [
                    'en' => "Hello, World! Error",
                    'ru' => "Привет, мир! Ошибка",
                    'de' => "Hallo, Welt! Fehler"
                ],
                'HELP_MESSAGE' => [
                    'en' => "Hello, World! Help",
                    'ru' => "Привет, мир! Помощь",
                    'de' => "Hallo, Welt! Hilfe"
                ],
            ]
        ]
    );

    echo '<PRE>';
    print_r($result);
    echo '</PRE>';
  • PHP (B24PhpSdk)
    try {
        $userfieldItemFields = [
            'FIELD_NAME' => 'UF_CRM_example',
            'USER_TYPE_ID' => 'string',
            'XML_ID' => 'xml_example',
            'SORT' => '100',
            'MULTIPLE' => 'N',
            'MANDATORY' => 'Y',
            'SHOW_FILTER' => 'Y',
            'SHOW_IN_LIST' => 'Y',
            'EDIT_IN_LIST' => 'Y',
            'IS_SEARCHABLE' => 'Y',
            'EDIT_FORM_LABEL' => 'Example Field',
            'LIST_COLUMN_LABEL' => 'Example Column',
            'LIST_FILTER_LABEL' => 'Example Filter',
            'ERROR_MESSAGE' => 'Error occurred',
            'HELP_MESSAGE' => 'Help message',
            'LIST' => 'list_value',
            'SETTINGS' => 'settings_value',
        ];

        $result = $serviceBuilder
            ->getCRMScope()
            ->contactUserfield()
            ->add($userfieldItemFields);

        print($result->getId());
    } catch (Throwable $e) {
        print('Error: ' . $e->getMessage());
    }

Пример создания пользовательского поля типа Список

  • cURL (Webhook)
    curl -X POST \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"fields":{"LABEL":"Пользовательское поле (список)","USER_TYPE_ID":"enumeration","FIELD_NAME":"ENUMERATION_EXAMPLE","MULTIPLE":"N","MANDATORY":"N","SHOW_FILTER":"Y","LIST":[{"VALUE":"Элемент списка #1","DEF":"Y","XML_ID":"XML_ID_1","SORT":100},{"VALUE":"Элемент списка #2","XML_ID":"XML_ID_2","SORT":200},{"VALUE":"Элемент списка #3","XML_ID":"XML_ID_3","SORT":300},{"VALUE":"Элемент списка #4","XML_ID":"XML_ID_4","SORT":400}],"SETTINGS":{"DISPLAY":"UI","LIST_HEIGHT":2},"SORT":2000}}' \
    https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webbhook_here**/crm.contact.userfield.add
  • cURL (OAuth)
    curl -X POST \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"fields":{"LABEL":"Пользовательское поле (список)","USER_TYPE_ID":"enumeration","FIELD_NAME":"ENUMERATION_EXAMPLE","MULTIPLE":"N","MANDATORY":"N","SHOW_FILTER":"Y","LIST":[{"VALUE":"Элемент списка #1","DEF":"Y","XML_ID":"XML_ID_1","SORT":100},{"VALUE":"Элемент списка #2","XML_ID":"XML_ID_2","SORT":200},{"VALUE":"Элемент списка #3","XML_ID":"XML_ID_3","SORT":300},{"VALUE":"Элемент списка #4","XML_ID":"XML_ID_4","SORT":400}],"SETTINGS":{"DISPLAY":"UI","LIST_HEIGHT":2},"SORT":2000},"auth":"**put_access_token_here**"}' \
    https://**put_your_bitrix24_address**/rest/crm.contact.userfield.add
  • JS
    BX24.callMethod(
        'crm.contact.userfield.add',
        {
            fields: {
                LABEL: "Пользовательское поле (список)",
                USER_TYPE_ID: "enumeration",
                FIELD_NAME: "ENUMERATION_EXAMPLE",
                MULTIPLE: "N",
                MANDATORY: "N",
                SHOW_FILTER: "Y",
                LIST: [
                    {
                        VALUE: "Элемент списка #1",
                        DEF: "Y",
                        XML_ID: "XML_ID_1",
                        SORT: 100,
                    },
                    {
                        VALUE: "Элемент списка #2",
                        XML_ID: "XML_ID_2",
                        SORT: 200,
                    },
                    {
                        VALUE: "Элемент списка #3",
                        XML_ID: "XML_ID_3",
                        SORT: 300,
                    },
                    {
                        VALUE: "Элемент списка #4",
                        XML_ID: "XML_ID_4",
                        SORT: 400,
                    },
                ],
                SETTINGS: {
                    DISPLAY: "UI",
                    LIST_HEIGHT: 2,
                },
                SORT: 2000,
            },
        },
        (result) => {
            result.error()
                ? console.error(result.error())
                : console.info(result.data())
            ;
        },
    );
  • PHP
    require_once('crest.php');

    $result = CRest::call(
        'crm.contact.userfield.add',
        [
            'fields' => [
                'LABEL' => "Пользовательское поле (список)",
                'USER_TYPE_ID' => "enumeration",
                'FIELD_NAME' => "ENUMERATION_EXAMPLE",
                'MULTIPLE' => "N",
                'MANDATORY' => "N",
                'SHOW_FILTER' => "Y",
                'LIST' => [
                    [
                        'VALUE' => "Элемент списка #1",
                        'DEF' => "Y",
                        'XML_ID' => "XML_ID_1",
                        'SORT' => 100,
                    ],
                    [
                        'VALUE' => "Элемент списка #2",
                        'XML_ID' => "XML_ID_2",
                        'SORT' => 200,
                    ],
                    [
                        'VALUE' => "Элемент списка #3",
                        'XML_ID' => "XML_ID_3",
                        'SORT' => 300,
                    ],
                    [
                        'VALUE' => "Элемент списка #4",
                        'XML_ID' => "XML_ID_4",
                        'SORT' => 400,
                    ],
                ],
                'SETTINGS' => [
                    'DISPLAY' => "UI",
                    'LIST_HEIGHT' => 2,
                ],
                'SORT' => 2000,
            ]
        ]
    );

    echo '<PRE>';
    print_r($result);
    echo '</PRE>';

Обработка ответа

HTTP-статус: 200

{
    "result": 399,
    "time": {
        "start": 1724239307.903115,
        "finish": 1724239308.567422,
        "duration": 0.6643068790435791,
        "processing": 0.20090818405151367,
        "date_start": "2024-08-21T13:21:47+02:00",
        "date_finish": "2024-08-21T13:21:48+02:00",
        "operating": 0
    }
}

Возвращаемые данные

Название
тип
Описание
result
[integer][1]
Корневой элемент ответа, содержит идентификатор созданного пользовательского поля
time
time
Информация о времени выполнения запроса

Обработка ошибок

HTTP-статус: 400

Данный метод может отдавать ошибки не сразу, а собирая несколько и соединяя их между собой строкой: \n.

{
    "error": "",
    "error_description": "The 'USER_TYPE_ID' field is not found."
}

Возможные коды ошибок

ОписаниеЗначение
Access deniedУ пользователя нет административных прав
The 'FIELD_NAME' field is not foundЛибо передан пустой FIELD_NAME, либо он не передан вовсе
Имя поля слишком длинное (больше 50-ти символов)Переданный FIELD_NAME содержит более 50 символов
Имя поля содержит недопустимые символы. Допустимыми являются: A-Z, 0-9 и _Переданный FIELD_NAME содержит недопустимые символы
The 'USER_TYPE_ID' field is not foundЛибо передан пустой USER_TYPE_ID, либо он не передан вовсе
Указан неверный пользовательский типПереданный USER_TYPE_ID не существует
Элемент списка со значением XML_ID=XML_ID уже существуетПереданные в элементы списка XML_ID не уникальны
  • [](./crm-contact-userfield-update)
  • [](./crm-contact-userfield-get)
  • [](./crm-contact-userfield-list)
  • [](./crm-contact-userfield-delete)

[1]: ../../../data-types.md

💡 Экспертное мнение и рекомендации

Советы эксперта по интеграции:

  • Всегда используйте кэширование при частых запросах к crm.contact.userfield.add, чтобы разгрузить базу данных.
  • Соблюдайте стандарты PSR при написании обработчиков для «Создать пользовательское поле для контактов crm.contact.userfield.add».
  • Регулярно проводите аудит производительности системы с помощью встроенного монитора 1С-Битрикс.

Похожая задача в бизнесе?

Помогу автоматизировать процессы и внедрить ИИ

Меня зовут Андрей Горошко. Я Full-stack разработчик и эксперт по 1С-Битрикс. Настраиваю CRM Битрикс24, разрабатываю защищенные API и создаю умных ИИ-агентов для автоматизации рутины.

Related Post

Удалить обработчик кассы sale.cashbox.handler.deleteУдалить обработчик кассы sale.cashbox.handler.delete

Оптимизация производительности и безопасности — залог успешного проекта на 1С-Битрикс. Данный материал посвящен практическому применению «Удалить обработчик кассы sale.cashbox.handler.delete». Мы подготовили подробный разбор принципов работы и развернутые примеры интеграции. Удалить

Отменить проведение документа catalog.document.unconfirmОтменить проведение документа catalog.document.unconfirm

Каждый PHP-разработчик, работающий с экосистемой Bitrix Framework, должен глубоко понимать работу её ключевых компонентов. В этой статье мы проведем подробный аудит темы «Отменить проведение документа catalog.document.unconfirm», проанализируем лучшие практики и

Файл манифестаФайл манифеста

Эффективная интеграция и кастомизация функционала в Битрикс24 часто требует работы на уровне API. Сегодня мы подробно рассмотрим «Файл манифеста». Вы узнаете экспертные методики работы с битрикс и научитесь избегать типичных