Я устал платить $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) }, [])
Как это работает:
- Вы добавляете API-ключ через интерфейс
- Он сохраняется в localStorage вашего браузера
- При выполнении workflow ключ подставляется на клиенте
- Мой сервер видит только ID ключа, но не сам ключ
Структура хранения:
Json{"id":"cred_abc123","name":"Мой OpenAI ключ","service":"openai","key":"sk-...","created":"2024-01-15T10:30:00Z"}
Да, это значит что при очистке браузера ключи пропадут. Поэтому есть экспорт/импорт конфигурации. Trade-off между удобством и безопасностью — я выбрал безопасность.
Как это работает: Пример сценария
Задача: Telegram-бот, который отвечает на сообщения через GPT.
- Триггер: Telegram Webhook — ловит входящие сообщения
- Нода: OpenAI — отправляет текст сообщения, получает ответ
- Нода: 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 получают полный доступ сразу.