-
-
Save eopo/9344584035f487db0e229d655bdb39c4 to your computer and use it in GitHub Desktop.
/** | |
* Script for scriptable to get the current capacity of FitnessFirst Gyms | |
*/ | |
let gymId = 'essen1' | |
let param = args.widgetParameter | |
if (param != null && param.length > 0) { | |
gymId = param | |
} | |
const currentGymCapacity = await fetchGymCapacity(gymId) | |
const storeInfo = await fetchGymInfo(gymId) | |
const gymName = await fetchGymInfo(gymId) | |
const widget = new ListWidget() | |
await createWidget() | |
if (!config.runsInWidget) { | |
await widget.presentSmall() | |
} | |
Script.setWidget(widget) | |
Script.complete() | |
//Create the widget | |
async function createWidget() { | |
const headlineText = widget.addText("🏋️ Capacity") | |
headlineText.font = Font.mediumRoundedSystemFont(19) | |
widget.addSpacer() | |
const widgetStack = widget.addStack() | |
widgetStack.layoutVertically() | |
widgetStack.bottomAlignContent() | |
const capacityText = widgetStack.addText(currentGymCapacity.toString() + "%") | |
capacityText.font = Font.mediumRoundedSystemFont(50) | |
if (currentGymCapacity < 20) { | |
capacityText.textColor = new Color("#33cc33") | |
} else if (currentGymCapacity < 30){ | |
capacityText.textColor = new Color("#ff9900") | |
}else{ | |
capacityText.textColor = new Color("#ff3300") | |
} | |
widgetStack.addSpacer(1) | |
const gymNameText = widgetStack.addText(gymName) | |
gymNameText.font = Font.regularSystemFont(12) | |
} | |
//Fetches the current capacity of the John Reed gym | |
async function fetchGymCapacity(id) { | |
const url = 'https://www.fitnessfirst.de/club/api/checkins/' + id | |
const req = new Request(url) | |
const result = await req.loadJSON() | |
return Math.round(result.data.check_ins*100/ result.data.allowed_people) | |
} | |
//Fetches the name of the gym | |
async function fetchGymInfo(id) { | |
const url = 'https://www.fitnessfirst.de/api/v1/node/club_page?include=field_features,field_opening_times&filter[status][value]=1&page[limit]=40&sort=title' | |
const req = new Request(url) | |
const apiResult = await req.loadJSON() | |
for (var i in apiResult.data){ | |
if(apiResult.data[i].attributes.field_easy_solution_club_id == id) | |
{ | |
return apiResult.data[i].attributes.title; | |
} | |
} | |
return 'Your Gym' | |
} |
Thank you!
One studio to add to your list:
Studio | ID |
---|---|
München Haidhausen | muenchen6 |
I also adjusted the page[limit]=40
to 100 for my studio to be part of the result set.
Another nice thing i figured out. If you have the Fitness First App you can set the widget interaction to "URL" and the URL to com.netpulse.fitnessfirst://
that will open the App when you tap on the widget
Thank you.
It seems like the API has changed in 2023, according to this post.
I don't know JavaScript, but I managed to fix the widget for my case.
The gymId
can now be discovered by following the procedure from the post linked above:
Visit your club’s website (e.g. https://www.fitnessfirst.de/clubs/hamburg-mitte-jungfernstieg 6)
Open Developer Console (F12) and search fordata-club
belowblock-clubcheckinsblock
. You’ll need to copy that number fromdata-club
(e.g. 1376532610)
Alternatively, reload the page with open network tab and you should see a request with a number (e.g. 1376532610).
GymID for München Haidhausen: 1363429860
I also needed to change the function that accesses the JSON file (thanks to ChatGPT).
My entire code looks like this (you need to change gymId
and the gymNameText
for your studio):
/**
* Script for scriptable to get the current capacity of FitnessFirst Gyms
*/
let gymId = '1363429860'
let param = args.widgetParameter
if (param != null && param.length > 0) {
gymId = param
}
const currentGymCapacity = await fetchGymCapacity(gymId)
//const storeInfo = await fetchGymInfo(gymId)
const widget = new ListWidget()
await createWidget()
if (!config.runsInWidget) {
await widget.presentSmall()
}
Script.setWidget(widget)
Script.complete()
//Create the widget
async function createWidget() {
const headlineText = widget.addText("🏋️ Capacity")
headlineText.font = Font.mediumRoundedSystemFont(19)
widget.addSpacer()
const widgetStack = widget.addStack()
widgetStack.layoutVertically()
widgetStack.bottomAlignContent()
const capacityText = widgetStack.addText(currentGymCapacity.toString() + "%")
capacityText.font = Font.mediumRoundedSystemFont(50)
if (currentGymCapacity < 30) {
capacityText.textColor = new Color("#33cc33") //green
} else if (currentGymCapacity < 50){
capacityText.textColor = new Color("#ff9900")//orange
}else{
capacityText.textColor = new Color("#ff3300")//red
}
widgetStack.addSpacer(1)
const gymNameText = widgetStack.addText("FF Haidhausen")
gymNameText.font = Font.regularSystemFont(12)
}
async function fetchGymCapacity(id) {
const url = 'https://www.fitnessfirst.de/club/api/checkins/' + id;
const req = new Request(url);
const result = await req.loadJSON();
// Find the current time slot and get its percentage
const currentTimeSlot = result.data.items.find(item => item.isCurrent);
return currentTimeSlot ? currentTimeSlot.percentage : null;
}
Fork of https://gist.github.com/masselmello/6d4f4c533b98b2550ee23a7a5e6c6cff
How to use: