Я устал платить $50/мес за Make и написал свою No-Code платформу. Теперь ищу 50 спартанцев для ЗБТ TL;DR для тех, кто спешит Запилил No-Code платформу для автоматизаций (аналог n8n/Make), но с человеческим UI и хранением API-ключей локально в браузере.

TL;DR для тех, кто спешит

Запилил No-Code платформу для автоматизаций (аналог n8n/Make), но с человеческим UI и хранением API-ключей локально в браузере. Ищу 50 Early Adopters для закрытой беты. Lifetime доступ по цене одного месяца Make.

Боль, которая всё началa

Если вы хоть раз настраивали автоматизацию “Telegram-бот → GPT → ответ пользователю”, вы знаете это чувство.

Zapier: $50/месяц за 2000 задач. Серьёзно? Мой бот для заметок столько не стоит.

Make (Integromat): Дешевле, но интерфейс будто делали в 2012 году и забыли обновить. Каждый раз, когда я открываю их редактор, у меня начинается флешбэк войны.

n8n: Self-hosted, бесплатный, мощный. Но давайте честно — чтобы его развернуть, нужен DevOps-скилл или день чтения документации. А UI там как у Jenkins — функционально, но глаза вытекают.

И главное — все они хранят ваши API-ключи у себя. OpenAI, Telegram, Stripe — всё на чужих серверах. Каждый раз, когда я вставляю токен, внутри что-то сжимается.

“А что если сделать своё?”

Классическая ошибка разработчика. “Тут работы на выходные”. Спойлер: прошло несколько месяцев.

Но результат того стоил:

Что получилось:

  • Визуальный редактор на React Flow (да, тот самый, который используют Stripe и Figma для своих flow-диаграмм)
  • Красивый тёмный UI, над которым я реально заморочился
  • API-ключи хранятся в localStorage вашего браузера — они никогда не покидают ваш компьютер
  • Drag & Drop с кастомными “призраками” и поддержкой скринридеров
  • Smart Matching ключей — платформа сама понимает, что “openai” и “llm-openai” это одно и то же

Теперь техническая часть для тех, кто любит код.

Техническое мясо: Smart Matching ключей

Проблема

Представьте: пользователь сохранил ключ с сервисом "openai". А нода в системе имеет ID "llm-openai". Классическое строковое сравнение не найдёт совпадения. Пользователь увидит “Нет сохранённых ключей” и пойдёт писать гневный отзыв.

Это не гипотетическая проблема — я сам на неё напоролся при первом же тесте.

Решение: Система алиасов

Typescript// NodeSettings.tsxconstSERVICE_ALIASES: Record = { 'llm-openai': ['openai', 'gpt', 'chatgpt', 'gpt-4', 'gpt-3.5'], 'llm-deepseek': ['deepseek', 'ds', 'deepseek-chat'], 'telegram': ['tg', 'telegram-bot', 'telegram-api'], 'llm-anthropic': ['anthropic', 'claude', 'claude-3'], 'llm-gemini': ['gemini', 'google-ai', 'bard', 'palm'], // ... и так далее }

Но этого мало. Пользователь мог назвать сервис как угодно. Поэтому добавил функцию, которая генерирует все возможные варианты:

