Уже полгода хожу в фитнес клуб World Class или как пишут в самом клубе - являюсь его резидентом. Выбрал этот клуб в основном из-за наличия в нём бассейна. Потом заинтересовался групповыми программами и частенько хожу на сайкл тренировки - это тренировки на специальном велотренажере.
И единственное меня раздражает, что для просмотра расписания занятий на следующую неделю каждый раз приходилось идти на сайт сети Ворд Класс, переходить в мой клуб, отбиваться от нескольких назойливых баннеров которые предлагают перезвонить через 3 секунды для того чтобы стать их клиентом. И только после этого найти в огромном расписании несколько строчек которые я ищу. На неделе таких занятий может проходить несколько и я вносил их в свой календарь, чтобы сходить хотя бы на одно в неделю.
Вся это операция с поиском и занесением в календарь занимала минут 15. И так каждую неделю.
В какой-то момент мне это надоело и я подумал, а не парсить ли расписание и добавлять в свой календарь занятия на сайкле автоматически?
Некоторым препятствием стало то, что сайт World Class динамически загружает контент с помощью JavaScript после начальной загрузки страницы. Зато нашлась конечная точка API и теперь занятия по сайклу каждый понедельник ночью добавляются в мой календарь за 3 секунды работы скрипта вместо 15 минут моей жизни каждую неделю.
Веб-сайт с общедоступным расписанием клуба World Class
На сайте используется динамическая загрузка контента с помощью JavaScript. Это значит что сайт, который динамически загружает контент с помощью JavaScript после первоначальной загрузки страницы, - это тот, на котором не вся информация сразу доступна при первом появлении страницы. Вместо этого дополнительные данные или контент извлекаются с сервера и отображаются по мере взаимодействия со страницей. Этот метод обычно используется в современных веб-приложениях. Это устраняет необходимость перезагружать всю страницу и делает процесс более быстрым и плавным для пользователя.
Конечная точка API - это определенный URL-адрес, который позволяет внешним приложениям взаимодействовать с ним. API позволяют различным программным системам взаимодействовать друг с другом, отправляя запросы и получая ответы.
Когда взаимодействую с сайтом, который динамически загружает контент, то сайт часто запрашивает данные со своего сервера с помощью API. Сервер обрабатывает запрос и возвращает необходимые данные, которые затем отображаются на веб-странице. В контексте фитнес-клуба World Class конечной точкой API будет определенный URL-адрес, который предоставляет данные о расписании занятий. Отправив запрос на эту конечную точку, можно получить данные о расписании напрямую, минуя необходимость вручную перемещаться по сайту.
Поворотный момент и техническая проблема
В какой-то момент я наткнулся на чистую ссылку, которая ведёт только на само расписание фитнес-клуба World Class без любой рекламы. Ссылка выглядит следующим образом:
https://my.worldclass.ru/scheduling?clubs=d35ba5fc-1f7e-11ec-b664-50e548298f06
Где вместо d35ba5fc-1f7e-11ec-b664-50e548298f06
должен стоять идентификатор вашего клуба. Выше это идентификатор клуба в городе Перми.
Все доступные идентификаторы других клубов можно посмотреть прямо в браузере в режиме просмотра страницы:
Поскольку World Class динамически загружает расписание с помощью JavaScript после начальной загрузки страницы, то стало некоторой проблемой найти конечную точка API и обратиться к ней за этим общедоступным и свободно опубликованным в интернете расписанием.
ICG Color Cycle (сайкл)
В пермском клубе World Class не обязательно записываться на занятия по сайклу заранее - достаточно прийти примерно за полчаса до занятия и взять на входе черную карточку для участия - места есть до тех пор пока карточки не закончатся. Правда бывают приходят и те кто записались онлайн, но карточку не взяли - просто не знали про это и мест не хватает. Это некоторая путаница.
Создание решения
Поскольку я использую Гугл календарь, то написал Google Apps скрипт. Apps Script - платформа на основе JavaScript для быстрой и простой разработки решений.
Скрипт может значительно упростить работу пользователя, избавив его от необходимости вручную проверять расписание и добавлять занятия в свой Гугл календарь.
Скрипт работает следующим образом:
-
Получение расписания: скрипт отправляет запрос в API World Class с идентификатором определенного спортзала. Далее извлекает расписание на следующие семь дней.
-
Фильтрация соответствующих занятий: после извлечения расписания скрипт отфильтровывает занятия «ICG Color Cycle» и «CORE», которые я хочу посещать. Все дальнейшие действия происходят только для отобранной выборки.
-
Создание событий календаря: для каждой отфильтрованной тренировки скрипт автоматически создает событие в Google календарь по умолчанию (можно задать любой календарь, я уже писал ранее про работу с календарями). Каждое событие включает:
-
Название: название тренировки (в моём случае либо «ICG Color Cycle», либо «CORE»).
-
Продолжительность: каждое событие запланировано на один час.
-
Описание: подробное объяснение зачем нужна эта тренировка.
-
Расположение: конкретный адрес клуба World Class, где проходит занятие.
-
Ведение журнала и обработка ошибок: скрипт регистрирует свой ход выполнения, указывая, когда он начинается и заканчивается, и предоставляя подробную информацию о каждом созданном событии. Если запрос API не выполняется или возвращает ошибку, скрипт регистрирует сообщение об ошибке для устранения неполадок.
По сути, этот скрипт - инструмент экономии времени для резидентов клуба World Class, которые могут быть уверены, что всегда будут знать когда проходят их любимые занятия:
function WorldclassAPISchedulingPerm() {
console.log(`Функция WorldclassAPISchedulingPerm начала работу в ${(new Date()).toLocaleString("ru-RU")}`);
//https://habr.com/ru/articles/838322/
const url = 'https://my.worldclass.ru/api/v1/clubs/scheduling';
const currentDate = new Date();
const endDate = new Date(currentDate);
endDate.setDate(currentDate.getDate() + 7);
const payload = {
"gymList": [
"d35ba5fc-1f7e-11ec-b664-50e548298f06" // это World Class в Перми
],
"startDate": currentDate.toISOString().split('.')[0],
"endDate": endDate.toISOString().split('.')[0],
"chain": 1,
"token": "70a69ca6-XXXX-XXXX-XXXX-005056b1372d" // здесь надо указать токен, узнать можно в DevTools Chrome на скриншоте выше
};
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
muteHttpExceptions: true,
headers: {
'brand': 'WorldClass',
'language': 'Ru',
'chain': '1',
'Accept': '*/*',
'Origin': 'https://my.worldclass.ru',
'Referer': 'https://my.worldclass.ru/scheduling?clubs='
},
timeoutSeconds: 30
};
try {
const response = UrlFetchApp.fetch(url, options);
const responseCode = response.getResponseCode();
console.log(`Код ответа: ${responseCode}`);
const responseText = response.getContentText();
const responseData = JSON.parse(responseText); // Разбираем JSON-строку
if (responseCode === 200) {
// Фильтрация для "ICG Color Cycle (сайкл)" и "CORE"
const filteredDates = responseData.data
.filter(item => item.service.name === "ICG Color Cycle (сайкл)" || item.service.name === "CORE")
.map(item => ({
name: item.service.name,
startDate: item.startDate
}));
console.log('Отфильтрованные даты:', filteredDates);
// Создаем события в календаре для каждой отфильтрованной даты
filteredDates.forEach(eventData => {
const startTime = new Date(eventData.startDate);
const endTime = new Date(startTime);
endTime.setHours(startTime.getHours() + 1); // Устанавливаем продолжительность события на 1 час
let eventTitle = eventData.name;
let eventDescription = '';
if (eventData.name === "ICG Color Cycle (сайкл)") {
eventDescription = 'ICG Color Cycle (сайкл тренировка с индивидуальными мониторами с мультимедийной системой ICG для визуализации данных и создания увлекательных программ. В зависимости от ваших данных мощности и сердечного ритма, которые фиксируются в режиме реального времени, для вас формируется оптимальная нагрузка в пяти цветовых зонах (белой, синей, зеленой, желтой и красной). Эти цвета зажигаются на передней панели – и отлично видны тренеру, который контролирует группу.';
} else if (eventData.name === "CORE") {
eventDescription = 'CORE тренировка фокусируется на укреплении центральной части тела, включая мышцы брюшного пресса и поясницы. Занятие направлено на повышение стабильности и силы всего тела.';
}
CalendarApp.getDefaultCalendar().createEvent(
eventTitle,
startTime,
endTime, {
description: eventDescription,
location: 'Фитнес клуб World Class, Пермская ул., 33, Пермь, Пермский край, Россия, 614045'
}
);
console.log(`Событие создано для: ${startTime} - ${eventTitle}`);
});
} else {
console.error(`Ошибка: получен статус ${responseCode} с ответом: ${responseText}`);
}
} catch (error) {
console.error('Ошибка запроса:', error.message);
}
console.log(`Функция WorldclassAPISchedulingPerm закончила работу в ${(new Date()).toLocaleString("ru-RU")}`);
}
Я не хожу на каждое занятие, а просто смотрю в календарь и когда намечается окно в моей деятельности - иду на ближайшее.
Как Вы можете воспользоваться этим скриптом?
Если вы новичок и хотите тоже автоматизировать получение определенных занятий, то скрипт Google Apps это мощный инструмент, который может вам помочь:
Шаг 1: Доступ к скрипту Google Apps
-
Откройте Google Drive: начните с перехода на Google Drive.
-
Создайте новый скрипт:
-
Нажмите кнопку Создать в верхнем левом углу.
-
Выберите Еще в раскрывающемся меню.
-
Нажмите Скрипт Google Apps. Откроется редактор скриптов Google Apps на новой вкладке.
Шаг 2: Назовите свой проект
-
Назовите свой скрипт: как только откроется редактор скриптов приложений, вы увидите проект без названия. Нажмите на заголовок (обычно это «Проект без названия») и дайте ему осмысленное имя, например «Расписание World Class».
Шаг 3: Скопируйте код
-
Удалите код по умолчанию: в редакторе вы увидите код по умолчанию (
function myFunction() {}
). Вы можете удалить его, чтобы освободить место для нового скрипта. -
Скопируйте и вставьте код:
-
Перейдите к статье с кодом скрипта Google Apps.
-
Скопируйте весь скрипт, предоставленный в статье.
-
Вернитесь в редактор скриптов приложений и вставьте код в пустое место.
Шаг 4: Сохраните свой скрипт
-
Сохраните свою работу: Щелкните значок дискеты или нажмите
Ctrl + S
(илиCmd + S
на Mac), чтобы сохранить свой скрипт.
Шаг 5: Запустите скрипт
-
Запустите свой скрипт: Чтобы протестировать скрипт, щелкните значок воспроизведения (▶) в верхней части редактора. Если вы запускаете скрипт впервые, Google запросит авторизацию.
-
Авторизуйте свой скрипт: Следуйте инструкциям, чтобы разрешить скрипту доступ к вашему Google Calendar и другим необходимым службам.
Шаг 6: Проверьте вывод
-
Проверьте журналы: После запуска скрипта вы можете проверить сообщения журнала, чтобы убедиться, что он работает правильно. Перейдите в
Просмотр > Журналы
в редакторе скриптов приложений, чтобы увидеть вывод.
Шаг 7: Автоматизируйте его
-
Установите триггер: если вы хотите, чтобы этот скрипт запускался автоматически через регулярные интервалы, вы можете настроить триггер:
-
Нажмите на значок часов на панели инструментов (Триггеры).
-
Нажмите + Добавить триггер в правом нижнем углу.
-
Установите запуск скрипта еженедельно, например на ночь между понедельником и вторником.
И это все! Вы успешно создали скрипт Google Apps, который автоматизирует добавление расписания в ваш календарь Google.
Результаты
При использовании использования гугл календаря этот скрипт представляет удобный инструмент который ищет интересующие групповые события и добавляет их автоматически в Ваш собственный Гугл Календарь.
Автор: Михаил Шардин,
2 сентября 2024 г.
Автор: empenoso