Об этом проекте

ClassSniper — это проект персональной автоматизации для бронирования занятий в спортзале в тот самый момент, когда открывается окно резервирования. Он ориентирован на конкретную сеть залов (One Playground в Австралии), где запись открывается ровно за 72 часа до начала занятия — в этот период популярные слоты и инструкторы могут быть заняты за считанные секунды. Репозиторий представляет собой шаблон, который можно адаптировать под свой аккаунт и филиал. Как это работает - Внешний сервис cron каждые 60 секунд вызывает эндпоинт workflow_dispatch репозитория. Каждый запуск проверяет, открылось ли 72-часовое окно для какого-либо запланированного бронирования. - Как только окно открывается, бот бронирует занятие: сначала через быстрый прямой путь API, а если он не дает результата — через полноценную браузерную автоматизацию Playwright. - Сопутствующий скрепер с той же периодичностью собирает актуальное расписание по всем студиям, чтобы веб-дашборд отображал реальные предстоящие занятия (название, инструктор, оставшиеся места), а не просто дату и время. - Жесткое правило безопасности блокирует активацию или попытку бронирования любого занятия, которое начинается менее чем через 30 часов, так как отмена менее чем за 24 часа влечет за собой штраф. Архитектура Репозиторий служит источником истины через три зафиксированных JSON-файла (pending_booking.json, status.json, class_list.json). Дашборд на GitHub Pages читает эти файлы напрямую (публично, без авторизации) и записывает изменения по активации/удалению через GitHub Contents API с использованием fine-grained PAT, ограниченного рамками репозитория. GitHub Actions запускает планировщик; bot/scraper.py обновляет расписание, а bot/striker.py выполняет бронирование. Скриншоты и состояние результата захватываются из живого контекста Playwright, чтобы сбои фиксировались, а не игнорировались. Технические особенности - Разграничение занятий: разные занятия часто проходят в одно и то же время в одном месте, поэтому сопоставление только по дате и времени неоднозначно. Каждое занятие имеет уникальный booking_id из API сессий заведения и сопоставляется точно. - Быстрый путь: анализ JavaScript-бандла заведения показал, что поток «нажать Забронировать → войти → подтвердить» в интерфейсе состоит из двух HTTP-запросов. Эти публичные эндпоинты вызываются напрямую, а браузерный поток сохранен как проверенный резервный вариант. - Тайминг: момент удара вычисляется точно, процесс засыпает до этого момента, прогревает HTTP-соединение примерно за пять секунд до старта, а затем срабатывает. - Выбор планировщика: триггеры расписания GitHub Actions работают по принципу «best-effort» и могут срабатывать с большими интервалами под нагрузкой, поэтому используется внешний cron, обращающийся к workflow_dispatch каждую минуту; группа конкурентности (concurrency group) и цикл повторов fetch-rebase обрабатывают перекрывающиеся запуски при git push. - Гигиена учетных данных: ошибки тайм-аута Playwright могут содержать значения DOM, такие как email для входа, поэтому обработчик тайм-аута входа выдает чистое сообщение, отладочные скриншоты маскируют поля email/пароль, а проход редирования удаляет совпадения с учетными данными перед записью в публичный status.json. - Лимиты запросов: быстрый путь делает максимум три запроса за попытку и не повторяет их, оставляя бюджет для резервного входа. Стек и настройка Python, Playwright, GitHub Actions и HTML/CSS/JS без фреймворков на GitHub Pages. Для адаптации требуется форкнуть репозиторий, добавить секреты GYM_EMAIL и GYM_PASSWORD, включить Pages и Actions, предоставить fine-grained токен для дашборда и — что важно — настроить внешний триггер со вторым токеном, ограниченным Actions, так как встроенный cron описан как слишком ненадежный для своевременных бронирований. Область применения Проект автоматизирует бронирования одного личного аккаунта в сервисе, за который оператор платит, используя те же публичные интерфейсы, что и официальный сайт сервиса. Заявлено, что он не обходит аутентификацию, не получает доступ к данным других участников и не превышает задокументированные лимиты запросов. Лицензия MIT.