Typescriptconst getServiceAliases = (serviceId: string): string[] => { const normalized = serviceId.toLowerCase() // Ищем в предопределённых алиасах for (const [key, aliases] ofObject.entries(SERVICE_ALIASES)) { if (key === normalized || aliases.includes(normalized)) { return [key, ...aliases] } } // Fallback: генерируем варианты автоматическиreturn [ normalized, normalized.replace(/[-_]/g, ''), // "llm-openai" → "llmopenai" ...normalized.split(/[-_]/) // "llm-openai" → ["llm", "openai"] ] }

Оптимизация для большого количества ключей

Когда у пользователя 5 ключей — можно просто перебрать. Когда 100+ — нужен кэш:

Typescript// Кэш для поиска ключейconst credCache = useRef(newMap()) const getMatchingCredentials = useCallback((blockId: string): Credential[] => { const cacheKey = `${blockId}_${availableCredentials.length}`// Проверка кэшаif (credCache.current.has(cacheKey)) { return credCache.current.get(cacheKey)! } // Для 100+ ключей используем Map вместо полного перебораif (availableCredentials.length > 100) { const serviceMap = newMap() availableCredentials.forEach(c => serviceMap.set(c.service.toLowerCase(), c)) const exactMatch = serviceMap.get(blockId.toLowerCase()) const result = exactMatch ? [exactMatch] : [] credCache.current.set(cacheKey, result) return result } // Полный поиск с алиасами для небольшого количестваconst nodeAliases = getServiceAliases(blockId.toLowerCase()) const result = availableCredentials.filter(cred => { const credServiceId = cred.service.toLowerCase() return nodeAliases.some(alias => { // 1. Точное совпадениеif (credServiceId === alias) returntrue// 2. Вхождение подстрокиif (credServiceId.includes(alias) || alias.includes(credServiceId)) returntrue// 3. Совпадение без разделителейconst normalizedCred = credServiceId.replace(/[-_]/g, '') const normalizedAlias = alias.replace(/[-_]/g, '') if (normalizedCred === normalizedAlias) returntruereturnfalse }) }) credCache.current.set(cacheKey, result) return result }, [availableCredentials])

Результат: пользователь сохраняет ключ как "OpenAI API", а система его находит для ноды "llm-openai". Магия? Нет, просто много if-ов и один вечер дебага.

Техническое мясо: Drag & Drop с человеческим лицом

Проблема стандартного DnD

Дефолтный drag-preview в браузере — это скриншот элемента. Выглядит… ну, вы видели. Полупрозрачная размазня, которая лагает на ретине.

Кастомный “призрак”

Typescript// BlockSidebar.tsxconstonDragStart = (event: React.DragEvent, block: any) => { const e = event asReact.DragEvent e.dataTransfer.setData('application/reactflow', block.id) e.dataTransfer.effectAllowed = 'move'// Создаём кастомный drag-previewconst ghost = document.createElement('div') ghost.style.cssText = ` position: absolute; top: -1000px; background-color: #1e293b; border: 1px solid #3b82f6; color: white; padding: 8px 12px; border-radius: 8px; font-weight: bold; font-size: 12px; z-index: 1000; ` ghost.innerText = block.namedocument.body.appendChild(ghost) e.dataTransfer.setDragImage(ghost, 0, 0) // Убираем после начала dragsetTimeout(() =>document.body.removeChild(ghost), 0) }

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

A11y: Потому что не все используют мышь

Честно? Я не думал про accessibility до тех пор, пока не спросил совета у DeepSeek. Он накидал список из 10 пунктов. Вот что внедрил:

Tsx// Категории с ARIA-атрибутами toggleCategory(catKey)} aria-expanded={isOpen} aria-controls={`category-${catKey}`} className="... focus:outline-none focus:bg-slate-800" > // Блоки с поддержкой клавиатурной навигации

Теперь можно полностью управлять сайдбаром с клавиатуры: Tab для навигации, Enter для раскрытия категорий. Скринридеры корректно озвучивают состояние (“развёрнуто” / “свёрнуто”).

CSS-трюк для плавного сворачивания

Обычно для анимации высоты используют max-height: 9999px. Работает, но transition длится вечность или дёргается. Вот что предложил DeepSeek:

Typescript

{/* контент */}

Grid-трюк! Анимируем grid-template-rows вместо height. Работает плавно независимо от количества контента.

Безопасность: Ключи никуда не уходят

Это главная фишка, и она до смешного простая:

Typescript// Загрузка ключейuseEffect(() => { constloadCreds = () => { const saved = localStorage.getItem('flowx_credentials') if (saved) { setAvailableCredentials(JSON.parse(saved)) } } loadCreds() window.addEventListener('storage', loadCreds) // Синхронизация между вкладкамиreturn() =>window.removeEventListener('storage', loadCreds) }, [])

Как это работает:

  1. Вы добавляете API-ключ через интерфейс
  2. Он сохраняется в localStorage вашего браузера
  3. При выполнении workflow ключ подставляется на клиенте
  4. Мой сервер видит только ID ключа, но не сам ключ

Структура хранения:

Json{"id":"cred_abc123","name":"Мой OpenAI ключ","service":"openai","key":"sk-...","created":"2024-01-15T10:30:00Z"}

Да, это значит что при очистке браузера ключи пропадут. Поэтому есть экспорт/импорт конфигурации. Trade-off между удобством и безопасностью — я выбрал безопасность.

Как это работает: Пример сценария

Задача: Telegram-бот, который отвечает на сообщения через GPT.

  1. Триггер: Telegram Webhook — ловит входящие сообщения
  2. Нода: OpenAI — отправляет текст сообщения, получает ответ
  3. Нода: Telegram Send — отправляет ответ пользователю

Настройка занимает ~3 минуты:

  • Перетащил 3 блока
  • Соединил стрелками
  • Вставил токены (которые остались в моём браузере)
  • Нажал “Deploy”

Такой сценарий на Make стоит примерно $20/месяц при активном использовании. У меня — входит в базовый тариф.

Что сейчас готово (честно)

✅ Работает:

  • Визуальный редактор с 30+ блоками
  • Интеграции: OpenAI, Claude, Gemini, DeepSeek, Telegram, VK, HTTP/Webhook, Т-Банк
  • Система хранения ключей в localStorage
  • Валидация JSON-полей в реальном времени
  • Debounced автосохранение (не теряем настройки)
  • Тёмная тема (светлую не планирую, извините)

⚠ В процессе:

  • Логи выполнения с человеческим интерфейсом
  • Шедулер (запуск по расписанию)
  • Версионирование workflow

❌ Пока нет:

  • Мобильная версия (desktop-first)
  • 500+ интеграций как у Zapier (но они будут)
  • Self-hosted версия (может быть позже)

Оффер: Закрытый бета-тест

Теперь честная часть.

Денег на рекламу нет. Серверы стоят денег. Я один разработчик (ну, почти — DeepSeek, Gemini 3 Pro и Claude Opus 4.5 помогают код ревьюить).

Поэтому ищу 50 спартанцев — людей, готовых:

  • Потыкать сырой продукт
  • Написать “тут сломалось” когда сломается
  • Предложить “а прикольно было бы если…”

Что получаете взамен:

🎁 Lifetime Deal — вечный доступ к платформе по цене одного месяца Make (~$15-20). Навсегда. Без подписок, без ежемесячных списаний.

🎁 Early Adopter статус — ваши пожелания в приоритете. Нужна интеграция с Notion? Голосуете первыми.

🎁 Место в “стене славы” — когда взлетим (если взлетим), вы будете в списке тех, кто поверил первым.

Для кого это

✅ Подойдёт:

  • Инди-хакерам, которые собирают MVP
  • Фрилансерам, которые автоматизируют рутину клиентам
  • Малому бизнесу, который хочет бота без найма разработчика
  • Тем, кто устал платить $50/мес за простую автоматизацию

❌ Не подойдёт:

  • Enterprise с требованиями SOC2 и 99.99% uptime
  • Тем, кому нужно 500 интеграций прямо сейчас
  • Любителям светлых тем (sorry)

Что дальше:

Телеграмм - @koteikin96

Если есть вопросы по технической части — спрашивайте в комментариях. Расскажу про Zustand-стор, React Flow кастомизацию, или как я третий раз переписывал систему валидации.

P.S. Если вы дочитали до сюда и не заснули на блоке кода с grid-template-rows — вы точно мой целевой пользователь.

Вопросы, которые вы возможно хотите задать:

Q: Почему не open-source? A: Пока нет. Когда проект взлетит — возможно, открою core. Сейчас нужно понять, есть ли вообще спрос.

Q: А оно не упадёт через месяц? A: Честный ответ: не знаю. Но Lifetime-деньги пойдут на серверы минимум на год вперёд. Плюс я сам этим пользуюсь для своих проектов.

Q: Можно посмотреть демо перед покупкой? A: Да, будет демо-режим с ограниченным функционалом. Но Early Adopters получают полный доступ сразу.

Начать дискуссию