Перейти к основному контенту

Как построить визуальный no-code редактор воронок на React поверх Metabot

Этот урок — про то, как поверх Metabot (который сам по себе полный low-code/full-code backend для чат-ботов и ассистентов) построить новый продукт: визуальный конструктор чат-ботов.

То есть вы создадите реальный продуктовый интерфейс — свой ManyChat / BotHelp, но умнее и современнее.

Главная идея:

Metabot — это ядро.
Пройдя этот урок, вы научитесь строить целые продукты поверх ядра, создавая собственный фронт, визуальный редактор, AI-функции и конструкторы.

Часть 1. Что будет в этом уроке — и чего здесь не будет

Чтобы вы сразу понимали рамки: этот урок — это фундамент, первая версия конструктора, на котором вы сможете дальше строить полноценный продукт. Здесь мы создаём работающий скелет визуального редактора и настраиваем импорт в Metabot.

А теперь — по пунктам.


Что будет в уроке

1. Создадим собственный JSON-формат воронки

Вы:

  • придумаете свой формат,

  • определите структуру шагов воронки,

  • создадите свои типы команд,

  • добавите свои параметры и опции.

То есть вы спроектируете свой DSL (domain-specific language) — язык описания воронок вашего продукта.


2. Разберётесь, как работает Mapper

Мы подробно посмотрим, как:

  • входящий JSON обрабатывается,

  • шаги проверяются,

  • неподдерживаемые типы фильтруются,

  • нужные команды собираются,

  • создаются переходы, кнопки, логгирование, LLM-вызовы и так далее.

То есть вы поймёте логику трансформации вашего формата → формат Metabot.

Вы получите исходный код Mapper'а.


3. Разберётесь, как работает Builder

Мы детально пройдём по механике:

  • создания секции/папки скриптов в Metabot,

  • создания скриптов,

  • добавления low-code команд в скрипт,

  • создания переходов и menu-кнопок,

  • удаления старых версий воронки.

И главное — вы увидите, как Builder напрямую манипулирует базой данных Metabot (PostgreSQL) через PHP/V8.

Это даёт понимание того, как работает ядро платформы и как можно строить свои надстройки.

Вы получите исходный код Builder'а.


4. Научитесь подключать Metabot как backend

Вы увидите, как:

  • передавать JSON в Metabot через API,

  • запускать импорт,

  • пересобирать воронку целиком,

  • структурировать код для своего продукта.

То есть Metabot превращается для вас в backend-as-a-platform, который вы можете использовать под любые проекты.


5. Сделаем визуальный редактор на React (с помощью V0 + Cursor)

Мы:

  • создадим canvas и интерфейс узлов,

  • свяжем их с JSON,

  • добавим  импорт и экспорт в/из файла,

  • добавим базовые настройки шагов и валидации,

  • подготовим front-end архитектуру.

Вы получите:

  • исходный код редактора,

  • архитектуру компонентов,

  • промпты, с помощью которых редактор собирался (это важно — это обучает самостоятельному созданию продуктов).


6. Настроим рабочий цикл разработки

Первые итерации будут такие:

1) создаём JSON вручную → 
2) отправляем через Postman → 
3) смотрим, как Metabot создал воронку →
4) фиксируем ошибки →
5) делаем свои команды →
6) строим визуальный редактор, который уже генерит нужный JSON →
7) импортируем в Metabot одной кнопкой

Это честный, практичный, продуктовый процесс.


7. Вы получите всё, чтобы создать свой продукт

В итоге у вас будет:

  • работающий визуальный редактор,

  • свой JSON-формат,

  • свой набор команд,
  • сохранение в файл и загрузка из файла,
  • исходники маппера/билдера,

  • связка React → JSON → Metabot.

На этом можно строить:

  • no-code конструктор,

  • CJM-редактор,

  • AI-конструктор цепочек,

  • бизнесовый продукт поверх Metabot.


🚫 Чего в этом уроке НЕ будет

Чтобы не вводить в заблуждение — сразу фиксируем:

1. Не будет двусторонней синхронизации

Мы делаем только импорт из вашего конструктора → Metabot.

То есть:

  • если воронка существует — она удаляется и создаётся заново,

  • мы не читаем текущую структуру из Metabot,

  • мы не отображаем её обратно в редактор.

Это осознанное упрощение.

Вторую сторону можно сделать, но это отдельный блок задач:
читать данные Metabot → конвертировать → отображать → синхронизировать версии.

Мы это оставляем для следующего урока, если будет запрос.


2. Не будет полноценного менеджмента трафика

Это очень важный момент.

