Лендинг, который работает вместо менеджера: itc34.ru
Кейс корпоративного сайта IT-компании: калькулятор цены без звонка, лид‑магнит на страхе штрафа, голосовой AI-консультант, квиз‑бот с PDF-аудитом и вся воронка в одном Telegram-треде. Один HTML-файл без сборки, Three.js на скролле, два бренда из одного кода.
Сайт есть, а заявок нет
Знакомая для многих компаний ситуация: сайт вроде бы работает, но по сути это визитка. Он рассказывает, чем занимается компания, показывает логотип и телефон — и на этом всё. Посетитель заходит, читает, не находит цены, не понимает, с чего начать разговор, и уходит. Ни звонка, ни заявки. Сайт есть, а продаж от него нет. Это одна из типовых дыр, через которые утекают заявки, — и, как правило, не единственная.
Именно с этим пришла компания «ИТ Консалтинг» из Волгограда — IT-аутсорсинг с 200+ клиентами и историей с 2012 года. Формулировка задачи была короткой и честной: «Нужен сайт, который работает круглосуточно вместо менеджера».
Из этой фразы выросли четыре требования, и каждое из них — про боль реального бизнеса:
- Посетитель должен сам увидеть цену — без «оставьте заявку, мы перезвоним». Большинство холодных клиентов уходят именно на этом шаге.
- Заявка должна доходить до менеджера мгновенно, куда бы он ни смотрел. У этой команды рабочий инструмент — Telegram.
- Нужен вход для холодного трафика: что‑то бесплатное, ценное и мгновенное, ради чего человек оставит контакт.
- Сайт должен выглядеть дорого. Клиенты компании — производство и ретейл, а не стартапы, и доверие здесь считывается в том числе через оформление.

Проект получился заметно больше, чем классический лендинг: восемь итераций с марта по май 2026, а на выходе — сайт, голосовой консультант, квиз‑бот с юридическим аудитом, отдельная инфраструктура для видеотрансляции и презентация для встреч. Ниже разбираю всё это по слоям — от архитектурного решения до честного раздела «что бы я сделал иначе».
Идея: четыре входа в одну воронку
Мы не стали делать один сценарий «прочитал — оставил заявку». Вместо этого на лендинге появилось четыре независимых входа, рассчитанных на разные типы посетителей: тот, кому нужна цена; тот, кто готов заполнить форму; тот, кто хочет просто поговорить; и тот, кто ещё ничего не решил, но боится проблем со своим сайтом.
Все четыре входа сходятся в одной точке — рабочей группе Telegram, где менеджер отвечает, не переключая приложение.
flowchart TB
V["Посетитель"] --> L["itc34.ru<br/>лендинг"]
L --> C["Калькулятор<br/>цена за 1 минуту"]
L --> F["Формы<br/>заявки"]
L --> AI["AI-консультант<br/>текст + голос"]
L --> A["Лид-магнит<br/>аудит сайта"]
C --> F
AI --> TG
A --> BOT["Бот-аудитор<br/>квиз из 5 вопросов"]
F --> TG["Telegram<br/>рабочая группа"]
BOT --> PDF["PDF-отчёт<br/>с оценкой и рисками"]
PDF --> TG
TG --> M["Менеджер<br/>звонит"]
style AI fill:#7c3aed,color:#fff
style BOT fill:#0ea5e9,color:#fff
style TG fill:#22c55e,color:#fff
style M fill:#f59e0b,color:#fff
Дальше разберу каждый вход по отдельности — что за решение, зачем оно и что дало.
Один HTML-файл без единой сборки
Начну с фундамента, потому что он определил всё остальное. Сайт — это один index.html на 4272 строки. Внутри — весь CSS, весь JavaScript, все данные. Никакого npm install, никакого шага сборки, никакого CI. Деплой выглядит так:
scp index.html root@server:/var/www/itc34/
Это не лень, а осознанный инженерный выбор. Лендинг живёт годами и правится редко — поменять цену в тарифе или добавить кейс. Сборка означала бы, что через год никто не вспомнит, какая версия Node нужна, чтобы что‑то поправить, и любая мелкая правка превращалась бы в археологию окружения. Здесь же цену в тарифе поправит любой человек, открыв файл в блокноте, — и сразу отправит одним scp. Через десять лет этот файл откроется в браузере ровно так же, как сегодня.
За такое решение приходится платить, и честнее проговорить это прямо: данные дублируются. Контент лежит и в JSON-файлах (services.json, cases.json, reviews.json, faq.json, clients.json), и в JS-константах внутри самого HTML. Причина конкретная: fetch() не работает по протоколу file:// — а сайт должен открываться двойным кликом с флешки, когда менеджер показывает его на встрече без интернета. Чтобы страница жила и на боевом домене, и локально с USB-носителя, данные пришлось держать в двух местах. Это компромисс, к которому я ещё вернусь в разделе про ошибки — но родился он не случайно.
Three.js, который реагирует на скролл
Ощущение «дорогого» сайта начинается с первого кадра, ещё до того, как посетитель прочитал заголовок. Поэтому фон здесь живой: частицы и wireframe-фигура на Three.js. Но не просто крутятся — фигура морфируется по мере прокрутки, синхронно с разделами страницы.
flowchart LR
A["Икосаэдр<br/>hero"] --> B["Октаэдр<br/>услуги"]
B --> C["Тор<br/>кейсы"]
C --> D["Сфера<br/>контакты"]
style A fill:#7c3aed,color:#fff
style B fill:#8b5cf6,color:#fff
style C fill:#0ea5e9,color:#fff
style D fill:#22c55e,color:#fff
Человек скроллит вниз — и геометрия на заднем плане плавно перетекает из одной формы в другую. Это подсознательно связывает движение по странице с движением сцены и держит внимание.
Отдельная деталь — прелоадер. Тянуть 600 КБ Three.js до первого кадра ради заставки было бы расточительно, поэтому на время загрузки крутится собственная wireframe-фигура на чистом Canvas 2D, без единой внешней библиотеки.

