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 (как и ВКонтакте) отвечает 200 с ошибкой внутри тела, разбирать
которую пришлось бы по тексту, поэтому его отказы приезжают одним кодом PROVIDER_ERROR, а
конкретика — в message. Если ветка должна отличать «нет прав» от «нет объекта», для
Битрикс24 придётся смотреть текст.
Что увидит человек: автор сценария — нашу фразу плюс дословные слова CRM (в журнале, в ветке ошибки, в панели проверки), собеседник чата — только нейтральную формулировку по коду, без внутренностей провайдера. Подробный разбор — на странице Ошибки, статусы запусков — на странице Статусы.
Типичный сценарий: заявка из чата → поля → сделка
Самая частая связка выглядит так: человек пишет в чат свободным текстом, модель вытаскивает из этого текста поля, вызов CRM создаёт объект, а ответ CRM превращается в реплику для человека.
- Исполнение + данные
- LLM
- Данные
- Разобрать сообщение. Нода LLM с JSON-ответом возвращает не свободный текст, а 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 без вашего портала и вашего токена работать не может. Ближайшая отправная точка — шаблон с извлечением полей, к которому дописывается вызов.
Ноды ВКонтакте: устройство то же, предмет другой
Рядом с CRM в палитре стоит группа VK — десять нод, собранных по той же схеме: подключение приезжает сбоку проводом данных, поля шаблонные, отказ уходит по той же галочке «Выход ошибки». Разница в предмете: это не универсальный вызов чужого REST, а готовые действия сообщества.
| Нода | Что делает |
|---|---|
| VK: подключение | выбирает сохранённое подключение и отдаёт его остальным нодам |
| VK: отправить сообщение | текст и вложения в личку, беседу или сообщество; возвращает message_id |
| VK: кнопки | клавиатура под ответом; нажатие возвращается командой и аргументами |
| VK: история чата · VK: поиск по истории | читают то, что бот записал сам: прошлое ВКонтакте боту не отдаёт |
| VK: получить файл | скачивает вложение файловой ссылкой — ссылки ВКонтакте протухают |
| VK: переслать сообщение | forward с пометкой источника или copy без неё |
| VK: информация о чате · VK: модерация | беседа и её участники; удалить сообщение, исключить, закрепить |
| VK: инструменты агента | те же чтение и модерация, но действие выбирает модель |
Одна деталь, на которой ошибаются молча: peer_id кодирует тип получателя прямо в
числе. Пользователь — это его id (12345), сообщество — с минусом (-98765), беседа —
2000000000 плюс номер беседы (беседа 5 → 2000000005). Промах здесь означает сообщение
не тому человеку, а не ошибку: ВКонтакте честно доставит его тому, чей id вы назвали.
У нод, принимающих peer_id, пустое поле значит «чат текущего хода» — внутри бота это
самый надёжный вариант.
Второе, что стоит знать заранее: модерация и точный список участников требуют уровня доступа, который выдаётся в самой беседе, а не ключом сообщества. Бана и мьюта для беседы у ВКонтакте нет вовсе — есть исключение участника, и ноды предлагают ровно те действия, которые существуют.
Что дальше
Интеграции: обзор
Где живут учётные данные и кто вправе их менять.
HTTP-запрос
Та же идея для сервиса, у которого нет своей ноды.
Ошибки
Коды, ветка on_error и что видит клиент.
Шаблоны и переменные
Как данные попадают в path, body и params.
Урок: логика и ветвление
Собрать цепочку целиком, а не одну ноду.
Справочник нод
Порты и поля всех четырёх нод CRM.