Розробка інтеграції Bitrix24 через REST API
REST API Bitrix24 — одна з найдокументованіших частин платформи, але інтеграції на ньому все одно регулярно «ламаються»: токени протухають о 01:00 ночі, batch-запити повертають часткові помилки, а ліміт у 2 запити на секунду починає працювати саме тоді, коли потрібно терміново синхронізувати 5000 контактів. Розробка надійної інтеграції — це не просто «викликати метод і записати відповідь».
Модель авторизації: OAuth2 проти вебхуків
Для постійних інтеграцій використовується OAuth2. Bitrix24 видає access_token (TTL 1 година) і refresh_token (TTL 14 днів). Ключова точка відмови — оновлення токена: якщо два паралельних процеси одночасно виявлять протухлий access_token і обидва підуть його оновлювати — один із refresh_token інвалідується та інтеграція «падає». Рішення: оновлення токена через Redis-локу або блокування на рівні БД.
// Паттерн атомарного оновлення токена через Redis
$lock = $redis->set("b24:token_refresh:{$portalId}", 1, ['NX', 'EX' => 10]);
if (!$lock) {
// Інший процес вже оновлює — чекаємо
usleep(500000);
return $this->getToken($portalId);
}
try {
$newTokens = $this->requestNewToken($refreshToken);
$this->storeTokens($portalId, $newTokens);
} finally {
$redis->del("b24:token_refresh:{$portalId}");
}
Для простих сценаріїв без необхідності працювати від імені конкретного користувача — вхідний вебхук. URL виду https://domain.bitrix24.ru/rest/1/{token}/method.json зі статичним токеном простіший, але не прив'язаний до користувача і не оновлюється.
Робота з лімітами
Хмарний Bitrix24: 2 запити на секунду, не більше 50 у batch. Коробковий — налаштовується в /bitrix/.settings.php ключем throttle_controller.
Для масових операцій — лише batch. 50 методів в одному HTTP-запиті із залежностями через $result[N]:
$batch = [
'contacts' => 'crm.contact.list?start=0&select[]=ID&select[]=NAME',
'deal_1' => 'crm.deal.get?id=$result[contacts][0][ID]',
];
При перевищенні ліміту API повертає помилку QUERY_LIMIT_EXCEEDED. Правильна стратегія: exponential backoff — чекаємо 1с, 2с, 4с. Не ломимось повторно негайно — це погіршує ситуацію.
Ключові групи методів
CRM: crm.lead.*, crm.deal.*, crm.contact.*, crm.company.*. Особливість: користувацькі поля мають префікс UF_CRM_ для лідів/угод або довільний для контактів/компаній — тип і ID поля потрібно запитувати через crm.userfield.list.
Задачі: tasks.task.*. Поле UF_* у задачах — через task.userfield.getlist. Чеклісти — окремі методи task.checklistitem.*.
Диск: disk.file.*, disk.folder.*. Завантаження файлу — через multipart POST на спеціальний URL, який спочатку потрібно отримати методом disk.folder.uploadfile.
Користувачі: user.get, user.add, user.update. Фільтрація за DEPARTMENT — ID відділу, не його назва.
Обробка пагінації
Більшість методів списку повертають максимум 50 записів і поле next із курсором. Правильний обхід:
$start = 0;
do {
$response = $b24->call('crm.deal.list', ['start' => $start, 'filter' => $filter]);
$items = $response['result'];
// обробка $items
$start = $response['next'] ?? null;
} while ($start !== null);
Для великих списків (>10 000 записів) start працює повільно — offset-пагінація деградує. Замість неї використовуємо фільтрацію за ID > last_id і сортування за ID ASC.
Робота з полями типу «список» і «прив'язка»
Поля типу «Прив'язка до елемента CRM» (crm_entity) повертають масив навіть якщо прив'язка одинична. При оновленні — передаємо масив. Поля типу «Список» — через числовий ID значення, не через його відображувану назву. Список значень — crm.status.list?filter[ENTITY_ID]=STATUS_ID.
Синхронізація та ідемпотентність
Кожен запис зовнішньої системи повинен мати mapped ID у Bitrix24. Стандартний підхід: використовуємо поле UF_CRM_EXTERNAL_ID (або аналогічне кастомне поле) для зберігання зовнішнього ідентифікатора. Перед створенням — перевіряємо crm.deal.list?filter[UF_CRM_EXTERNAL_ID]=ext123. Якщо знайшли — оновлюємо, не знайшли — створюємо. Це захищає від дублів при повторному запуску синхронізації.
Обробка помилок і моніторинг
API повертає помилки в полі error + error_description. Типові:
| Помилка | Причина | Рішення |
|---|---|---|
QUERY_LIMIT_EXCEEDED |
Перевищено ліміт 2 рпс | Exponential backoff |
expired_token |
access_token протух | Оновити через refresh_token |
ERROR_CORE |
Помилка на боці Bitrix24 | Повтор через 30–60 сек |
ACCESS_DENIED |
Прав недостатньо | Перевірити права програми/користувача |
NOT_FOUND |
Об'єкт видалено | Видалити маппінг у зовнішній системі |
Усі виклики API логуємо: метод, параметри (без токенів), статус відповіді, час виконання. При error rate > 5% за 5 хвилин — алерт.
Етапи розробки
| Етап | Зміст | Термін |
|---|---|---|
| Проєктування | Карта даних, вибір методів, модель маппінгу | 3–5 днів |
| OAuth2 та управління токенами | Авторизація, зберігання, ротація | 2–3 дні |
| Ядро синхронізації | CRUD-операції з Bitrix24, пагінація | 1–2 тижні |
| Обробка лімітів і помилок | Rate limiting, retry, circuit breaker | 3–5 днів |
| Тестування | Юніт-тести, інтеграційні тести на sandbox | 1 тиждень |
| Моніторинг | Логування, метрики, алерти | 2–3 дні |
Загалом: 4–8 тижнів залежно від кількості синхронізованих сутностей і напрямків передачі даних.







