CRM: amoCRM и Битрикс24
Готовых действий «создать сделку», «найти контакт», «передвинуть по воронке» в платформе нет. На каждую CRM есть пара нод — выбор подключения и один универсальный вызов, — и этот вызов представляет собой тонкую обёртку над её REST API: вы сами пишете, какой метод дёрнуть и что положить в тело, а платформа берёт на себя адрес, заголовок авторизации, таймаут и разбор JSON. Значит, рядом с редактором всегда открыта документация самой CRM: имена методов, названия полей и форма ответа — её, не наши. Это и есть цена универсальности: любой метод, который умеет CRM, доступен в день своего появления и не ждёт, пока мы напишем под него отдельную ноду с полями «Название сделки» и «Сумма».
Что хранит подключение и чем авторизуется запрос
Учётные данные лежат в рабочем пространстве, а не в графе — общее устройство описано в обзоре интеграций. Здесь важно, что у двух CRM устроено это по-разному.
| Вид подключения | Поля | Чем авторизуется запрос |
|---|---|---|
| amoCRM | Поддомен + Долгоживущий токен | заголовок Bearer с токеном |
| Битрикс24 | URL входящего вебхука (+ Домен портала, необязательно) | сам URL: код вебхука лежит в пути |
amoCRM. В поле Поддомен кладётся либо
голое имя аккаунта (mycompany → mycompany.amocrm.ru), либо целый хост в одной из трёх
разрешённых зон: amocrm.ru, amocrm.com, kommo.com. Список зон закрытый, и это не
перестраховка: значение подставляется в адрес запроса, к которому прикладывается ваш токен, —
произвольный хост в этом поле означал бы, что сохранённое подключение способно увезти токен
куда угодно. Токен — долгоживущий, выпускается в настройках интеграции самого аккаунта
amoCRM; OAuth с обновлением токена платформа не ведёт, так что срок жизни токена — ваша
забота, и в день его истечения все вызовы начнут отвечать 401.
Битрикс24. У входящего вебхука ключом служит весь URL целиком —
https://<портал>.bitrix24.ru/rest/<id пользователя>/<код>/, отдельного токена нет. Поэтому
поле хранится как секрет и обратно в браузер не отдаётся. Из этого следует практическое:
права запроса определяет не платформа, а то, от чьего имени и с какими правами вебхук создан
в портале. Ответ «недостаточно прав» лечится в Битрикс24, а не в воркфлоу. Поле
Домен портала (необязательно) на сам вызов не влияет —
оно сверяется с хостом вебхука при сохранении и ловит ровно одну ошибку: вставленный
вебхук от другого или уже пересозданного портала.
Две ноды на сервис
Схема одинакова для обеих CRM. Нода-конфигурация (Конфигурация amoCRM, Конфигурация Bitrix24) не делает ничего, кроме выбора сохранённого подключения, и отдаёт его проводом данных в порт вызывающей ноды (amoCRM REST-вызов, Bitrix24 REST-вызов). Порядок исполнения задаёт обычная цепочка выполнения — конфигурация подключается сбоку и на него не влияет.
- Исполнение + данные
- Данные
Ставить вторую ноду ради одного вызова необязательно: у вызывающей ноды есть собственное поле выбора подключения. Правило приоритета одно и то же во всём семействе интеграций — подключённый порт сильнее поля, и форма это прямо пишет, гася поле.
Пока не заполнено ни то, ни другое, редактор показывает предупреждение
wire.required_port_not_wired, а деплой и запуск такой граф отклоняют (разбор кодов — на
странице Коды валидации). Заполненное поле считается источником
наравне с проводом, так что «жёлтая» подсказка исчезает в обоих случаях.
Выход config-ноды в журнале выполнения отредактирован: там остаётся только название подключения, без токена и без URL вебхука. Это стоит помнить, когда вы смотрите на прогон и не находите значения — оно не потерялось, его намеренно не пишут в базу.
Как задаётся запрос
| Нода | Поля | Что в них кладут |
|---|---|---|
| amoCRM REST Call | method / path / body | HTTP-глагол из списка; путь от слэша; JSON-тело |
| Bitrix24 REST Call | method / params | имя метода через точку; JSON-объект параметров |
Разница не косметическая. У amoCRM адресация «как в HTTP»: GET /api/v4/leads,
POST /api/v4/contacts, PATCH /api/v4/leads/12345. Глагол выбирается из фиксированного
списка (GET, POST, PATCH, PUT, DELETE) — свободного ввода там нет, потому что вводить туда
нечего. У Битрикс24 адресация «как в RPC»: имя метода пишется через точку —
crm.lead.add, crm.deal.list, user.get, — и полностью задаёт, что произойдёт; путь и
глагол платформа собирает сама.
Поля path, body, method (у Битрикс24) и params — шаблонные: в них работают
{{ inputs.<порт> }}, {{ nodes.<id>.output.<поле> }}, {{ variables.<имя> }} и
{{ secret.<ИМЯ> }}, как везде (см. Шаблоны и переменные). Именно так и
подставляются данные, собранные предыдущими нодами:
/api/v4/leads/{{ nodes.find_lead.output.result._embedded.leads[0].id }}
Три вещи, на которых спотыкаются в первый раз:
- путь начинается со слэша. Он приклеивается к хосту как есть, без нормализации:
api/v4/leadsбез ведущего слэша даст бессмысленный адрес и невнятную ошибку; - пустое тело и
{}— разные вещи. Значение по умолчанию уbody— именно{}, и это непустой JSON-объект: он уйдёт телом запроса. Для чистогоGETполе стоит очистить совсем — тогда тело не отправляется вовсе. У Битрикс24 наоборот: пустыеparamsпревращаются в{}, потому что метод без аргументов — норма; - невалидный JSON — это отказ ноды, а не пустое тело. Ошибка приходит с кодом
VALIDATIONи указанием строки и колонки от разборщика. Собирать JSON конкатенацией строк в шаблоне — верный способ получить именно её; надёжнее собрать объект отдельной нодой и передать его целиком:{{ nodes.build_params.output }}.
Как читать ответ
Обе ноды кладут разобранный JSON в поле result своего выхода, то есть дальше по графу он
читается так:
{{ nodes.crm_call.output.result }}
Что именно лежит внутри — определяет CRM. У Битрикс24 конверт {"result": …, "time": …}
платформа распаковывает: в result попадает содержимое одноимённого поля ответа, а не
весь конверт. У amoCRM распаковывать нечего — тело ответа отдаётся как есть, со всей его
структурой (_embedded.leads, _links, _page и прочим), поэтому путь до нужного значения
бывает длинным. Проверять форму удобнее всего прогоном в панели проверки: она показывает
вход и выход каждой ноды целиком (см. Проверка воркфлоу).
Куда уходит ошибка
Клиенты обеих CRM устроены так, что сами никогда не бросают исключение: отказ транспорта, 401, 404 и ответ вида «ошибка в конверте» они сворачивают в один и тот же результат. Бросает нода — иначе вызов с мёртвым токеном заканчивался бы зелёным прогоном, а дальше по графу уезжало бы пустое значение.
Дальше поведение зависит от одной галочки в конфигурации ноды:
По умолчанию выключен: без него сбой роняет весь запуск.
- галочка выключена (так по умолчанию) — падение ноды роняет весь запуск: он получает
статус
failed, а ноды ниже по цепочке не выполняются; - галочка включена и выход подключён — управление уходит по ветке ошибки, а запуск
остаётся успешным. В ветку приезжает объект с полями
message(текст для автора),error_code,failed_node_idиfailed_node_type. Ветвиться следует поerror_code: это стабильная строка, пригодная для сравнения в нодеif.
Тонкость, которую видно только на практике: amoCRM различает виды отказов, а Битрикс24 —
нет. amoCRM отвечает HTTP-статусом, поэтому 401 превращается в AUTH, 404 — в NOT_FOUND,
402 — в BILLING. Битрикс24 (как и VK ниже) отвечает 200 с ошибкой внутри тела, разбирать
которую пришлось бы по тексту, поэтому его отказы приезжают одним кодом PROVIDER_ERROR, а
конкретика — в message. Если ветка должна отличать «нет прав» от «нет объекта», для
Битрикс24 придётся смотреть текст.
Что увидит человек: автор воркфлоу — нашу фразу плюс дословные слова CRM (в журнале, в ветке ошибки, в панели проверки), собеседник чата — только нейтральную формулировку по коду, без внутренностей провайдера. Подробный разбор — на странице Ошибки, статусы запусков — на странице Статусы.
Типичный сценарий: заявка из чата → поля → сделка
Самая частая связка выглядит так: человек пишет в чат свободным текстом, модель вытаскивает из этого текста поля, вызов CRM создаёт объект, а ответ CRM превращается в реплику для человека.
- Исполнение + данные
- LLM
- Данные
- Разобрать сообщение. Нода LLM со структурированным выводом возвращает не свободный текст, а JSON по заданной вами схеме — имя, телефон, что человек хочет. Именно схема, а не «попроси модель ответить JSON-ом», делает следующий шаг предсказуемым.
- Собрать параметры. В поле
paramsкладётся объект метода в терминах CRM:{"fields": {"TITLE": "{{ nodes.fields.output.title }}", "NAME": "{{ nodes.fields.output.name }}"}}. Имена полей — из документации Битрикс24; у портала с настроенными пользовательскими полями там будут ещё и коды видаUF_CRM_…. - Вызвать метод.
crm.lead.addдля лида,crm.deal.addдля сделки. Ответ — id созданного объекта; он же пригодится, если нужно сразу прикрепить комментарий или задачу вторым вызовом. - Ответить человеку. В ноде выхода — текст со ссылкой на созданный объект, собранный из
{{ nodes.crm_call.output.result }}. - Решить, что делать при отказе. Для заявки клиента «молча упасть» — худший исход: включите выход ошибки и отправьте по этой ветке честное «не получилось, мы записали контакт» плюс уведомление себе.
Разбор того, как строятся такие цепочки (ветвление, шаблоны, сборка ответа), — в Уроке: логика и ветвление. Готового CRM-шаблона в примерах сейчас нет: ни один из встроенных шаблонов CRM не трогает, потому что шаблон обязан заработать сразу после установки, а вызов CRM без вашего портала и вашего токена работать не может. Ближайшая отправная точка — шаблон с извлечением полей, к которому дописывается вызов.
VK и VK Teams: только исходящие сообщения
Четыре ноды рядом с CRM — Конфигурация VK и Отправить сообщение в VK, Конфигурация VK Teams и Отправить сообщение в VK Teams — устроены так же: подключение сбоку, поля с шаблонами, выход ошибки по той же галочке. Но делают они ровно одно — отправляют текстовое сообщение.
| Нода | Подключение хранит | Поля | Что возвращает |
|---|---|---|---|
| Send VK Message | токен доступа + версия API | peer_id, текст | message_id |
| Send VK Teams Message | токен бота (+ базовый URL API) | chat_id, текст | message_id |
Что из этого следует практически: обе ноды имеют смысл как уведомление — «пришла заявка»,
«упал ночной обмен», «клиент ждёт ответа» — в беседу сотрудников, а не как канал общения с
клиентом. Для VK peer_id кодирует тип получателя прямо в числе: пользователь — его id
(12345), сообщество — с минусом (-98765), беседа — 2000000000 + номер беседы (беседа
5 → 2000000005). Ошибиться здесь означает отправить сообщение не туда, а не получить
ошибку, — VK честно доставит его тому, чей id вы назвали. У VK Teams идентификатор чата —
это email сотрудника (user@example.com) или id группового чата (681234567@chat.agent).
Поле Базовый URL API (необязательно) нужно только тем, у кого
Teams развёрнут на своём сервере; для облачного оставьте пустым.
Что дальше
Интеграции: обзор
Где живут учётные данные и кто вправе их менять.
HTTP-запрос
Та же идея для сервиса, у которого нет своей ноды.
Ошибки
Коды, ветка on_error и что видит клиент.
Шаблоны и переменные
Как данные попадают в path, body и params.
Урок: логика и ветвление
Собрать цепочку целиком, а не одну ноду.
Справочник нод
Порты и поля всех четырёх нод CRM.