Когда клиент заполняет форму на сайте, заявка должна попасть к менеджеру за секунды. Почта медленная, CRM требует ручной обработки, а вот Telegram-бот с inline-кнопкой «Взять заявку» — это когда менеджер открывает чат и сразу работает. Разбираем полную реализацию на PHP: от приёма данных с сайта до обработки callback от менеджера.
Архитектура: сайт → webhook-бота → менеджер
Схема простая: HTML-форма на сайте отправляет POST-запрос на ваш API-эндпоинт. PHP-скрипт генерирует lead_id, пишет запись в таблицу leads, формирует сообщение с inline-кнопкой и отправляет через Bot API менеджеру. Когда менеджер нажимает «Взять», бот получает callback_query, проверяет, что заявка ещё свободна, и перенаправляет её в чат с менеджером.
Ключевое ограничение, которое нужно учитывать сразу: callback_data в inline-кнопке не может превышать 64 байт. Поэтому вместо длинных ID или JSON-объектов используем компактный хеш.
Таблица leads в базе данных
Перед отправкой заявки создаём таблицу. Понадобятся: уникальный идентификатор, статус (new/taken/closed), ID менеджера, который взял заявку, и время взятия.
Генерация lead_id: bin2hex(random_bytes(7))
Зачем свой ID, если есть автоинкремент? Автоинкремент предсказуем, а lead_id должен быть непредсказуемым и коротким. random_bytes(7) генерирует 7 байт, bin2hex превращает их в 14 символов — достаточно компактно для callback_data и при этом безопасно.
Пример результата: a3f8b2c1d9e04f
Обработчик формы на сайте: HTML + JavaScript
Форма минимальная, но валидация обязательна. Отправляем fetch-запрос, показываем состояние загрузки и обрабатываем ошибки.
API-эндпоинт: /api/lead/submit
Этот PHP-скрипт принимает данные, валидирует, пишет в базу и отправляет уведомление в Telegram. Токен бота и chat_id менеджера — из переменных окружения.
Обработка callback_query: бот берёт заявку
Webhook-эндпоинт бота получает callback_query. Проверяем: заявка существует, она ещё не взята. Если всё ок — обновляем статус, запоминаем менеджера и отправляем ему детали заявки в личный чат.
Почему не inline-кнопка с длинным data
Telegram ограничивает callback_data до 64 байт. Если запихнуть туда JSON с данными клиента, можно легко превысить лимит при длинном сообщении. Бинарный хеш из random_bytes(7) — это 14 символов, компактно и достаточно для надёжного JOIN с базой. Данные хранятся в MySQL, а не в кнопке.
Идемпотентность: двойное нажатие не страшно
Менеджер может случайно нажать кнопку дважды. UPDATE ... WHERE status = 'new' с проверкой $stmt->rowCount() гарантирует: выполнится только первое нажатие. Второе получит ответ «заявка уже взята».
Что дальше
К базовой схеме можно добавить: уведомление клиенту о получении заявки, автоматический перезапуск кнопки через N минут, если менеджер не взял, или экспорт необработанных заявок в конце дня. Главное — данные уже в базе, а менеджер получает их одним тапом.
Для быстрого развёртывания связки формы и Telegram-бота можно воспользоваться готовыми решениям на BotCreator.