Когда прогресс доходит до 100%, прелоадер уезжает вверх и запускает две анимации сразу: шапка выпадает сверху, а слова заголовка проявляются по очереди. Обе анимации заранее поставлены на паузу через animation-play-state: paused и стартуют только по классу body.page-ready. Это гарантирует, что пользователь никогда не увидит «уже отыгравшую» сцену — а именно такие мелочи отличают дорогой сайт от собранного на коленке.
Калькулятор до формы, а не после
Главный барьер холодного клиента — вопрос «а сколько это вообще стоит?». Классический ответ «оставьте заявку, мы рассчитаем» теряет большинство: человек ещё не готов отдавать контакт ради непонятной суммы.
Поэтому калькулятор стоит одной из первых секций и считает цену прямо на слайдерах. Двигаете количество компьютеров и серверов, отмечаете дополнительные услуги — и видите итоговую сумму в реальном времени, без единого клика по кнопке отправки.

Отдельная деталь — название кнопки. Она называется не «Отправить», а «Зафиксировать цену». Это меняет психологию действия: абстрактный расчёт превращается в маленькое обязательство, которое проще довести до заявки.
Лид‑магнит, который бьёт в конкретный страх
Самая конверсионная секция сайта — не услуги и не кейсы. Это чеклист аудита сайта, который бьёт в один очень конкретный страх бизнеса: штраф Роскомнадзора до 500 000 ₽ за нарушение ФЗ-152. Про то, как устроен автоматический аудит сайта изнутри, я подробно писал в отдельном разборе.

