Telegram Mini App для мероприятия: регистрация, билеты и проверка QR-кодов
За десять минут до лекции у входа появляется очередь. Один гость ищет письмо, второй показывает скриншот билета приятеля, у третьего телефон почти разрядился. Волонтёр листает таблицу, организатор отвечает в чате, а выступающий уже проверяет микрофон. Все системы работают — просто каждая занята своим делом.
Небольшое приложение в Telegram может собрать регистрацию и вход в один маршрут: человек записывается, получает билет, показывает код, сотрудник отмечает посещение. Но QR-код здесь лишь способ передать данные. Сам по себе квадрат с узором ничего не знает ни о количестве мест, ни о повторном проходе.
Спроектируем приложение для бесплатного мероприятия с ограниченной вместимостью. Такой пилот позволяет отработать регистрацию, отмену и контроль входа, не смешивая их сразу с оплатой и возвратами.
Содержание
- Сначала нарисуйте путь гостя и путь сотрудника
- Регистрация начинается с правил вместимости
- Что именно находится внутри QR-кода
- Вход подтверждает сервер, а не камера
- Два входа и один скриншот
- Telegram помогает открыть приложение, но не заменяет авторизацию персонала
- Что делать, если у входа пропал интернет
- Напоминания, отмена и лист ожидания
- Сервер и репетиция открытия дверей
VPS для регистрации и проверки билетов
Держите регистрацию, билеты и журнал проходов в одном приложении на VPS. Перед мероприятием проверьте работу двух сканеров и восстановление базы.
Выбрать VPS для Mini AppСначала нарисуйте путь гостя и путь сотрудника
У гостя пять понятных действий: открыть описание, выбрать сеанс, зарегистрироваться, найти свой билет, при необходимости отменить участие. На каждой стадии должно быть ясно, где и когда состоится событие, сколько человек проходит по билету и как связаться с организатором.
У сотрудника другой маршрут: войти в служебный интерфейс, выбрать сегодняшнее мероприятие, отсканировать код, увидеть результат. Не заставляйте волонтёра искать кнопку проверки внутри общего каталога. В момент открытия дверей простота интерфейса измеряется вполне физической длиной очереди.
Заранее решите, нужен ли именной билет. Если достаточно предъявить код, система фактически работает с пропуском на предъявителя. Передача скриншота тогда возможна по определению. Если требуется сверка личности, добавьте отдельную процедуру и сообщите о ней при регистрации, а не у входа.
Билет на группу также нельзя случайно считать обычным одиночным билетом. Для первой версии проще выдавать отдельный пропуск каждому участнику. Групповое посещение потребует учитывать остаток проходов и частичный приход людей.
Регистрация начинается с правил вместимости
Создайте сущности «мероприятие», «сеанс», «регистрация» и «билет». Даже у однодневной встречи полезно иметь отдельный сеанс: позже появятся утренние и вечерние группы, и не придётся переделывать все связи.
В карточке сеанса храните начало, конец, часовой пояс, лимит мест и состояние регистрации. Дедлайн регистрации и фактическое закрытие дверей — разные настройки. Человек может зарегистрироваться заранее, но опоздать; это не должно неожиданно превращаться в техническую ошибку приложения.
Запись последнего места выполняйте атомарно в базе. Обычная последовательность «посчитали свободные места, затем добавили человека» допускает гонку двух запросов. Можно блокировать строку сеанса на время проверки лимита и создания регистрации либо использовать иной согласованный механизм транзакций. Для реализации пригодится описание блокировок строк PostgreSQL.
Повторную регистрацию одного человека на тот же сеанс обрабатывайте по правилам события: возвращайте прежний билет или явно предлагайте дополнительного участника. Не создавайте новый пропуск только потому, что приложение не дождалось ответа и повторило запрос.
Что именно находится внутри QR-кода
Не помещайте в код фамилию, телефон и полный профиль гостя. Обычно достаточно случайного непрозрачного токена, который сервер сопоставляет с билетом. Используйте криптографически стойкую генерацию с достаточной энтропией; последовательный номер регистрации для этого не годится.
Сам токен становится секретом доступа к проходу. Не выводите его целиком в обычные журналы запросов и не отправляйте сторонней аналитике. В базе можно хранить хеш токена, а в интерфейсе показывать билет только авторизованному владельцу.
Отдельный короткий номер билета нужен для разговора с поддержкой. Он может быть удобочитаемым и не обязан открывать проход. Так сотрудник сможет найти запись по номеру, не прося гостя переслать действующий секрет в общий чат.
Для перевыпуска создавайте новый токен и отзывайте старый. Простое перерисовывание картинки ничего не меняет: если внутри тот же токен, предыдущий скриншот продолжит работать. У гостя должно быть понятное предупреждение, что после перевыпуска старый билет недействителен.
Вход подтверждает сервер, а не камера
Сканер распознаёт строку и отправляет её вашему API. Сервер проверяет сотрудника, событие, состояние билета, срок действия и возможность прохода. Только затем фиксируется посещение.
Удобно разделить распознавание и окончательную отметку. После сканирования сотрудник видит название события и разрешённые сведения о билете, затем подтверждает проход. Это помогает не погасить код случайно, пока человек лишь спрашивает дорогу к другому залу.
Для одиночного билета атомарный переход может выглядеть так. Это фрагмент серверной операции, выполняемый после проверки прав сотрудника; параметры поступают из проверенного контекста:
UPDATE tickets
SET checked_in_at = now(), checked_in_by = :staff_id
WHERE id = :ticket_id
AND event_id = :event_id
AND status = 'valid'
AND checked_in_at IS NULL
RETURNING id, checked_in_at;
Если строка не вернулась, сервер выясняет причину и отдаёт понятное сообщение: уже использован, отозван, относится к другому событию. Запись действия в журнал и изменение билета связывайте одной транзакцией. Результат «уже использован» должен содержать время предыдущего прохода для сотрудника, но не раскрывать лишние данные постороннему посетителю.
Для повторного входа после выхода понадобится другая модель состояний. Не снимайте отметку вручную каждый раз: так теряется история. В первой версии можно прямо объявить однократный вход и вынести исключения на старшего администратора.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
АРЕНДОВАТЬ СЕРВЕРДва входа и один скриншот
Самый полезный тест проводится с двумя телефонами сотрудников. Оба одновременно проверяют один билет. Один проход должен быть принят, второй — получить объяснение о предыдущем использовании.
Блокировка кнопки в браузере от такой ситуации не защищает. Сотрудники работают на разных устройствах, а запросы встречаются только на сервере. Именно поэтому решение о допуске должно приниматься одной согласованной операцией в базе.
Если ответ потерялся после успешной отметки, повтор с тем же ключом операции должен показать прежний результат, а не выглядеть как попытка нового прохода. Иначе сотрудник увидит красный экран и начнёт спорить с человеком, которого сам только что пропустил.
Telegram помогает открыть приложение, но не заменяет авторизацию персонала
Гостевой интерфейс можно запускать кнопкой бота, а сканирование реализовать средствами приложения. В документации Telegram Mini Apps есть метод открытия встроенного QR-сканера. Поддержку конкретного клиента нужно проверить; предусмотрите ручной поиск по безопасному номеру билета, если камера недоступна.
Авторизация гостя и права сотрудника — разные вещи. Даже корректно подтверждённый Telegram-пользователь не получает доступ к списку посетителей автоматически. Сотрудника заранее назначает организатор, причём желательно на конкретное событие и срок.
Служебный экран должен быть недоступен обычному гостю даже по прямому адресу. Проверяйте права на каждом запросе API. Спрятанная кнопка и отдельный цвет интерфейса полезны для удобства, но серверу от них ни холодно ни жарко.
Потерянный телефон сотрудника должен быстро исключаться из работы: завершение сессий, отзыв назначения, при необходимости дополнительное подтверждение входа. В конце мероприятия временные доступы закрываются.
Что делать, если у входа пропал интернет
Это решение нужно принять до события. Для небольшого мероприятия практичнее иметь резервный канал связи и процедуру ручного допуска, чем обещать сложную автономную синхронизацию, которую никто не испытывал.
Офлайн-проверка подписанного кода способна подтвердить, что билет выпущен организатором. Но два независимых устройства без связи не могут надёжно узнать, что один и тот же билет только что использовали у соседней двери. Криптография не передаёт сведения через стену сама по себе.
Если всё же требуется автономная работа, задайте ограничения: одна точка входа, локальный список использованных билетов, ответственное устройство и последующая сверка. Данные списка защищайте и удаляйте после установленного срока. Отдельно решите, как устройство узнаёт об отозванных билетах до потери связи.
Ручной допуск отмечайте с причиной и именем сотрудника. После восстановления сети такие решения разбираются как отдельные события, а не задним числом маскируются под обычное сканирование.
Напоминания, отмена и лист ожидания
Отправляйте напоминание только тем, кто действительно зарегистрирован и может получать сообщения бота. После отмены старое напоминание должно стать неактуальным. В сообщении укажите время, адрес и способ открыть действующий билет.
Если места ограничены, отмена освобождает место в той же согласованной операции, которая отзывает билет. Лист ожидания можно сначала вести с ручным подтверждением организатора. Автоматическая выдача освобождённого места потребует срока ответа и защиты от одновременных приглашений.
Не публикуйте полный список участников в клиентской части без отдельной причины и соответствующего основания. Для самого гостя обычно достаточно собственного билета и общей информации о мероприятии. Поле в базе существует не для того, чтобы обязательно показать его всем.
Сервер и репетиция открытия дверей
Для небольшого события с одним API и PostgreSQL начните проверку на Uab Start: 2 vCPU, 4 ГБ памяти и 80 ГБ диска. Если рядом работают сайт, рассылки и другие приложения, оцените Heka Standard с 4 vCPU и 8 ГБ. На VPS MAATRIX такой сервис устанавливается самостоятельно, например на поддерживаемую проектом Ubuntu 24.04.
Выбирайте размещение с учётом пути от площадки до сервера и требований к данным. Проверьте не домашний Wi-Fi разработчика, а связь там, где будут стоять сотрудники. Резервная копия базы нужна отдельно от рабочего VPS; полезно заранее восстановить её на тестовом узле.
Перед запуском проведите небольшую репетицию: обычный проход, повтор, чужое событие, отозванный билет, потерянный ответ и отказ камеры. Измеряйте время полного действия сотрудника, а не только скорость ответа API. Хорошая система допуска позволяет человеку у двери заниматься гостями, а не превращаться в живой журнал ошибок.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
АРЕНДОВАТЬ СЕРВЕРОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →