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  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 ```