Пункты разбиты на категории: «Закон», «Безопасность», «Скорость», «SEO». Самые опасные — политика конфиденциальности, согласие на обработку персональных данных, уведомление о cookies, хранение данных на серверах РФ — помечены красной меткой «штраф». Человек видит список того, что у него, скорее всего, не в порядке, — и хочет проверить.
Но самое дорогое — не то, о чём обычно думают. Политика конфиденциальности и cookies стоят до 500 000 ₽ по ФЗ-152, а рядом лежат две вещи страшнее: иконка Instagram в подвале сайта — это уже символика Meta* и статья КоАП вплоть до ареста, а форма обратной связи на иностранном сервисе — передача персональных данных за рубеж со штрафом до 6 000 000 ₽. Подробную таблицу статей и наказаний я разбираю ниже, в блоке про квиз‑бота — именно он всё это проверяет.
Проверка происходит не на сайте, а в Telegram-боте: пользователь отвечает на пять вопросов кнопками, оставляет адрес сайта — и получает персональный разбор. Так холодный посетитель без единого звонка превращается в контакт менеджера.
AI-консультант, который ведёт по скрипту продаж
В правом нижнем углу — виджет AI-консультанта. У него два режима: текстовый чат и голосовой диалог. Это не «спросите что угодно» — за виджетом стоит проработанный сценарий продаж.

Консультант работает на современных AI-моделях: одна отвечает в текстовом чате, вторая — в голосовом режиме, с живым синтезом речи. Но задача у него сугубо прикладная: понять, с чем пришёл человек, и мягко довести его до следующего шага. Системный промпт — это не «дружелюбный ассистент», а скрипт продаж с жёсткой воронкой.
flowchart TD
S["Приветствие:<br/>какой IT-вопрос актуален?"] --> Q{"О чём речь?"}
Q -->|"Проблемы с сайтом,<br/>штрафы"| AU["Предложить<br/>аудит сайта"]
Q -->|"Хочет создать<br/>сайт"| WEB["Веб-разработка<br/>→ собрать заявку"]
Q -->|"Серверы, 1С,<br/>сети, безопасность"| INF["Аудит<br/>инфраструктуры"]
AU --> CASE["Привести кейс,<br/>похожий на ситуацию"]
WEB --> CASE
INF --> CASE
CASE --> NEXT{"Следующий шаг"}
NEXT -->|"Согласие<br/>на аудит"| RA["Открыть форму<br/>аудита"]
NEXT -->|"Хочет<br/>консультацию"| SL["Имя → телефон → услуга<br/>→ подтверждение<br/>→ заявка"]
RA --> BOT["Telegram-бот"]
SL --> TG["Telegram-группа"]
style RA fill:#0ea5e9,color:#fff
style SL fill:#22c55e,color:#fff
Самое интересное здесь — правила, которые появились не на бумаге, а после наблюдения за живыми диалогами:
- Не предлагать аудит тому, кто хочет создать сайт с нуля. У него ещё нет сайта — аудировать нечего. Модель регулярно наступала на эти грабли, пока правило не прописали явно.
- Говорить «назовите», а не «введите». Тот же сценарий обслуживает и голосовой режим, где «введите телефон» звучит абсурдно.
- Не называть вслух никакие ссылки и имена ботов. Вместо этого консультант сам открывает нужную форму, а вслух говорит «Открываю форму». Продиктованная в голосовом режиме ссылка — почти гарантированная потеря клиента.
- Обязательное подтверждение перед отправкой заявки. Прежде чем отправить контакт менеджеру, консультант зачитывает имя, телефон и услугу и ждёт «да». Без этого в Telegram сыпался мусор с распознавания речи.
Заявка от консультанта уходит тем же путём, что и обычные формы, но с пометкой «от AI-консультанта» и отдельной целью в Метрике — так видно, сколько лидов приносит именно этот канал, отдельно для текста и отдельно для голоса.
Прокси, который прячет ключ и заодно решает доступность
Первая версия виджета звала AI-модель напрямую из браузера. Это значит, что ключ доступа лежал в клиентском JavaScript и был виден любому, кто откроет DevTools. Для боевого сайта это неприемлемо: чужим ключом можно пользоваться бесплатно за ваш счёт.
Решение — прокси на собственном сервере. Все запросы идут через него, и ключ подставляется уже на сервере, не покидая его.
sequenceDiagram
participant B as Браузер
participant N as nginx<br/>itc34.ru
participant P as gemini-proxy<br/>:3001
participant G as AI-модель<br/>(облако)
B->>N: wss://itc34.ru/ws-gemini
N->>P: proxy_pass
Note over P: Проверка Origin<br/>по белому списку
P->>G: wss + ключ
G-->>P: аудио-поток
P-->>N: аудио-поток
N-->>B: аудио-поток
Note over B,P: Ключ никогда не покидает сервер
Небольшой Node-скрипт под PM2 проксирует и WebSocket для голосового потока, и HTTP для текстового чата. Ключ подставляется на сервере, а заголовок Origin фильтруется по белому списку — чужой сайт не сможет проксировать запросы через наш сервер и жечь наш лимит.
Побочный бонус оказался не менее ценным, чем сама безопасность: сервер стоит в Европе, и это заодно сняло вопрос стабильной доступности AI-модели из России. Один архитектурный ход закрыл сразу две задачи — защиту ключа и надёжный доступ к модели.
Кейсы с цифрами, а не с «повысили эффективность»
Раздел реализованных проектов сделан по одному принципу: никаких общих слов. Каждый кейс — с конкретным результатом.

