About this project
ClassSniper is a personal automation project for booking gym classes the instant their reservation window opens. It targets a specific gym chain (One Playground in Australia), whose classes open for booking exactly 72 hours before the start time — a window where popular slots and instructors can fill within moments. The repository is a template you can adapt to your own account and venue.
How it works
- An external cron service calls the repo's workflow_dispatch endpoint every 60 seconds. Each run checks whether any queued booking's 72-hour window has opened yet.
- Once a window opens, the bot books the class: first via a fast direct API path, falling back to full Playwright browser automation if the fast path is inconclusive.
- A companion scraper pulls the live class schedule across every studio location on the same cadence, so the web dashboard shows real upcoming classes (name, instructor, spots remaining) rather than a blind date/time entry.
- A hard safety rule blocks arming or striking any class starting less than 30 hours away, since cancelling within 24 hours incurs a fee.
Architecture
The repo acts as the source of truth through three committed JSON files (pending_booking.json, status.json, class_list.json). A GitHub Pages dashboard reads those files directly — public, no auth needed to view — and writes arm/remove changes back through the GitHub Contents API with a fine-grained PAT scoped to the repository. GitHub Actions runs the scheduler; bot/scraper.py refreshes the schedule and bot/striker.py performs the booking. Screenshots and result state are captured from inside the live Playwright context so failures are recorded rather than silently swallowed.
Notable engineering details
- Class disambiguation: distinct classes often share the same time slot at the same location, so matching on date plus time alone is ambiguous. Each class carries a unique booking_id sourced from the venue's own session API and is matched exactly.
- Fast path: reading the venue's JavaScript bundle revealed that the UI's "click Book → sign in → confirm" flow is two HTTP calls underneath. Those public endpoints are called directly, with the browser flow retained as a tested fallback.
- Timing: the strike moment is computed precisely, the process sleeps until just before it, warms up its HTTP connection about five seconds early, then fires.
- Scheduler choice: GitHub Actions schedule triggers are best-effort and were observed landing far apart under load, so an external cron hitting workflow_dispatch every minute is used instead; a concurrency group and a fetch-rebase retry loop handle overlapping runs racing on git push.
- Credential hygiene: Playwright timeout errors can embed DOM values such as the login email, so the login-timeout handler raises a clean message, debug screenshots mask visible email/password fields, and a redaction pass scrubs credential matches before anything is written to the public status.json.
- Rate limits: the fast path makes at most three requests per attempt and does not retry, leaving budget for a fallback login.
Stack and setup
Python, Playwright, GitHub Actions, and framework-free HTML/CSS/JS on GitHub Pages. Adapting it requires forking the repo, adding GYM_EMAIL and GYM_PASSWORD secrets, enabling Pages and Actions, supplying a fine-grained token for the dashboard, and — importantly — configuring an external trigger with a second token scoped to Actions, since the built-in cron alone is described as too unreliable for on-time strikes.
Scope
The project automates a single personal account's own bookings against a service the operator pays for, using the same public interfaces the service's own website uses. It states that it does not bypass authentication, access other members' data, or exceed documented rate limits. Licensed under MIT.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.