В реальной жизни по ранее импортированной воронке уже могут идти живые пользователи.
Если вы меняете воронку, возникают вопросы:

  • что делать с активными пользователями?

  • надо ли их перенаправлять в новую версию?

  • надо ли блокировать обновления?

  • нужно ли создавать копии воронок?

  • нужно ли делать миграции шагов?

  • как правильно писать стратегию версионирования?

Это целая философия, и у каждого продукта — свой подход.
Мы эту сложность сознательно не включаем в этот урок.

Но если понадобится понадобится помощь — дайте знать, попробуем помочь.


3. Не будет полноценной "платформенности"

В этом уроке:

  • нет авторизации и регистрации — импорт по API токену пользователя, привязанному к боту.
  • нет совместной работы.

Мы делаем первую версию конструктора, но она уже рабочая и расширяемая.


Принял. Делаю первую итерацию — без фанатизма, но уже структурно, лаконично, красиво, чтобы можно было вложить в документацию и развивать дальше.
Ты дал огромный объём информации, поэтому я сейчас фиксирую каркас главы 2, + делаю первый блок: спецификация команд Metabot + JSON-формат, + простую таблицу команд, красиво оформленную, + мини-описание модели данных (sentences, phrases, references).

В следующей итерации я смогу:

    добить оставшиеся разделы,

    оформить финальный CJM JSON на 20 шагов,

    добавить продвинутую постановку задач.


    Глава 2. JSON-формат и фундаментальная модель данных Metabot

    Чтобы создать собственный визуальный конструктор поверх Metabot, нужно понимать две вещи:

      Какие команды реально существуют в ядре платформы

      Как Metabot хранит эти команды в базе данных

      Эта глава даёт разработчику язык конструктора — JSON-формат шага, таблицу команд и модель хранения внутри Metabot.


      2.1. Базовая модель данных Metabot

      Метабот — low-code движок. Его диалоговая логика физически живёт в трёх таблицах:

      sentences — это скрипты

      Каждый шаг в нашем редакторе превратится в отдельный скрипт Metabot.

      Поле Что значит id ID скрипта code Уникальный код (мы сами создаём) name Читабельное имя bot_id Бот, которому принадлежит скрипт section_id Папка/категория (наша “воронка”) ... Остальные поля нам пока не нужны

      Пример:

      id: 85681
      code: "test-script"
      name: "TestScript"
      bot_id: 2370

      phrases — это команды внутри скрипта

      Одна запись = одна команда.
      Каждый шаг в нашем редакторе может порождать от 1 до 10 фраз.

      Поле Описание id ID команды type Тип команды (send_text, run_javascript, …) sentence_id Скрипт, которому команда принадлежит content Текст или JSON-контент команды sort_order Порядок выполнения alias Уникальный ID команды

      Пример вывода send_text:

      type: "send_text"
      sentence_id: 85681
      content: "Hello, World!"
      sort_order: 0

      Пример ввода пользователя value_input:

      id: 231462
      type: value_input
      sentence_id: 85681
      content: {"attribute_key":"var","prompt":"Введите число",...}
      sort_order: 1

      references — это кнопки (меню)

      Меню — это не фраза, а отдельная таблица (так исторически, да). Каждая запись — это кнопка.

      Поле Значение sentence_id Скрипт, которому меню принадлежит caption Текст кнопки code Код/значение кнопки jump_sentence_id Куда переходить sort_order Порядок кнопок line_num Для многострочных клавиатур condition_script_code Условие отображения

      Пример:

      sentence_id: 85681
      caption: "Start Over"
      code: "1"
      jump_sentence_id: 85680

      📌 Все 21 команды Метабота

      На момент написания этого урока в Metabot есть 20 команд в скриптах + одна неявная команда (меню).

      № Команда Что делает Где хранится Пример content в БД 1 send_text отправляет текстовое сообщение phrases Hello, World!!! 2 value_input запрашивает ввод и валидирует phrases {"attribute_key":"abc","prompt":"Введите число", ...} 3 run_javascript выполняет JS на сервере se lead.setAttr('abc', 123); 4 send_image отправляет изображение phrases {"path":"bot/.../logo.png","name":"logo.png"} 5 send_file отправляет файл (любые документы) phrases {"path":"bot/...","name":"file.pdf"} 6 run_sentence выполняет другой скрипт, останавливает текущий phrases 85681 7 send_email отправляет email phrases {"recipient":"user@mail","subject":"...","body":"..."} 8 run_trigger запускает триггер phrases {"trigger_id":"7222","run_at":"2025-06-11","run_after_sec":300} 9 set_lead_status меняет статус лида phrases 7783 10 add_lead_tags добавляет теги phrases "tag" 11 remove_lead_tags удаляет теги phrases "tag" 12 nlp_detect_intent определяет интент phrases {"text_to_detect":"intent"} 13 run_js_callback делает JS-callback phrases {"prompt":"...","error_message":"...","js_code":"..."} 14 async_api_call async вызов API (например, обращение к LLM) phrases {"js_code":"...","is_immediate_call":1} 15 add_lead_contexts добавляет контекст phrases "context" 16 remove_lead_contexts удаляет контекст phrases "context" 17 forward_to_operator переводит на оператора phrases 7784 18 return_to_bot возвращает в бота phrases 7783 19 repeat_sentence повторяет текущий скрипт phrases {} 20 stop полностью останавливает выполнение phrases {} 21 menu (reference) кнопки меню, переходы, inline actions references caption="Start", jump_sentence_id=85680

      Короткое объяснение логики исполнения команд

        Команды внутри одного скрипта (sentence) выполняются сверху вниз по sort_order.

        Любая команда типа run_sentence или run_js_callback может мгновенно передать управление в другой скрипт.

        Кнопки (references) — это отдельная сущность: они не лежат в phrases, но участвуют в сценарии.

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

        Это идеально идёт сразу после секции со списком 21 команды Metabot.


        🔶 Раздел: «Зачем нам свой конструктор и свои команды»

        (вставь в статью как есть — он написан в том же тоне, что и предыдущие части и красиво связывает контекст)

        После того как мы разобрались, какие команды реально существуют внутри Metabot и посмотрели, как они физически хранятся в базе (sentences, phrases, references), мы можем перейти к ключевой идее нашего урока:

        Мы не будем создавать интерфейс, который один-в-один повторяет Metabot.
        Мы создадим свой собственный визуальный конструктор, и в нём у нас будут свои команды — более удобные, более компактные и намного более выразительные.

        Почему так?


        ## 🧠 Почему в Metabot всё разбито на 21 команду

        (и почему это отлично для движка, но неудобно для дизайнера чат-ботов)

        Metabot — это low-code ядро. Каждая команда — это минимальная атомарная операция:

          отправить текст,

          отправить картинку,

          записать тег,

          выполнить JS,

          перейти в скрипт,

          вызвать LLM,

          записать аналитику,

          дождаться ввода
          и так далее.

          Это правильно для движка:
          движок должен быть предсказуемым и детерминированным.

          Но для человека, который рисует сценарий, это слишком низкий уровень.
          Чтобы собрать один «узел» диалога, дизайнеру нужно вручную собрать:

            1–3 send_text

              условия и JS

                настройки под разные каналы

                  кнопки меню (в references)

                    обработчики кликов (ещё несколько run_sentence + JS)

                      автологирование для аналитики

                        триггеры для отслеживания ссылок

                          переходы к следующему шагу

                          В итоге один визуальный узел превращается в:

                          → 6–12 низкоуровневых фраз в базе

                          → 2–4 скрипта (sentences)

                          → и пачку записей в references

                          Именно поэтому мы не хотим заставлять пользователя руками разбираться в 21 команде ядра. Мы хотим сократить этот слой.


                          🔶 Теперь проектируем наш собственный редактор

                          Мы создаём свою систему узлов — такую, в которой:

                            один узел = одна логическая операция сценария,

                            пользователь видит высокоуровневую настройку,

                            а всё сложное — «распаковывается» автоматически внутрь Metabot при импорте.

                            Это и есть смысл маппера и билдера.


                            ## Какие наши команды мы сделаем первыми

                            Мы начинаем не с копирования полного набора команд Metabot.
                            Мы делаем те команды, которые дают 80% функциональности и 20% сложности.

                            1. Start / Entry Node

                            Стартовый узел воронки.
                            Даёт визуальную точку входа + будущую связь с диплинками.

                            2. Send Text (расширенная)

                            Это не просто send_text из Metabot.
                            Наша версия включает:

                              💬 универсальное сообщение

                              💬 кастомизация под каналы (Telegram, WhatsApp, VK, WebChat)

                              ⚙️ обработку макросов

                              🤖 возможность вставить LLM-подсказки

                              🔘 кнопки со встроенными обработчиками

                              📌 запись в аналитику прямо внутри узла

                              ↪️ переход к следующему шагу

                              🔗 поддержка ссылок (с автогенерацией триггеров)

                              В Metabot для этого потребовалось бы от 6 до 12 низкоуровневых команд.
                              У нас — один визуальный блок.


                              3. Записать в аналитику

                              Метаботовская команда run_javascript + вызов WayLogger.
                              Мы прячем всё JS-пекло от пользователя.

                              В нашем интерфейсе есть:

                                выбор типа логирования: step, event, tag, utter,

                                выбор пути (way),

                                параметры.


                                4. Переход к следующему шагу

                                В Metabot это команда run_sentence.
                                В нашем редакторе — просто стрелка между узлами.


                                5. Обращение к LLM (call_llm)

                                В Metabot — большой JSON с настройками callback.
                                Мы делаем:

                                  выбор модели

                                  выбор агента

                                  system / user prompts

                                  способ отображения ответа

                                  параметры истории

                                  next & error flow

                                  Всё это — внутри одного визуального окна.


                                  6. Поиск по базе знаний (search_knowledgebase)

                                  Точно так же — один узел, один JSON.
                                  А Metabotу при импорте достанется пачка сложных команд и связок.


                                  ## Почему наши команды будут «упакованными»

                                  (концепция compact high-level commands)

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

                                    собираем данные в простой JSON (наш формат),

                                    передаём этот JSON мапперу,

                                    маппер превращает один наш узел в:

                                      1 или несколько sentences

                                      десятки phrases

                                      references

                                      JS-код

                                      триггеры

                                      переходы

                                      аналитику

                                      То есть пользователь видит простую, компактную визуальную воронку, а под капотом:

                                      строится настоящая сложная система Metabot с триггерами, скриптами, условиями, логированием и разветвлёнными сценариями.


                                      ## Пример эффекта (наглядно)

                                      Было бы без нашего редактора 👇

                                      Один узел =
                                      → 3–5 команд отправки сообщений
                                      → 1–3 условия
                                      → 3–10 кнопок (references)
                                      → 1–5 вспомогательных скриптов
                                      → JS обработчики
                                      → триггеры для ссылок
                                      → аналитика как отдельный скрипт
                                      → ручное связывание переходов

                                      С нашим редактором 👇

                                      Один узел =
                                      → 1 блок Send Text с кнопками и аналитикой
                                      → 1 JSON-объект
                                      → 1 клик: «Импорт в Metabot»
                                      → всё остальное сделает маппер и билдер


                                      ## Вводная мысль для перехода к следующей главе

                                      Теперь, когда мы понимаем:

                                        какие команды существуют внутри Metabot,

                                        почему они такие низкоуровневые,

                                        и зачем нам свой набор «уплотнённых» команд,

                                        мы можем перейти к следующему этапу —
                                        спецификации нашего JSON-формата, который и станет языком для визуального конструктора.


                                        Если всё ок, я сделаю следующий раздел:

                                        🔷 «Наш JSON-формат: структура всех типов шагов»

                                        включая:

                                          поля узла,

                                          поля кнопок,

                                          поля аналитики,

                                          поля ссылок,

                                          поля LLM,

                                          и пример полного JSON на 6–8 шагов.

                                          Гони?

                                           

                                          ⚡️ Наш новый формат для No Code редактора

                                          Теперь, когда ты знаешь, какие команды существуют в Metabot и как они хранятся в sentences/phrases/references, мы можем спроектировать наш собственный JSON-формат.

                                          Он не равен командам Metabot —
                                          мы создаём собственную, удобную DSL.

                                          А затем мы создадим маппер, который превращает наш JSON → структуры Metabot.

                                          Простой пример шага:

                                          {
                                            "code": "hello_world",
                                            "type": "send_text",
                                            "name": "Приветствие",
                                            "content": "Привет! Как дела?",
                                            "next_step": "next_message",
                                            "coordinates": { "x": 120, "y": 300 },
                                            "buttons": [
                                              {
                                                "title": "Продолжить",
                                                "value": "go",
                                                "next_step": "continue",
                                                "add_tags": [],
                                                "remove_tags": []
                                              }
                                            ]
                                          }

                                          Важно: наш JSON ≠ команды Metabot

                                          Наша концепция:

                                            Пользователь создаёт узлы (steps).

                                            Наш JSON описывает машину состояний.

                                            На импорте Mapper превращает “steps” → множество “phrases”.

                                            Например:

                                            Наш узел “send_text” превращается в:

                                              1 или несколько команд send_text (для каждого канала)

                                              0–5 команд add/remove tags

                                              0–1 команд run_javascript

                                              0–10 кнопок в таблице references

                                              0–1 переход run_sentence в следующий скрипт

                                              То есть одна наша команда = много внутренних.

                                              Именно поэтому мы делаем свой язык.