«В понедельник в 8:00 все сотрудники приступили к работе, простоев — 0 часов». «Скорость обмена данными выросла на 40%». «45% клиентов перешли на самообслуживание, нагрузка на колл‑центр упала на 30%». Такие формулировки работают на доверие гораздо сильнее, чем абстрактное «повысили эффективность».
Telegram как бесплатная CRM
У компании нет CRM — и она ей не нужна. Вся воронка живёт в одной рабочей группе Telegram, и это осознанное решение, а не компромисс. Тот же принцип — «мессенджер как рабочий стол команды» — мы разбирали в кейсе про мост между MAX и Telegram: все каналы сходятся в одно окно, а не размазываются по трём приложениям.
flowchart LR
subgraph Источники
F1["Модальная<br/>форма"]
F2["Форма<br/>в услуге"]
F3["Форма<br/>в футере"]
AI["AI-консультант"]
Q["Квиз-бот"]
end
F1 & F2 & F3 & AI --> S["Отправка в Telegram<br/>+ IP, ОС, устройство, UTM"]
S --> G["Рабочая группа · общий тред"]
Q --> T["Отдельный тред<br/>на каждого клиента"]
T --> G
G --> M["Менеджер отвечает<br/>прямо из треда"]
M -.->|"ответ уходит<br/>от имени бота"| Q
style G fill:#22c55e,color:#fff
style M fill:#f59e0b,color:#fff
Каждая форма и каждая заявка от AI-консультанта уходит в группу вместе с контекстом: IP (определяется по внешнему сервису), операционная система, устройство, UTM-метки из ссылки. Менеджер сразу видит, откуда пришёл человек и по какому объявлению, — ещё до первого звонка.
Квиз‑бот идёт ещё дальше: на каждого нового клиента он автоматически создаёт отдельную тему в супергруппе и дублирует туда всю переписку. Менеджер отвечает прямо из этой темы — клиенту ответ приходит как будто от бота. При повторном обращении тема находится по идентификатору пользователя, и вся история сохраняется. По сути это и есть логика CRM — карточка клиента и вся история в одном месте — только без внедрения, подписки и обучения команды.
Квиз‑бот с PDF-отчётом: главный лид‑магнит
Бот‑аудитор начинался как лид‑магнит для этого лендинга, а вырос в самостоятельный продукт. Это отдельный сервис на Python (aiogram), запущенный под systemd, — и именно он делает всю тяжёлую работу воронки.
Логика от «/start» до готового PDF выглядит так:
flowchart TD
S["/start audit"] --> Q1["5 вопросов<br/>кнопками"]
Q1 --> T{"Тип сайта?"}
T -->|"Пока нет сайта"| CONS["Консультация<br/>через топик"]
T -->|"Есть сайт"| URL["Адрес сайта"]
URL --> PH["Телефон<br/>одной кнопкой"]
PH --> PRE["Мгновенно:<br/>уровень риска штрафа"]
PRE --> QU["Очередь в SQLite<br/>audit_queue"]
QU --> W{"Рабочее время<br/>9:00–20:00 МСК?"}
W -->|"нет"| WAIT["Ждём до утра"] --> GEN
W -->|"да"| GEN
GEN["Обработчик аудита"] --> SH["Скриншот сайта"]
GEN --> PARSE["Прямой разбор HTML:<br/>символика Meta*, трекеры,<br/>формы с ПДн"]
GEN --> LLM["AI-модель:<br/>остальные пункты"]
GEN --> MK["Маркетинговый<br/>аудит лендинга"]
SH & PARSE & LLM & MK --> PDF["PDF · 6 страниц"]
PDF --> C["Клиенту в чат"]
PDF --> MGR["Менеджеру в тред"]
style PDF fill:#7c3aed,color:#fff
style PARSE fill:#ef4444,color:#fff
style C fill:#0ea5e9,color:#fff
style MGR fill:#22c55e,color:#fff
Три инженерных решения в этом боте стоят отдельного слова.
Не всё отдано модели. Самые дорогие для клиента нарушения проверяются не AI-моделью, а прямым разбором HTML — там, где нужен точный, а не вероятностный ответ. AI-модель отлично формулирует «скорее всего, у вас проблема с политикой конфиденциальности», но для юридических рисков «скорее всего» не годится: слишком высокая цена ошибки. Поэтому символику, трекеры и формы, отправляющие данные за рубеж, бот ищет в коде страницы напрямую, детерминированно. Вот что и по какой статье он проверяет:
| Статья | Что проверяем | Наказание |
|---|---|---|
| ч. 1 ст. 20.3 КоАП | Символика Meta* (иконки Facebook, Instagram, WhatsApp) | арест до 15 суток |
| ФЗ №41 | Передача персональных данных на иностранные сервисы | до 6 000 000 ₽ |
| 152-ФЗ | Политика, согласие на обработку ПДн, cookies | до 500 000 ₽ |
| 149-ФЗ | Ссылки на заблокированные ресурсы | проверка РКН |
| 436-ФЗ | Возрастная маркировка | до 200 000 ₽ |
Эти пять строк — и есть тот страх, на котором держится весь лид‑магнит. Владелец сайта чаще всего понятия не имеет, что иконка соцсети в подвале или форма на иностранном движке может стоить ему миллионов.
Очередь переживает перезапуск. Задачи на аудит хранятся не в памяти процесса, а в таблице SQLite. Первая версия теряла отчёт, если бота передеплоили в неудачный момент — клиент ждал PDF, которого уже никто не собирался готовить. Теперь после рестарта обработчик просто берёт незавершённые задачи из базы и доводит их до конца. Клиент не замечает, что бота вообще перезапускали.
Отчёт не приходит мгновенно. Между квизом и готовым PDF проходит около получаса, а вне окна 9:00–20:00 по Москве отправка откладывается до утра. Это не техническое ограничение, а психология: отчёт, пришедший через полчаса, читается как работа человека, который сел и разобрал ваш сайт. Пришедший через две секунды — как автоответчик, которому грош цена. Пока идёт ожидание, бот отправляет презентацию и анимацию — паузу нужно чем‑то заполнить, чтобы клиент не решил, что о нём забыли.
Итоговый PDF получился на шесть страниц: обложка со скриншотом сайта и общей оценкой, карта рисков по всем пунктам, блок юридических угроз, маркетинговый разбор лендинга по методике StoryBrand (только для лендингов и промо‑сайтов), персональное коммерческое предложение и призыв к действию. Клиент получает документ, который не стыдно распечатать и положить руководителю на стол.
Два бренда из одного кода
Тот же движок бота сегодня обслуживает два бренда и двух заказчиков. @itc34audit_bot собирает лиды для «ИТ Консалтинг». @WebAuditRuBot — независимый сервис аудита сайтов, где владелец продукта юрист, а не IT-компания. Разные заказчики, разные группы, разный призыв к действию — но одна кодовая база.
Разделение получилось почти бесплатным, потому что всё, что отличает инсталляции, вынесено в .env: своя рабочая группа, свои админы, свой CTA, свой домен. В коде нет ни одной ветки вида «если это WebAudit — веди себя иначе». Один main.py, две независимые установки, которые не знают друг о друге.
Продукт прошёл три поколения кода, и таблица хорошо показывает, как лид‑магнит превращался в самостоятельный сервис:
| Поколение | Что изменилось |
|---|---|
itc34audit-bot |
24 пункта чеклиста, весь анализ через AI-модель, состояние диалога в SQLite |
WebAuditRuBot |
32 пункта, прямой разбор HTML для юридических рисков, собственный бренд |
itc34quiz |
Очередь аудитов в SQLite, маркетинговый аудит по StoryBrand, PDF на 6 страниц |
Чеклист за это время вырос с 24 до 32 пунктов в четырёх категориях: Закон (14), Безопасность (6), Скорость (6), SEO (6). Актуальное поколение открыто — код лежит на GitHub: github.com/ircitdev/itc34quiz.
Ещё несколько экранов
Ощущение солидного сайта складывается из деталей, которые по отдельности незаметны, а вместе создают тот самый эффект «выглядит дорого».
Тёмная и светлая темы — обе полноценные, не «инверсия по остаточному принципу». Весь цвет живёт в CSS-переменных, переключение — одним классом на корне документа, а по умолчанию берётся системная тема пользователя.

