Узлы-действия: что умеет каждый

Справочник по всем восьми действиям, которые можно положить на холст флоу. Для каждого — что делает, когда брать и что вписать в поля.

Общий порядок работы: «Добавить узел» → «Действие», в панели справа выбрать «Тип действия» и заполнить поля. Правки сразу попадают в схему — не забудьте нажать «Сохранить черновик».

Панель настроек GraphQL-узла

Поля, которые есть у любого действия

  • При ошибке — «Продолжить» или «Остановить». По умолчанию сбой шага не останавливает флоу (например, письмо не ушло — а страница «Спасибо» посетителю всё равно покажется). «Остановить» — когда следующий шаг без этого бессмыслен.
  • Запустить в фоне (не ждать) — для медленных внешних сервисов: посетитель получает ответ сразу, шаг доделывается в фоне. Работает у «Отправить email», «HTTP POST» и «Уведомление в Telegram».

Какие данные доступны в текстовых полях

Почти любое текстовое поле действия — это шаблон, куда можно подставлять данные. Основные источники:

Запись Откуда данные
{{ form.имя }} Поля отправленной формы (у формы на сайте имена полей — name, email…)
{{ json.имя }} Тело JSON-запроса (когда пишет программа, а не человек)
{{ query.имя }} Параметры из адреса страницы (?utm_source=…). Только в GET-флоу: у отправки формы (POST) тело раскладывается по form.* / json.* / xml.*, а query не подставляется
{{ params.имя }} Куски пути маршрута: для /blog/:slug это {{ params.slug }}
{{ results.ключ… }} Ответы предыдущих GraphQL-узлов — по их «Ключу результата»
{{ member.поле }} Залогиненный участник сайта (id, email…)
{{ headers.имя }} Заголовки запроса (для интеграций по API)

GraphQL — взять данные из CMS

Когда брать: странице нужны записи — каталог, блог, список сотрудников.

  • Источник запроса — «Из библиотеки» (повторно используемый запрос из вкладки «Библиотека запросов») или «Вручную» (запрос пишется прямо в узле).
  • Запрос — что взять. Пример: query { services(limit: 50) { id title price } }.
  • Переменные (JSON) — значения для запроса-с параметрами; каждое строковое значение тоже обрабатывается как шаблон (можно подставить {{ form.email }}).
  • Ключ результата — имя, под которым ответ станет доступен следующим узлам и шаблону: results.ключ. Для ключа catalog список услуг в шаблоне лежит в catalog.data.services.
  • Секретные переменные — имена полей формы (по одному), значения которых не должны сохраняться в «Отправках» (пароли). Флоу их видит, а хранилище — нет.

Запрос из библиотеки в инспекторе

Рендер страницы — показать HTML

Когда брать: флоу отвечает за страницу (вместе с маршрутом GET).

  • Шаблон — файл из вкладки «Файлы» (например, katalog.liquid). Общую обёртку сайта (шапку, подвал, <head>) шаблон подключает сам — как устроена база, разобрано в статье «Файлы сайта».

Одна и та же страница работает и как ответ на форму. В демо-проекте у «Заявки» (форма на /contacts) последняя карточка — узел «Рендер страницы» с шаблоном spasibo.liquid: посетитель отправил форму — и вместо перезагрузки видит собранную этим шаблоном страницу «Спасибо». Сам шаблон лежит во вкладке «Файлы»; страница не существует сама по себе — её каждый раз рисует узел.

JSON-ответ — ответить данными

Когда брать: адрес на сайте нужен программе, а не человеку (API для приложения или партнёра).

  • Тело (шаблон) — JSON, который получит запрашивающий; внутрь можно подставлять данные ({{ results.ключ… }}).
  • Статус — код ответа (по умолчанию 200).

Как собрать JSON-тело из полей формы

Для полей «Тело (шаблон)» узлов «JSON-ответ» и «HTTP POST». Тело — это шаблон, который должен превратиться в корректный JSON. Три правила:

1. Каждое значение — через фильтр json. Он сам ставит кавычки и экранирует кавычки и переносы внутри значения. Без него фамилия с кавычкой сломает весь JSON.

2. Необязательные поля — с запятой внутри {% if %} — тогда пропущенное поле не оставит висячей запятой.

3. Осторожно с blank. Проверка {% if form.lastName != blank %} означает лишь «поле пришло»: пустая строка и строка из пробелов пройдут её, и в CRM уедет "lastName":" ". Правильный рецепт — обрезать пробелы и сравнить с пустой строкой:

{% assign ln = form.lastName | strip %}
{% if ln != "" %},"lastName":{{ ln | json }}{% endif %}

Присвоение обязательно: фильтр внутри самого условия ({% if form.x | strip != "" %}) — синтаксическая ошибка.

Готовый пример контакта для CRM:

{%- assign fn = form.firstName | strip -%}
{%- assign ln = form.lastName | strip -%}
{%- assign ph = form.phone | strip | digits -%}
{%- assign em = form.email | strip -%}
{"firstName":{{ fn | json }}{% if ln != "" %},"lastName":{{ ln | json }}{% endif %}{% if ph != "" %},"phones":[{{ ph | json }}]{% endif %}{% if em != "" %},"emails":[{{ em | json }}]{% endif %}}

Всё пустое (поле не пришло, пустое, из одних пробелов) пропускается, телефон очищается до цифр, кавычки внутри значений экранируются.

Полезные фильтры для тела

Фильтр Пример Что делает
json {{ form.name | json }} Значение → корректный JSON (кавычки, экранирование); пустое поле → null
strip {{ form.name | strip }} Обрезает пробелы по краям. Фильтра «trim» нет — это он и есть; lstrip/rstrip — с одной стороны
digits {{ form.phone | digits }} Оставляет только цифры: +7 (900) 123-45-6779001234567
number {{ form.qty | number | json }} Строку — в число: "990.50"990.5; не-число → null
base64_encode / base64_decode {{ form.pair | base64_encode }} Кодирует/раскодирует base64 (например, заголовок Basic-auth)
now {{ "" | now }} Текущее время в Unix-секундах
uuid {{ "" | uuid }} Случайный UUID (ключи идемпотентности)

Арифметика

plus, minus, times, divided_by, modulo, abs, ceil, floor, round — всё есть: {{ form.price | number | times: 2 }}. Подводные камни:

  • Строки считаются как дробные числа — очень большие числа (длиннее 15 цифр) теряют точность. Для цен и количеств это неважно.
  • plus/times на пустом или не-числовом поле молча дают 0. Нужно честное «не пришло» — используйте number.
  • divided_by с делителем-строкой, нулём или отсутствующим полем ломает весь шаблон. Обе стороны — через number, и проверяйте делитель:
{% assign total = form.total | number %}
{% assign parts = form.parts | number %}
{% if parts %}{{ total | divided_by: parts }}{% else %}0{% endif %}

Памятка: обрезать и закодировать — | strip | json (отсутствующее поле даст ""; голый | json даст null). Числом, а не строкой — | number | json.

Отправить email — письмо с вашего сервера

Когда брать: узнать о заявке на почту, отправить посетителю подтверждение.

  • Кому / Копия — адреса (можно несколько; подойдёт и {{ form.email }} — ответить самому посетителю).
  • Тема и Содержимое письма — в поле «Содержимое письма» два режима: «Текст (Liquid)» — пишете текст письма прямо в узле, подставляя данные ({{ form.name }}, {{ results.ключ… }}); «Шаблон сайта» — берёте готовый HTML-файл из вкладки «Файлы» (так делают оформленные письма).
  • SMTP — ваш почтовый сервер (хост, порт, логин/пароль ящика, адрес отправителя). Платформа письма за вас не отправит — нужен собственный ящик; для тестов подойдёт любой бесплатный SMTP.
  • В текстовом письме работает фильтр signed_token — подставить одноразовую ссылку участника (используется в письмах сброса пароля).

Важно: пароли в письмы не попадают — платформа блокирует такие попытки.

HTTP POST — передать дальше

Когда брать: заявку нужно положить в CRM, таблицу или другой сервис.

  • URL, Тело (шаблон), Заголовки (например, токен авторизации сервиса), Таймаут (по умолчанию 10 секунд).
  • Долгие внешние сервисы — повод включить «Запустить в фоне».
  • Как собрать «Тело (шаблон)» — раздел «Как собрать JSON-тело» выше.

Уведомление в Telegram — сообщение в чат

Когда брать: быстро видеть заявки в общем чате команды.

  • Webhook-URL — адрес чат-бота (токен бота уже внутри URL; отдельного поля для него нет).
  • Текст сообщения — шаблон с данными заявки.
  • chat_id — обязателен для официального api.telegram.org.

Когда брать: вход участника, «запомнить меня», скрытые метки.

  • Имя, Значение (шаблон), Срок жизни в днях (0 — удалить cookie, так работает «Выход»), Путь (по умолчанию весь сайт).
  • Режим «сессионная» — cookie живёт до закрытия браузера; такая в одном флоу может быть только одна.
  • Значение запечатывается подписью платформы — подделать его извне нельзя.

Редирект — перенаправить

Когда брать: после действия увести посетителя на другой адрес (например, с /old-page на /new-page или обратно на форму при ошибке).

  • Куда — адрес (шаблон: можно /{{ params.slug }}).
  • Статус — по умолчанию 303 «Смотри другой адрес».

Ещё два вида узлов

Кроме действий, на холсте есть узлы «Условие» (развилка «да/нет»); обязательного узла «Конец» нет: ветка просто заканчивается там, где у последней карточки не поставлена исходящая связь, — и схема считается завершённой. Условия разобраны в отдельной статье «Условия и ветвления».

Меню «Добавить узел»


Следующая статья: Условия и ветвления