Работа с файлами в полях CRM
Сложность: medium | Скоупы: crm | Стек: cURL / Node.js / PHP
Что делаем
Читаем, скачиваем и записываем файлы в пользовательских полях типа «Файл» у сущностей CRM, которые работают через crm.item.*.
Два типа файловых полей
В Битрикс24 есть два разных типа файловых полей, и работают они по-разному.
- «Файл» — поле не связано с Диском. Содержимое хранится в самом поле. Эта страница про него.
- «Файл (диск)» — поле ссылается на объект Диска. С такими файлами работают через эндпоинты
/v1/files/*, см. Работа с файлами Диска.
Тип поля виден в ответе GET /v1/{entity}/fields.
Где применимо
Механика одинакова для всех сущностей CRM на crm.item.*.
- Сделки —
GET / PATCH /v1/deals/:id - Лиды —
GET / PATCH /v1/leads/:id - Контакты —
GET / PATCH /v1/contacts/:id - Компании —
GET / PATCH /v1/companies/:id - Предложения —
GET / PATCH /v1/quotes/:id - Счета —
GET / PATCH /v1/invoices/:id - Смарт-процессы —
GET / PATCH /v1/items/:entityTypeId/:id
Имя поля
Имя файлового поля имеет вид ufCrm_<код>. Точное имя и признак множественности возвращает GET /v1/{entity}/fields.
Как поле выглядит в ответе
GET /v1/deals/:id возвращает файловое поле массивом объектов.
{
"ufCrm_1a2b3c": [
{
"id": 35845,
"url": "https://portal.bitrix24.ru/bitrix/services/main/ajax.php?action=crm.controller.item.getFile&entityTypeId=2&id=100&fieldName=UF_CRM_1A2B3C&fileId=35845",
"urlMachine": "https://portal.bitrix24.ru/rest/1/WEBHOOK/crm.controller.item.getFile/?token=..."
}
]
}
В каждом объекте два адреса для разных задач.
url— для открытия в браузере. Требует активной сессии пользователя.urlMachine— для программного скачивания. Авторизация включена в сам адрес.
Скачать файл
Возьмите urlMachine из ответа и выполните по нему GET. В ответе придёт бинарное содержимое файла.
curl -s -o result.pdf "URL_MACHINE_FROM_RESPONSE"
import { writeFile } from 'node:fs/promises'
const res = await fetch(urlMachine)
await writeFile('result.pdf', Buffer.from(await res.arrayBuffer()))
<?php
file_put_contents('result.pdf', file_get_contents($urlMachine));
Для ключа-вебхука авторизация вшита в адрес и работает сразу. Для ключа OAuth-приложения адрес действует ограниченное время. Скачивайте файл сразу после чтения записи, а если прошло время, перечитайте запись и возьмите свежий urlMachine.
Записать файл
Файл передаётся парой из имени и содержимого в формате base64.
Одиночное поле принимает одну пару.
{ "ufCrm_1a2b3c": ["contract.pdf", "BASE64_CONTENT"] }
Множественное поле принимает массив пар.
{ "ufCrm_1a2b3c": [["contract.pdf", "BASE64_CONTENT"], ["act.pdf", "BASE64_CONTENT"]] }
Признак множественности возвращает GET /v1/{entity}/fields. Примеры ниже показывают множественное поле. Для одиночного поля передайте одну пару без внешнего массива.
curl -s -X PATCH -H "X-Api-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
"https://vibecode.bitrix24.tech/v1/deals/100" \
-d '{"ufCrm_1a2b3c": [["contract.pdf", "BASE64_CONTENT"]]}'
await fetch('https://vibecode.bitrix24.tech/v1/deals/100', {
method: 'PATCH',
headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ ufCrm_1a2b3c: [['contract.pdf', base64Content]] }),
})
<?php
$ch = curl_init('https://vibecode.bitrix24.tech/v1/deals/100');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => ['X-Api-Key: YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'ufCrm_1a2b3c' => [['contract.pdf', $base64Content]],
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
curl_close($ch);
Тело запроса ограничено 1 МБ, а base64 увеличивает размер примерно на треть, поэтому практический предел одного файла — около 750 КБ. Для больших файлов используйте поле «Файл (диск)» и загрузку на Диск.
Чтобы сохранить уже прикреплённые файлы и добавить новый, передайте идентификаторы существующих файлов вместе с новой парой.
{ "ufCrm_1a2b3c": [{ "id": 35845 }, ["new.pdf", "BASE64_CONTENT"]] }
Удалить файл
Передайте в поле только те файлы, которые нужно оставить. Пустой массив очищает поле полностью.
{ "ufCrm_1a2b3c": [] }