Карта лояльности компьютерного клуба в Telegram
QR-код вместо бумажной карты: учёт посещений и награда за шестую ночь
Telegram-бот лояльности для компьютерного клуба вместо бумажных карт: клиент показывает QR-код, администратор начисляет ночь одним нажатием, за шестую ночь бот открывает награду. Python, aiogram 3, SQLite.
Задача
Компьютерный клуб вёл программу лояльности на бумажных карточках. Бумага не даёт цифр: сколько игроков, как часто они приходят, кому пора выдать награду и кто из персонала что начислил.
Клубу нужна цифровая замена: администратор сканирует QR-код клиента и начисляет посещение одним нажатием, бот сам отслеживает наступление награды (каждая шестая ночь или бесплатный кальян) и ведёт журнал действий персонала. Владельцам нужны статистика и ежедневная копия базы.
Решение
Telegram-бот заменяет бумажные карты цифровой системой лояльности: учёт посещений («ночей»), выдача наград, база игроков и журнал действий персонала. Что реализовано.
Для клиента:
- регистрация по команде
/start; - «Моя карта (QR)»: баланс ночей, шкала прогресса из шести ячеек, статус награды и персональный QR-код;
- уведомление, когда награда стала доступна: бесплатная ночь или кальян.
Для администратора:
- открытие профиля клиента по QR-коду; посторонним бот отвечает отказом;
- поиск игрока по номеру телефона и список всех игроков с ником, телефоном, ночами и потраченными наградами;
- кнопки в профиле: «Добавить ночь», а при доступной награде «Списать: БЕСПЛАТНАЯ НОЧЬ» и «Списать: КАЛЬЯН»;
- защита от накрутки: пауза 70 секунд между начислениями и запрет начислять себе.
Для главного администратора:
- статистика клуба: игроки, админы, всего ночей, выдано наград;
- журнал последних 30 действий;
- управление списком администраторов командами
/add_adminи/del_admin; - несколько главных администраторов, ежедневная копия базы и скрытая команда
/version.
Как это устроено
QR-карта клиента: qrcode и Pillow
Библиотеки qrcode и Pillow создают картинку QR-кода. Внутри кода зашита ссылка на бота вида «открыть бота с параметром scan_<номер клиента>». Когда администратор сканирует QR камерой телефона, Telegram открывает бота именно с этим параметром, и бот показывает профиль клиента. Для остальных пользователей эта ссылка не даёт ничего: бот отвечает отказом.
Правило награды: каждая шестая ночь
Порог задан константой: шесть ночей. Когда счётчик достигает шести, у клиента выставляется отметка о доступной награде и приходит уведомление. Списание уменьшает баланс на шесть и увеличивает счётчик потраченных наград. Тип награды, ночь или кальян, записывается в журнал.
Антифрод: пауза и запрет начисления себе
Защита от злоупотреблений двухслойная. Первый слой: между начислениями одним администратором проходит 70 секунд. Второй слой: обычный администратор не может начислить ночь самому себе. Все начисления и списания (ADD_NIGHT, SPENT_NIGHT, SPENT_HOOKAH) пишутся в журнал, который главный администратор смотрит из бота.
SQLite и aiosqlite: база без отдельного сервера
SQLite — база данных в одном файле, ей не нужен отдельный сервер. Драйвер aiosqlite работает с ней асинхронно, поэтому запросы не блокируют бота. Таблицы игроков, администраторов и журнала создаются при первом запуске. Для небольшого клуба такого решения достаточно: резервная копия — это просто файл.
Три уровня доступа: клиент, администратор, главный администратор
Права проверяются по списку администраторов в базе и по ID главных администраторов из настроек. Клиент видит только свою карту. Администратор открывает профили по QR или по номеру телефона, начисляет ночи, списывает награды и просматривает список игроков; обычным администраторам этот список тоже доступен. Главный администратор дополнительно видит статистику и журнал и управляет составом администраторов. Пользователь без прав, открывший ссылку с QR, получает отказ.
Ежедневная копия базы
Фоновая задача раз в сутки отправляет файл базы всем главным администраторам в Telegram. Главных администраторов может быть несколько: их ID перечисляются через запятую в настройке окружения.
Результат
- Бумажные карты заменены QR-картой в Telegram: клиенту нужен только телефон.
- Награда наступает автоматически на шестой ночи, клиент получает уведомление.
- Начисление одним нажатием, ограничено паузой 70 секунд и запретом начислять себе.
- Все действия персонала пишутся в журнал, статистика клуба доступна главному администратору.
- Ежедневная копия базы приходит главным администраторам файлом.
- Автотестов в репозитории нет, приёмка ручная.
Технологии: что и зачем
- Python 3.10+ и aiogram 3 — асинхронный Telegram-бот с меню, ролями и диалоговыми состояниями.
- SQLite и aiosqlite — хранение игроков, администраторов и журнала в одном файле.
- qrcode и Pillow — генерация персонального QR-кода клиента.
- python-dotenv — токен бота и ID главных администраторов из окружения.
Статус
Версия 2.2.1 от 11 января 2026 года. После неё в репозитории добавлены константа версии, скрытая команда /version и документация: эти изменения ещё не вынесены в выпуск. Известные ограничения по README: пауза между начислениями и состояния диалогов хранятся в памяти и сбрасываются при перезапуске; тип награды фиксируется только в журнале; проверка доступной награды при списании выполняется на уровне кнопок, а не базы; нет Docker-файлов и автотестов; время в базе и журнале хранится в UTC. Другие детали заказчика не раскрываются.
Вопросы по проекту
Как сделать накопительную карту клиента без приложения?
Как администратор начисляет посещение?
Какая награда и как она списывается?
Как защититься от накрутки посещений персоналом?
Где хранятся данные клиентов и что видит владелец?
Можно ли сделать такую систему лояльности для другого бизнеса?
Ещё по этому направлению
Финансовый ассистент: учёт денег из PDF-выписок в Telegram
собственный продукт: бот и веб-дашборд, выписки четырёх банков, Gemini
Тикет-система для IT-отдела в Telegram
для музейного комплекса в Москве: заявки, учёт техники, база знаний и аналитика
Tech Poly VPN: биллинг VPN-подписок в Telegram
собственный продукт: оплата по СБП, выдача ключей в Marzban, резервный бот во ВКонтакте
Нужно похожее?
Расскажите о задаче — покажем, как решали такое, и прикинем объём работ.