Почему простая схема ломается
Самый короткий путь выглядит убедительно: браузер отправляет форму, сервер сразу вызывает Telegram API, пользователь видит «Спасибо». В спокойной сети этого достаточно. Но успех формы в таком сценарии начинает зависеть от чужого сервиса, DNS, маршрута провайдера и доступности конкретного получателя.
Если Telegram ответил медленно или соединение оборвалось, возникают два плохих варианта. Либо посетителю показывают ошибку, хотя его данные уже успели уйти. Либо показывают успех, хотя команда ничего не получила. Повторное нажатие может создать ещё одну заявку, а разбирать ситуацию потом приходится по неполным журналам.
- Уведомление — это способ сообщить о заявке, а не сама заявка.
- Ответ «200» от формы должен означать сохранённый результат, а не просто начатую попытку.
- Повторять можно только временную ошибку и только ограниченное число раз.
Сначала источник истины
В нашем контуре источником истины стала база данных. После серверной проверки заявка записывается целиком, получает время создания и состояние доставки. Только после этого начинается отправка уведомлений. Если внешний канал недоступен, обращение уже не потеряно: его можно увидеть, повторить доставку или обработать другим способом.
Такой порядок важен ещё и для честного интерфейса. Пользователь получает подтверждение не потому, что браузер нарисовал зелёную плашку, а потому, что сервер принял и сохранил данные. Мессенджер остаётся быстрым рабочим каналом, но перестаёт быть единственной памятью системы.
Доставка — отдельный процесс
У каждого получателя свой результат: доставлено, ожидает повторной попытки или требует внимания. Это позволяет не путать две разные ситуации — «заявка существует» и «уведомление уже дошло». В проверке рабочего контура оба заранее подтверждённых получателя получили одну и ту же тестовую заявку, а запись сохранила итог доставки.
Для временных сетевых ошибок, ограничения частоты и ответов сервиса 5xx предусмотрены короткие повторы с паузой. Ошибки доступа, неверная конфигурация и другие постоянные отказы не повторяются бесконечно: цикл заканчивается явным состоянием, которое можно диагностировать.
- Получатель сначала сам запускает диалог с ботом: Telegram не разрешает боту начать личную переписку по номеру телефона.
- Список разрешённых людей хранится на сервере, а не передаётся в браузер.
- Токен бота, служебные идентификаторы и полный текст заявки не попадают в публичные логи.
Аналитика не должна читать заявку
Полезно измерять факт отправки формы, но для этого не нужны имя, телефон, ник или свободный рассказ о задаче. В аналитику уходит только техническое событие вроде «короткая форма отправлена». Содержание обращения остаётся внутри контура заявки.
Это разделение снижает риск утечки и делает отчёт понятнее. Система аналитики отвечает на вопрос «сценарий сработал?», а база заявок — «что написал человек и кому нужно ответить?». Смешивать эти роли не требуется.
Что проверить до запуска
Проверка формы не заканчивается сообщением в браузере. Нужен сквозной сценарий: реальная отправка с сайта, запись в базе, доставка каждому адресату, корректное состояние и отсутствие персональных данных в аналитических запросах. Затем отдельно имитируются временный отказ Telegram и повторное нажатие кнопки.
Если проект небольшой, не обязательно сразу строить сложную очередь. Но три свойства нужны почти всегда: независимое сохранение, различимый результат доставки и понятный путь восстановления. Архитектура должна быть соразмерна риску потери обращения, а не моде на технологии.