Услуги открываются боковой панелью с составом, тарифами и формой прямо внутри — без ухода со страницы:

Секция сравнения тарифов построена на трёхколоночном CSS Grid без display: contents — с ним таблица разъезжалась в Safari, и пришлось собирать сетку явными колонками:

И главное — мобильная версия сделана не по остаточному принципу, а в первую очередь: на неё приходится около 70% трафика.

Инфраструктура сверх задачи: трансляция суда
Отдельная история, которая выросла из просьбы клиента и хорошо показывает, что «сделать сайт» иногда означает совсем не сайт. Нужно было вывести в VK-группу прямую трансляцию с камеры Светлоярского районного суда.
Проблема оказалась чисто сетевой: у камеры (Hisilicon) наружу проброшены служебные порты, но не 554 — то есть RTSP-поток снаружи недоступен. Зато камера прекрасно видна изнутри VPN. Пришлось строить цепочку из туннеля и перекодирования:
flowchart TB
CAM["Камера 192.168.1.10:554<br/>HEVC · внутри VPN"]
CAM -->|"VPN"| TB["Промежуточный сервер"]
TB -->|"SSH reverse tunnel<br/>autossh · systemd"| PR["Боевой сервер<br/>127.0.0.1:5554"]
PR --> FF["ffmpeg по запросу<br/>HEVC → H.264 baseline"]
FF --> MM["MediaMTX<br/>HLS"]
MM --> NG["nginx"]
NG --> HLS["itc34.ru/cam/…<br/>index.m3u8"]
HLS --> HJS["hls.js → браузер → VK"]
style CAM fill:#ef4444,color:#fff
style PR fill:#7c3aed,color:#fff
style HJS fill:#22c55e,color:#fff
Несколько находок, которые стоили отдельного времени:
- RTSP-путь камеры пришлось выяснять через ONVIF. Он оказался нетривиальным, с динамическим токеном вместо простого пароля. По очевидным путям (
/0,/1,/h264) камера всегда отдаёт главный поток в высоком разрешении — а для лёгкого substream нужен полный, «хитрый» URL, который так просто не угадать. - Перекодирование HEVC → H.264 включается только по запросу и гаснет через 15 секунд после ухода последнего зрителя. Браузеры не умеют играть HEVC-поток напрямую, поэтому его приходится конвертировать в H.264 — но делать это круглосуточно ради пустого эфира было бы бессмысленным сжиганием процессора.
- Туннель держит
autosshпод systemd. Камера в чужой сети, разрывы связи неизбежны, и туннель должен подниматься сам, без ручного вмешательства.
К сайту это отношения не имеет, но к отношениям с клиентом — самое прямое. Когда команда решает не «свою» задачу, а реальную проблему заказчика, это и есть то, за что возвращаются.
Материалы, которые не видит клиент, но которые продают
Отдельно собрали три страницы для отдела продаж — они не индексируются и живут только для менеджеров.
| Страница | Что это |
|---|---|
| Питч‑дек | Презентация компании на одной альбомной странице A4 с кнопкой «Сохранить PDF» |
| Коммерческое предложение | Три страницы A4, персонализируется под клиента правкой одного блока данных |
| Страница‑хаб | Клиенту уходит одна ссылка, внутри — предпросмотр всех материалов сразу |

