Лендинг, который работает вместо менеджера: itc34.ru

Кейс корпоративного сайта IT-компании: калькулятор цены без звонка, лид‑магнит на страхе штрафа, голосовой AI-консультант, квиз‑бот с PDF-аудитом и вся воронка в одном Telegram-треде. Один HTML-файл без сборки, Three.js на скролле, два бренда из одного кода.

Сайт есть, а заявок нет

Знакомая для многих компаний ситуация: сайт вроде бы работает, но по сути это визитка. Он рассказывает, чем занимается компания, показывает логотип и телефон — и на этом всё. Посетитель заходит, читает, не находит цены, не понимает, с чего начать разговор, и уходит. Ни звонка, ни заявки. Сайт есть, а продаж от него нет. Это одна из типовых дыр, через которые утекают заявки, — и, как правило, не единственная.

Именно с этим пришла компания «ИТ Консалтинг» из Волгограда — IT-аутсорсинг с 200+ клиентами и историей с 2012 года. Формулировка задачи была короткой и честной: «Нужен сайт, который работает круглосуточно вместо менеджера».

Из этой фразы выросли четыре требования, и каждое из них — про боль реального бизнеса:

  • Посетитель должен сам увидеть цену — без «оставьте заявку, мы перезвоним». Большинство холодных клиентов уходят именно на этом шаге.
  • Заявка должна доходить до менеджера мгновенно, куда бы он ни смотрел. У этой команды рабочий инструмент — Telegram.
  • Нужен вход для холодного трафика: что‑то бесплатное, ценное и мгновенное, ради чего человек оставит контакт.
  • Сайт должен выглядеть дорого. Клиенты компании — производство и ретейл, а не стартапы, и доверие здесь считывается в том числе через оформление.

Главный экран сайта itc34.ru: тёмная тема, заголовок «Обеспечим надёжную работу IT-инфраструктуры», кнопки расчёта стоимости и скачивания презентации

Проект получился заметно больше, чем классический лендинг: восемь итераций с марта по май 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, без единой внешней библиотеки.

Экран загрузки: тонкая wireframe-фигура на тёмном фоне, надпись «ИТ Консалтинг» и индикатор прогресса

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

Калькулятор до формы, а не после

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

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

Калькулятор стоимости: слайдеры количества компьютеров и серверов, чекбоксы дополнительных услуг и крупная итоговая цифра 18 000 ₽ в месяц

Отдельная деталь — название кнопки. Она называется не «Отправить», а «Зафиксировать цену». Это меняет психологию действия: абстрактный расчёт превращается в маленькое обязательство, которое проще довести до заявки.

Лид‑магнит, который бьёт в конкретный страх

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

Секция аудита: заголовок «Ваш сайт может нарушать закон. Штраф — до 500 000 ₽» и сетка пунктов проверки с метками «штраф» и категориями

Пункты разбиты на категории: «Закон», «Безопасность», «Скорость», «SEO». Самые опасные — политика конфиденциальности, согласие на обработку персональных данных, уведомление о cookies, хранение данных на серверах РФ — помечены красной меткой «штраф». Человек видит список того, что у него, скорее всего, не в порядке, — и хочет проверить.

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

Проверка происходит не на сайте, а в Telegram-боте: пользователь отвечает на пять вопросов кнопками, оставляет адрес сайта — и получает персональный разбор. Так холодный посетитель без единого звонка превращается в контакт менеджера.

AI-консультант, который ведёт по скрипту продаж

В правом нижнем углу — виджет AI-консультанта. У него два режима: текстовый чат и голосовой диалог. Это не «спросите что угодно» — за виджетом стоит проработанный сценарий продаж.

AI-консультант в углу экрана: сообщение с расчётом стоимости IT-аутсорсинга и кнопки быстрых ответов — «О компании», «Аудит сайта», «Аутсорсинг», «1С», «Консультация»

Консультант работает на современных 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-модели из России. Один архитектурный ход закрыл сразу две задачи — защиту ключа и надёжный доступ к модели.

Кейсы с цифрами, а не с «повысили эффективность»

Раздел реализованных проектов сделан по одному принципу: никаких общих слов. Каждый кейс — с конкретным результатом.

Секция «Реализованные проекты»: три карточки кейсов — переезд IT-инфраструктуры завода, единая сеть для торговой сети, B2B-портал для логистики — с измеримыми результатами

«В понедельник в 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, персонализируется под клиента правкой одного блока данных
Страница‑хаб Клиенту уходит одна ссылка, внутри — предпросмотр всех материалов сразу

Питч-дек на одну страницу: краткая презентация компании и услуг с кнопкой сохранения в PDF

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

Коммерческое предложение на несколько страниц: структура с ценами и услугами, готовая к сохранению в PDF

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

Страница-хаб для менеджера: одна ссылка клиенту, внутри — предпросмотр всех материалов через встроенные окна

Презентация: офлайн‑вход в ту же воронку

Ко всему цифровому контуру прилагается 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-кодом и призывом пройти бесплатный аудит

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.

Читайте также

Комментарии

Войдите через Telegram, чтобы оставить комментарий:

Пока нет комментариев. Будьте первым.