website

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

the-gym-group-see-capacity-without-the-app.md (3030B)


      1 +++
      2 title = "The Gym Group: see capacity without the app!"
      3 date = 2024-08-30
      4 url = "the-gym-group-see-capacity-without-the-app"
      5 +++
      6 
      7 If you're like me, you hate busy gyms. I was very happy to learn that I can view my gym's capacity at any time with The Gym Group:
      8 
      9 ![Screenshot_20240830-095752](/blog/images/351b0b57.png)
     10 
     11 But there's a catch! It can only be viewed using their app.
     12 
     13 This annoying decision is made even more annoying after you discover that in order to get the number, the app is just making a _simple web request_. You really have to wonder why I need to provide location data (a necessary app permission), and have Google Play Services enabled, just to see the response of a web request.
     14 
     15 Let's get it without the app. The process is 2 steps:
     16 
     17 1. Logging in and obtaining:
     18    - a cookie
     19    - your ID
     20    - your gym's ID
     21 2. Sending a web request to `/gym-busyness`
     22 
     23 I'll be using [hurl](https://hurl.dev) to send requests, but you can use any tool that can send web requests and read responses.
     24 
     25 Start by making a POST request to `/login` with your username and password. The `Content-Type` is `x-www-form-urlencoded` (a simple web form). Here is it in hurl:
     26 
     27 ```
     28 POST https://thegymgroup.netpulse.com/np/exerciser/login
     29 [FormParams]
     30 password: ********
     31 guestUuid:
     32 username: ****@******.net
     33 ```
     34 
     35 and then run:
     36 
     37 ```
     38 npx hurl login.hurl --very-verbose
     39 ```
     40 
     41 From the output, find and copy:
     42 
     43 - your cookie - set by the `set-cookie` response header
     44 - `uuid`
     45 - `homeClubUuid`
     46 
     47 Now all we need to do is make a GET request to `/gym-busyness`. Here it is in hurl with placeholders for the values above:
     48 
     49 ```
     50 GET https://thegymgroup.netpulse.com/np/thegymgroup/v1.0/exerciser/{put uuid here}/gym-busyness?gymLocationId={put homeClubUuid here}
     51 Accept: application/json
     52 Accept-Encoding: gzip
     53 Connection: Keep-Alive
     54 Cookie: {put set-cookie here}
     55 Host: thegymgroup.netpulse.com
     56 User-Agent: okhttp/4.10.0
     57 X-NP-API-Version: 1.5
     58 X-NP-APP-Version: 6.1
     59 X-NP-User-Agent: clientType=MOBILE_DEVICE; devicePlatform=ANDROID; deviceUid=; applicationName=The Gym Group; applicationVersion=6.1; applicationVersionCode=60
     60 ```
     61 
     62 That's it! No app required. Here's an example of the result:
     63 
     64 ```
     65 {
     66   "gymLocationId": "",
     67   "gymLocationName": "London Wandsworth",
     68   "currentCapacity": 20,
     69   "currentPercentage": 12,
     70   "historical": [
     71     {
     72       "hour": "12AM",
     73       "percentage": 4
     74     },
     75     {
     76       "hour": "2AM",
     77       "percentage": 2
     78     },
     79     {
     80       "hour": "4AM",
     81       "percentage": 6
     82     },
     83     {
     84       "hour": "6AM",
     85       "percentage": 21
     86     },
     87     {
     88       "hour": "8AM",
     89       "percentage": 29
     90     },
     91     {
     92       "hour": "10AM",
     93       "percentage": 34
     94     },
     95     {
     96       "hour": "12PM",
     97       "percentage": 32
     98     },
     99     {
    100       "hour": "2PM",
    101       "percentage": 36
    102     },
    103     {
    104       "hour": "4PM",
    105       "percentage": 40
    106     },
    107     {
    108       "hour": "6PM",
    109       "percentage": 33
    110     },
    111     {
    112       "hour": "8PM",
    113       "percentage": 5
    114     },
    115     {
    116       "hour": "10PM",
    117       "percentage": 0
    118     }
    119   ],
    120   "status": "open"
    121 }
    122 ```