Коммерческое предложение устроено так, чтобы менеджер не собирал документ заново под каждого клиента: весь текст берётся из одного объекта с данными, и персонализация сводится к правке нескольких полей.

А страница‑хаб решает проблему «менеджер отправил клиенту пять ссылок, клиент открыл одну»: клиенту уходит одна ссылка, а внутри — предпросмотр всех материалов сразу, через встроенные окна.

Презентация: офлайн‑вход в ту же воронку
Ко всему цифровому контуру прилагается PowerPoint-презентация на 8 слайдов — то, что менеджер показывает на живой встрече и оставляет клиенту. И это не «слайды про компанию», а продолжение той же воронки, только для офлайна.

Презентация построена не как рассказ о себе, а как продажа одного действия — бесплатного аудита. Первый слайд задаёт не вопрос «кто мы такие», а «Сколько денег вы теряете из‑за IT прямо сейчас?». Дальше идёт классическая продающая связка:
flowchart LR
S1["Сколько денег<br/>вы теряете?"] --> S2["Проблема в том,<br/>что это не видно"]
S2 --> S3["Решение —<br/>ИТ Консалтинг"]
S3 --> S4["Что вы получите<br/>после аудита"]
S4 --> S5["90% компаний<br/>переплачивают за IT"]
S5 --> S6["Каждый день без<br/>аудита = потери"]
S6 --> QR["QR-код<br/>в Telegram-бот"]
style S1 fill:#1e40af,color:#fff
style S5 fill:#1e40af,color:#fff
style QR fill:#22c55e,color:#fff
Боль → невидимость боли → решение → выгода → срочность. Числа не абстрактные: средняя переплата 15–40% бюджета на IT и три конкретных источника потерь — лишние подписки, устаревшее железо, оплата времени подрядчика вместо результата.
Главное — последний слайд.

