Мхитар Манасян › bestmdidi Паспорт верифицирован
Сайты, Telegram-боты и Mini Apps - Next.js, Nest.js, Node.js
Рейтинг
71 900
№ 10 в каталоге
Отзывы
Профессионализм
10/10
Коммуникация
9 /10
Город
Москва
Опыт работы
6 лет
На сайте с
2022 года
Юридический статус
Самозанятый
Эксперт
Национальной Гильдии Фрилансеров
Freelance.Boutique
Премиум-сервис для лучших исполнителей
Безопасная сделка
Деньги списываются после приёмки

Доработка сайта санитарной службы на WordPress: вернул доступ после фильтрации, подтверждение заявок по SMS и умная маска телефона, два сервера с автопереключением

Используемые навыки JavaScript Linux MySQL PHP WordPress

Описание

Заказчик - санитарная служба: дезинсекция, дератизация, дезинфекция, Москва и область. Сайт на WordPress достался готовым: самописная тема, 16 плагинов заказчика, около 480 городских поддоменов и 24 формы заявок на Contact Form 7. Заявки уходят на почту, в CRM Planfix и в коллтрекинг, после отправки тема пишет цель в Яндекс.Метрику, по ней Яндекс.Директ считает конверсии. Основной источник заявок - платная реклама, поэтому любой простой сайта оборачивается потерянными обращениями.

Три задачи по порядку. Первая: сайт перестал открываться у абонентов части операторов после блокировки РКН, нужно было вернуть доступ. Вторая: заменить внешний сервис подтверждения номеров по SMS своим решением и починить маску телефона, из-за которой номер, набранный с восьмёрки, терял последнюю цифру, и код уходил на чужой номер. Третья: после нескольких сбоев у хостинга сделать так, чтобы при отключении одного сервера сайт продолжал работать без ручного переноса, без дорогих тарифов, через уже оплаченную защиту.

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

Решение

Доступ. Перевёл сайт на новый сервер за сеть защиты DDoS-Guard: посетители ходят на адреса защиты, настоящий сервер снаружи не виден. Все ~480 городских поддоменов работают через один домен в тарифе и один сертификат, HTTPS обязателен. Сервер получает от защиты настоящий IP посетителя: иначе антибот и аналитика видели бы один адрес. Позже перевёл домен на выделенный защищённый адрес без простоя.

Подтверждение заявок. Написал плагин для WordPress с нуля. Посетитель жмёт «Отправить», номер сохраняется в разделе «Клиенты» как неподтверждённый, открывается окно ввода кода, SMS уходит через SMS.ru. Ввёл код => заявка идёт обычным путём: письмо, CRM Planfix, коллтрекинг, цель в Метрике, конверсия в Директе. Не ввёл за минуту => заявка всё равно уходит менеджерам с пометкой «не подтверждён», но без конверсии: заявки не теряются, а реклама учится только на живых людях. Защита от накрутки: лимиты на попытки, повторные SMS и заявки с номера, автоматическая блокировка. В «Клиентах» группировка по номеру, фильтры, поиск, выгрузка в CSV.

Главная сложность: код форм разбросан по теме и плагинам. 24 формы, у телефона 22 имени поля, формы вставлены в 3 шаблона темы и в тексты 38 страниц, часть во всплывающих окнах. Скрипт темы подставляет скрытые поля, шлёт 21 цель в Метрику и передаёт данные в коллтрекинг по жёсткой карте форм; вокруг 5 плагинов-дополнений и чужие спам-фильтры с капчей. Ничего не переписывал: окно кода встроено в штатный механизм Contact Form 7, само находит поле телефона в любой форме, а на сервере форма без подтверждённого кода не уходит. После кода она уходит как обычно, и цели, письма, CRM и коллтрекинг срабатывают сами. На живом трафике каждая четвёртая подтверждённая заявка не доходила из-за конфликта с чужим спам-фильтром формы. Конфликт устранил и добавил страховку: недошедшую подтверждённую заявку сервер через пару минут досылает сам с пометкой «восстановлено», это 2-3% подтверждённых заявок в месяц. Почту сайта перевёл на SMTP: прямые письма с сервера попадали под фильтры.

Умная маска телефона. Свой скрипт на чистом JavaScript без библиотек, около 400 строк, подключается к любому полю по классу. Формат +7 (___) ___-__-__, «+7» стереть нельзя. Первая цифра: 89 => 9, 88 => 8, 81-87 => код города. Вставка из буфера берёт только цифры и отбрасывает «+7» и «8» в начале. На телефоне цифровая клавиатура, отдельно обработан ввод на Android. Неполный номер не уходит. Письма, CRM и коллтрекинг ждали номер в прежнем формате, поэтому на сервере номер приводится к старому виду: снаружи ничего не изменилось. Включается одной настройкой, выключил => вернулась старая. На ядро маски 163 теста: 43 сценария ТЗ и 120 случайных «злых» серий.

Два сервера. Переезд без простоя: копию на новом сервере проверил заранее, включая живую заявку, старый сервер неделю держал для отката. Резерв у другого провайдера в другом городе. Защита сама проверяет оба сервера и выводит упавший из работы, в обычном режиме трафик делится между ними; проверка здоровья смотрит, что сайт реально работает. База: двусторонняя репликация MySQL, оба сервера принимают заявки, данные доходят до соседа примерно за секунду, номера записей разведены. Файлы уходят с основного на резервный за 10-20 секунд. Админка всегда на основном сервере, чтобы обновления не расходились по машинам. Сторожа с уведомлениями на почту следят за обменом и сверяют серверы. Ежедневные копии на обоих серверах плюс копия у соседа. Страница состояния и значок в админке показывают, какой сервер отвечает.

По ходу ускорил серверную часть: запросы ждали внешние DNS-серверы, поставил локальный кэширующий DNS; удалил заброшенную копию стороннего скрипта с разросшейся базой, сайт уменьшился с 757 до 415 МБ; статику ~480 поддоменов раздаю с основного домена: в кэше CDN одна копия вместо ~480. Стек: PHP и WordPress API, JavaScript, MySQL, Linux, Nginx и Apache, lsyncd и rsync, BIND, bash и cron, SMS.ru, Planfix, SMTP, Метрика и Директ.

Результат

Сайт снова открывается у всех операторов и работает через сеть защиты с выделенным адресом. Заявки подтверждаются кодом из SMS: около 70% посетителей доводят подтверждение до конца, неподтверждённые заявки тоже доходят до менеджеров, а реклама считает конверсии только по живым людям. Маска телефона больше не теряет цифры, 163 теста ядра проходят.

Два сервера у разных провайдеров: на учениях с боевым трафиком переключение на резерв заняло 24 секунды, заявка, пришедшая посреди аварии, записана резервным сервером и через минуту ушла менеджерам, основной вернулся в работу сам. Среднее время генерации страницы в день правки снизилось с 0,12 до 0,07 с на основном сервере и с 0,19 до 0,03 с на резервном, доля страниц дольше 0,5 с упала с 2,6% до 1,8% и с 11% до 0,65%. Сайт уменьшился с 757 до 415 МБ.

Плагин подтверждения: 12 файлов, около 2,5 тысячи строк на PHP, JavaScript и CSS; маска около 400 строк без зависимостей. Запуск подтверждения 20 июня 2026, маска 8 июля, связка двух серверов 10 августа, выделенный адрес защиты в сентябре. Сотрудничество продолжается, веду сайт и серверы.

Ссылку и название сайта не публикую без согласия заказчика. На кадрах логотип размыт, номера демонстрационные; адреса серверов, названия хостингов и устройство защиты намеренно не раскрываю.

Оценили проект:

Другие проекты

Все проекты →
Веб-разработка и IT Визуальный редактор дашбордов мониторинга: npm-пакет на React и TypeScript со структурным редактированием, drag-and-drop, undo/redo и проверкой структуры
Визуальный редактор дашбордов мониторинга: npm-пакет на React и TypeScript со структурным редактированием, drag-and-drop, undo/redo и проверкой структуры
36
Веб-разработка и IT TMS для американской грузоперевозочной компании: рейсы и документы, мобильные экраны водителя, расчёт зарплат и P&L-отчёты. Fullstack на NestJS + React, PostgreSQL, TypeScript
TMS для американской грузоперевозочной компании: рейсы и документы, мобильные экраны водителя, расчёт зарплат и P&L-отчёты. Fullstack на NestJS + React, PostgreSQL, TypeScript
37
Веб-разработка и IT CommerceAPI - SaaS-платформа для интернет-магазинов с динамическим ORM и no-code конструктором каталогов | Next.js, Nest.js, PostgreSQL, Redis
CommerceAPI - SaaS-платформа для интернет-магазинов с динамическим ORM и no-code конструктором каталогов | Next.js, Nest.js, PostgreSQL, Redis
184
Веб-разработка и IT Trenergy - SaaS для фитнес-тренеров: Telegram Mini App, бот и панель управления. Тренировки, питание с КБЖУ, прогресс, чаты, оплата | React.js, Nest.js, Node.js
Trenergy - SaaS для фитнес-тренеров: Telegram Mini App, бот и панель управления. Тренировки, питание с КБЖУ, прогресс, чаты, оплата | React.js, Nest.js, Node.js
117