Условия и ветвления

Условие — развилка на холсте: сценарий проверяет что-то и идёт по пути «да» или по пути «нет». Это то, что превращает набор шагов в логику.

Как это выглядит

Узел «Условие» добавляется через «Добавить узел» → «Условие». У него две исходящие точки: зелёная «да» и красная «нет». К каждой можно подключить свою цепочку шагов.

Сценарий «Заявка» с развилкой

Что можно проверять

В панели условия задаются одна или несколько строк вида «поле — оператор — значение». Строки объединяются переключателем: «и» (все должны сойтись, по умолчанию) или «или» (хотя бы одна).

Операторы — по-человечески:

Оператор Проверка
равно / не равно Точное совпадение текста или числа
больше / больше или равно / меньше / меньше или равно Числа и даты
содержит Вхождение подстроки: form.email содержит @
совпадает с шаблоном Регулярное выражение, для строгих проверок формата
пароль совпадает Сверка введённого пароля с хэшем из CMS (для входа участников)
токен верный Проверка одноразовой ссылки из письма (сброс пароля, подтверждение)

Три тонкости:

  • В значениях для «пароль совпадает» и «токен верный» можно подставлять данные ({{ results.… }}), остальные операторы сравнивают значение буквально.
  • В проверках доступны и cookie посетителя — cookies.имя. На этой проверке построен режим «Только для участников» (он включается на узле «Начало» и не требует ручных условий).
  • Если проверка сломалась (опечатка в имени поля), условие считается несойденным — сценарий пойдёт по «нет». Это безопасный запасной вариант.

Пример из сценария «Заявка» (см. кадр выше): одна строка form.email — содержит — @. Заполнил посетитель почту — идём писать письмо и показывать «Спасибо»; оставил мусор — вежливо возвращаем на форму.

Несколько готовых рецептов. Каждый — одна-две строки в панели условия; выражение пишется целиком: поле, оператор, значение.

Почта похожа на почту — письмо вам, иначе возврат на форму:

form.email  содержит  @

Согласие на обработку — принять заявку, иначе показать страницу «подтвердите согласие»:

form.agree  равно  да

Промокод из списка — скидка в письме, иначе обычная цена. Несколько допустимых значений — несколько строк, объединённых переключателем «или»:

form.promo  равно  BLACKFRIDAY
form.promo  равно  SALE30

Только совершеннолетние — обычный путь, иначе отказ:

form.age  больше или равно  18

Корпоративная почта — заявка в отдел продаж, иначе общий поток. Регулярное выражение отсекает популярные бесплатные домены:

form.email  совпадает с шаблоном  .*@(?!gmail|yandex|mail)\..+

Регулярные выражения — инструмент точный, но хрупкий: ошибётесь в одном символе — условие начнёт молча отбрасывать правильные заявки. Поэтому сложную регэкспу всегда проверяйте на превью с несколькими разными значениями, а там, где можно обойтись простым «равно» со списком значений через «или», — обходитесь им.

Попробовать вживую можно на демо-сайте: primer.dynapi.ru/contacts — отправьте форму с пустым полем почты, и условие вернёт вас обратно; с заполненной — получите письмо-подтверждение и страницу «Спасибо».

Выражение вместо строк «поле — оператор — значение»

У условия есть второй режим: переключатель «Выражение (expr-lang)» — и ветку выбирает одно логическое выражение (в конфиге узла поле называется predicate_expr). Когда заполнены и строки, и выражение, побеждает выражение — строки остаются в узле как запасная копия для редактора.

Пример — «участник залогинен и найден в CMS как активный»:

member.id != nil && member.id != ""
  && len(results?.login?.members ?? []) > 0
  && results.login.members[0].status == "active"

Здесь видно главное правило чтения списков: ?. защищает доступ по ключу, но не индекс [0] — чтение первого элемента страхует проверка длины, а короткое замыкание && не даёт ему выполниться на пустом списке.

Что важно знать:

  • Результат обязан быть true или false. Ошибка компиляции или чтение по цепочке пустого значения останавливают сценарий с видимой ошибкой в журнале прогонов — ни «да», ни «нет» не выбирается молча. Несуществующее поле — это nil; сравнивайте с ним явно, одного != "" недостаточно (у отсутствующего поля nil != "" — истина).

  • В выражении доступны функции-аналоги строковых операторов: bcrypt_matches(candidate, hash) — сверка пароля с хэшем из CMS (то же, что «пароль совпадает»), token_valid(token, purpose, hash) — проверка одноразовой ссылки из письма (то же, что «токен верный»), — а также дайджесты для подписей вебхуков: md5_hex/sha1_hex/sha256_hex/ sha512_hex и HMAC-варианты вида hmac_sha256_hex(secret, input). Проверка подписи одним выражением:

    hmac_sha256_hex(secret("whsec"), raw_body) == headers["X-Signature"]
    
  • Секреты проекта читаются через secret("имя"); неизвестное имя — отказ проверки (безопасный вариант).

  • Сохранение проверяет компиляцию: выражение, которое не компилируется, сценарий не сохранится.

Строки «поле — оператор — значение» — LEGACY-режим: работают и поддерживаются, но для новой логики предпочитайте выражение. Исключение — составные подписи с ротацией ключей (Stripe t=…,v1=…): они пока проверяются только строковым режимом — оператором «Подпись вебхука совпадает (digest/HMAC)».

Ветка «нет» необязательна

Если у условия подключён только путь «да», то при несошедшемся условии сценарий просто завершится (посетитель останется на той же странице). Ничего дорисовывать ради симметрии не нужно.

Частый вопрос: а если в ветках по несколько шагов?

Соединяйте шаги в цепочку внутри ветки — «да» может привести к письму, за ним к странице «Спасибо», а «нет» — сразу к редиректу. Длина веток не ограничена; внутри ветки тоже можно поставить ещё одно условие и получить третий уровень развилки.

Зациклить сценарий (связь назад к более раннему узлу) платформа не даст — сохранение отклонится с ошибкой.


Следующая статья: Маршруты: как посетитель попадает в сценарий →