QR-код ведёт в тот же самый Telegram-бот, куда ведут кнопка на лендинге и AI-консультант. Встреча заканчивается не обещанием «пришлём КП», а телефоном клиента, который он сам ввёл в квизе, пока менеджер собирал ноутбук.
В этом и весь смысл конструкции: четыре разных входа — поиск, реклама, живая встреча, холодный звонок — и один выход. Тред в Telegram, где лежит PDF-отчёт и номер телефона.
Стек
Для тех, кому интересна техническая сторона, — из чего это собрано:
| Слой | Технологии |
|---|---|
| Фронтенд | Vanilla JS, Tailwind (CDN), Three.js, Canvas 2D |
| AI | AI-модель для текста и голоса, function calling |
| Прокси | Node.js, WebSocket, PM2 |
| Бот | Python, aiogram, SQLite, headless-браузер для скриншотов, генерация PDF |
| Стриминг | MediaMTX, ffmpeg, autossh, hls.js |
| Инфраструктура | nginx, Let’s Encrypt, systemd |
| Аналитика | Яндекс.Метрика — 8 настроенных целей |
Ключевое здесь — на фронтенде в проде нет ни одной собственной зависимости и ни одного шага сборки. Вся тяжёлая логика вынесена на сервер, а сам сайт остаётся одним файлом, который откроется где угодно.
Что бы я сделал иначе
Хороший кейс честен не только про удачи, но и про ошибки. Ниже — то, что я разобрал уже после первой версии этого проекта.
Дублирование данных JSON ↔ JS-константы. Требование file:// было настоящим — сайт правда должен открываться с флешки без интернета. Но решать это простой копипастой контента в два места плохо: рано или поздно данные разъедутся, и на боевом сайте окажется одна цена, а в офлайн‑версии другая. Правильнее было бы генерировать блок JS-констант скриптом при деплое: один источник правды в JSON, автоматическая сборка констант — и по‑прежнему ноль зависимостей на клиенте.
API-ключ AI-модели попал в git-историю. Прокси спрятал ключ от браузера, но сам ключ какое‑то время лежал прямо в коде прокси и в коде бота — и, разумеется, попал в историю git. Классическая ловушка: .gitignore добавили после первого коммита, а он не действует задним числом. Разбор занял отдельный вечер:
- ключи вынесены в
.envс правами600, в репозитории остался только.env.example; - боевой ключ ограничен в облачной консоли по IP сервера — украденный, он теперь отдаёт
403с любого другого адреса. Проверено вручную: с моей машины403, с боевого сервера200; - старые ключи из истории отозваны и больше не работают;
- при уборке в папке обработчиков нашлись пять копий корневых модулей, которые никто не импортировал, и в одной из них прятался второй захардкоженный ключ. Всё удалено — минус больше тысячи строк мёртвого кода.
Опасные дефолты в конфиге. В файле конфигурации стояли значения по умолчанию для идентификатора рабочей группы и списка админов. Это значит, что бот, задеплоенный на новый сервер без .env, молча слал бы чужие лиды в старую группу — и никто бы не заметил, пока не хватились бы заявок. Теперь без переменных окружения бот падает на старте с внятной ошибкой. Упасть громко лучше, чем тихо работать «куда‑то не туда».
Тесты промпта. Каждое правило в системном промпте AI-консультанта появилось после того, как модель ошиблась на живом клиенте. Набор из пары десятков сценариев с проверкой, вызвался ли нужный инструмент и не предложил ли консультант аудит тому, у кого сайта ещё нет, сэкономил бы несколько таких клиентов. Промпт — это тоже код, и он тоже заслуживает тестов.
Ни одна из этих вещей не была катастрофой, и все они уже исправлены. Но вместе они — хорошая иллюстрация того, что зрелость проекта измеряется не только тем, что работает, а тем, насколько честно разобраны его слабые места.
Что в итоге
Сайт делает ровно то, ради чего его заказывали. Он показывает цену без звонка, ловит холодный трафик через страх штрафа, разговаривает голосом и по тексту, ведёт диалог по скрипту продаж, присылает шестистраничный PDF с юридическим разбором сайта — и складывает все заявки в один Telegram-тред, откуда менеджер отвечает, не переключая приложение.
Четыре разных входа для разных людей, одна точка сборки. Именно так «сайт‑визитка» превращается в «сайт, который работает вместо менеджера».
И всё это — без единой собственной зависимости на фронтенде и без шага сборки. Через год цену в тарифе поправит любой человек, открыв файл в блокноте и отправив его одной командой.
Главная мысль этого кейса шире одного проекта: сайт продаёт не тогда, когда красиво рассказывает о компании, а когда снимает барьеры один за другим — показывает цену, даёт мгновенную пользу, отвечает на вопрос в ту же секунду и не заставляет клиента ждать перезвона.
Посмотреть вживую
Перейти на сайтitc34.ru Телеграм‑бот@itc34audit_bot Исходники на GitHubITC-2026-LandingСледующий шаг: хотите лендинг, который работает вместо менеджера — с калькулятором, голосом и квиз‑ботом, напишите мне в Telegram.
Читайте также
- Архитектура AI-маркетинга: 4 слоя системы — как этот лендинг укладывается в общую схему
- Куда утекают заявки: 7 дыр в воронке — что чинил калькулятор и лид‑магнит
- Разбор лендинга услуг: где он теряет клиентов — те же барьеры на чужом примере
- Мост MAX ↔ Telegram — мессенджер как рабочий стол команды








Комментарии
Войдите через Telegram, чтобы оставить комментарий:
Пока нет комментариев. Будьте первым.