Диагностика CRM-интеграций в РФ: Bitrix24, amoCRM и n8n ¶
Обновлено: 2026-05-29
Короткий ответ ¶
Если Битрикс24 или amoCRM через n8n создаёт дубли лидов, теряет поля или пишет сделку не в ту воронку, почти всегда проблема в трёх местах: нет стабильного внешнего ID, телефон/email не нормализуются перед поиском, а workflow смешивает “создать” и “обновить” в одной ветке. Для CRM-интеграций важнее не количество нод, а порядок: принять событие, очистить данные, найти существующий контакт/сделку, проверить права, затем создать или обновить запись.
Быстрая диагностика по симптомам ¶
| Симптом | Вероятная причина | Первое действие |
|---|---|---|
| Каждый webhook создаёт новый лид | нет дедупликации | искать контакт по телефону/email до create |
| Поля пустые | неверный путь к данным или формат | сохранить входной payload и проверить expressions |
| Сделка попала не в ту воронку | перепутан pipeline/status ID | вынести ID в конфиг |
401 или 403 |
токен/вебхук без прав | проверить пользователя и scopes |
| Повторные лиды после сбоя | CRM или форма повторила событие | хранить event_id |
| UTM пропали | поле не передаётся в CRM или перезаписывается | разделить first-touch и last-touch |
Шаг 1. Зафиксируйте входной payload ¶
Перед тем как чинить CRM-ноды, сохраните сырой входящий payload. Иначе вы будете гадать: поле не пришло из формы, потерялось в n8n или не принялось CRM.
Минимальный диагностический объект:
{
"external_id": "lead-001",
"name": "Анна",
"phone": "+7 999 000-00-00",
"email": "anna@example.ru",
"utm_source": "yandex",
"form_id": "landing-main",
"created_at": "2026-05-29T10:00:00+03:00"
}
Если в payload нет external_id, создайте его на стороне формы, сайта или первого workflow. Нельзя надёжно бороться с дублями, если событие каждый раз выглядит как новое.
Шаг 2. Нормализуйте телефон и email до поиска ¶
CRM часто хранит телефон в одном формате, а форма присылает в другом: +7, 8, пробелы, скобки, дефисы. Если искать контакт по сырому номеру, workflow не найдёт существующего клиента и создаст дубль.
Нормализация должна выполняться до поиска:
- убрать пробелы, скобки и дефисы;
- привести российские номера к одному формату;
- email перевести в lowercase;
- пустые значения не использовать как ключ поиска;
- сохранить исходный номер отдельно, если он нужен менеджеру.
Пример для Code node:
const phoneRaw = $json.phone || '';
const phone = phoneRaw.replace(/\D/g, '').replace(/^8/, '7');
const email = ($json.email || '').trim().toLowerCase();
return [{ json: { ...$json, phone_normalized: phone, email_normalized: email } }];
Шаг 3. Разделите create и update ¶
Правильный CRM-flow обычно выглядит так:
- Найти контакт по нормализованному телефону.
- Если не найден — найти по email.
- Если контакт найден — обновить нужные поля, но не перетирать важную историю.
- Если контакт не найден — создать контакт.
- Найти открытую сделку по контакту или external_id.
- Если открытая сделка есть — обновить её.
- Если нет — создать новую сделку в нужной воронке.
Ошибка многих workflow — сразу создавать лид, а потом пытаться “объединять” дубли. Это дороже и опаснее, чем искать перед созданием.
Шаг 4. Вынесите ID воронок и стадий из нод ¶
ID воронки, стадии, ответственного, источника и пользовательских полей не должны быть разбросаны по десяти нодам. Создайте отдельный Set/Code node “CRM config” или таблицу конфигурации.
Пример конфигурации:
{
"source": "landing-main",
"pipeline_id": "sales_primary",
"stage_new": "new_lead",
"stage_paid": "paid",
"responsible_user_id": "12345",
"custom_fields": {
"utm_source": "UF_CRM_UTM_SOURCE",
"external_id": "UF_CRM_EXTERNAL_ID"
}
}
Когда CRM поменяет стадию или добавит новую воронку, вы исправите конфиг, а не будете искать значение по всему workflow.
Шаг 5. Проверяйте права не только по факту авторизации ¶
Успешный credential test не означает, что интеграция может создавать сделки, читать контакты, менять ответственного и писать пользовательские поля. 401 обычно говорит о проблеме авторизации, а 403 — о правах. Но в CRM встречаются и “мягкие” ошибки: запрос принят, часть полей проигнорирована.
Проверяйте отдельно:
- какой пользователь или приложение выполняет запрос;
- есть ли доступ к нужной воронке;
- видит ли пользователь custom fields;
- разрешено ли создавать контакты и сделки;
- не ограничены ли webhooks/IP/портал;
- не истёк ли токен OAuth.
Шаг 6. Защититесь от повторных webhooks ¶
Форма, сайт, телефония, чат-виджет или сама CRM могут отправить одно и то же событие несколько раз. Не пытайтесь “на глаз” понять, дубль это или новая заявка. Введите таблицу обработанных событий.
Ключи для дедупликации:
| Источник | Лучший ключ | Запасной вариант |
|---|---|---|
| форма сайта | form_submission_id |
phone + form_id + date |
| звонок | call_id |
phone + call_started_at |
| платеж | payment_id |
order_id + status |
| чат | conversation_id |
email/phone + timestamp |
Если событие уже было обработано, workflow должен завершиться с понятным логом, а не создавать вторую сделку.
Шаг 7. Не перетирайте маркетинговые данные ¶
UTM-метки часто ломаются не из-за CRM, а из-за update-логики. Первый источник клиента и последний источник обращения — разные сущности. Если каждый новый webhook перезаписывает utm_source, отчёты перестанут отвечать на вопрос, откуда пришёл клиент впервые.
Рекомендация:
first_utm_*заполнять только если поле пустое;last_utm_*обновлять при каждом новом обращении;form_idиlanding_urlхранить отдельно;- источник ручного менеджера не смешивать с автоматическим источником формы.
Контрольный тест ¶
Сделайте три прогона:
- Новый телефон и новый email — должен создаться контакт и сделка.
- Тот же телефон, другой email — должна обновиться существующая карточка или появиться задача, но не дубль.
- Тот же
external_idповторно — workflow должен завершиться как повтор события.
После теста проверьте CRM руками: контакт, сделка, поля, ответственный, UTM, комментарий с execution ID.
FAQ ¶
Почему CRM создаёт дубли, хотя я ищу контакт?
Проверьте формат телефона и email. Если поиск идёт по сырому номеру, разные написания одного телефона выглядят как разные клиенты.
Что лучше использовать для дедупликации — телефон или email?
Лучше иметь внешний event_id или external_id. Телефон и email полезны для поиска клиента, но не всегда уникальны и могут меняться.
Почему поля не записываются, но ошибки нет?
Возможно, используются неправильные ID пользовательских полей или у интеграционного пользователя нет прав. Сравните request/response и проверьте права в CRM.
Нужно ли хранить сырой payload?
Да, хотя бы временно и без лишних персональных данных. Это помогает доказать, где потерялось поле: в форме, n8n или CRM.
Как безопасно обновлять UTM?
Разделите first-touch и last-touch поля. Первые не перезаписывайте, последние обновляйте при новом обращении.