Когда я кодировал свой личный веб-сайт, я искал способы персонализировать проект. Я не хотел, чтобы это было просто место для постов в блогах и пошаговых инструкций по проектам. Я хотел поделиться частичкой себя там также.
Имея это в виду, я интегрировал RSS-канал Goodreads, так как книги — одна из моих страстей. Пока я работал над своим портфолио, я также готовился к своему первому полумарафону и пробежал ТОННУ, которую записал на Strava. Я подумал про себя, почему бы не добавить эти данные и на мой сайт?
Я видел, что у них есть API, использующий OAuth2, с которым у меня не было большого опыта. После небольшого количества проб и ошибок, а также различных интернет-ресурсов, я смог все настроить и запустить.
Чтобы сэкономить вам время, я решил написать простое руководство по процессу. Strava предоставляет информацию здесь, но я буду сокращать ее для вас шаг за шагом. Вот документация Strava, если хотите полное изложение.
Давайте начнем!
1. Получите учетные данные приложения из Strava
Первый шаг, который вам нужно сделать, — это зайти в Strava, чтобы зарегистрировать приложение (это намного проще, чем кажется), а затем получить доступ. ключи. URL-адрес для этого может быть трудно найти, поэтому вот он для справки: https://www.strava.com/settings/api.
Когда вы окажетесь там, вам нужно будет заполнить несколько полей, чтобы получить свои учетные данные. Поля, заполненные здесь, не очень важны.
Поле, которое сбило меня с толку, было Authorization Callback Domain
. Это используется только один раз для следующего шага, поэтому вы можете установить его на localhost
, чтобы все заработало. Вам не нужно запускать локальный хост или предпринимать какие-либо дополнительные шаги, чтобы заставить Authorization Callback Domain
работать, просто заполните эту форму localhost
как Authorization Callback Domain
и все.
2. Авторизация учетных данных в браузере
Этот шаг выполняется только один раз и включает посещение определенного URL-адреса в браузере, чтобы вы могли авторизовать использование учетных данных, которые Strava предоставила вам на предыдущем шаге. .
Моей целью при использовании API было использование конечной точки Список действий спортсменов, для которой требуется read_all
доступ. Вам нужно будет выполнить этот шаг для любого уровня доступа, который вы хотите, но следующий URL-адрес будет специально для доступа read_all
.
Что вам нужно сделать здесь, так это вставить этот URL-адрес в свой браузер: // https://localhost/exchange_token?state=&code=1c49f418910a609b0097ae5ce0016c9b8141e8cd&scope=read,activity:read_all
. Идите вперед и укажите URL-адрес с client_id
из вашей учетной записи Strava.
3. Получите код доступа Strava
Отлично! Когда вы перейдете по указанному выше URL-адресу, вам будет предложено авторизовать свой проект в Strava:
Как только вы нажмете Authorize
, вы будете перенаправлены на новый URL-адрес, который выглядит следующим образом: https://localhost/exchange_token?state=&code=1c49xxxxxxxxxxxxxxxxxxxxxxx&scope=read,activity:read_all
.
Вы не увидите ничего отображаемого на этой странице, и это нормально. Все, что вам нужно, это новый URL.
Я отредактировал некоторое значение code
, которое я получил там в качестве параметра запроса, но это поле, которое вы захотите сохранить для следующего шага.
4. Получите токены доступа и обновления Strava
После того, как вы соберете значение code
, вам нужно будет сделать запрос API (вы можете использовать Postman, cURL или любой другой Инструмент запроса API или сервер для этого), чтобы получить актуальную информацию о маркере доступа.
Запрос будет POST для этой конечной точки:
https://www.strava.com/oauth/token
В качестве параметров запроса вы должны указать следующее:
client_id
: вы можете получить это из своей учетной записи Stravaclient_secret
: вы можете получить это из своей учетной записи Strava code
: вы должны были получить это на последнем шаге из URL-адресаgrant_type
: установите это до authorization_code
Полный URL-адрес будет выглядеть так (я отредактировал собственные значения):
https://www.strava.com/oauth/token?client_id=xxxxxxx&client_secret=xxxxxxxxxxxxxxxxxxxxxx&code=1c49xxxxxxxxxxxxxxxxxxxxxxx&grant_type=authorization_code
Если вы используете Postman, вот как должен выглядеть интерфейс:
Выполнение этого запроса приведет к ответу, который выглядит следующим образом:
{ "token_type": "Bearer", "expires_at": 1681350948, "expires_in": 21600, "refresh_token": "25bdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "access_token": "87b0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "athlete": { "id": xxxxxx, "username": "xxxxxxx", "resource_state": 2, "firstname": "Spencer", "lastname": "Attick", "bio": null, "city": "Oakland", "state": "California", "country": "United States", "sex": null, "premium": false, "summit": false, "created_at": "2015-04-01T00:46:54Z", "updated_at": "2023-04-11T18:24:23Z", "badge_type_id": 0, "weight": 0.0, "profile_medium": "https://graph.facebook.com/1226490129/picture?height=256&width=256", "profile": "https://graph.facebook.com/1226490129/picture?height=256&width=256", "friend": null, "follower": null } }
Важными полями, на которые следует обратить внимание, являются expires_at
, refresh_token
и access_token
.
access_token
Strava истечет в expires_at
времени, которое является отметкой времени эпохи Unix. Мы поговорим об обновлении позже, а пока давайте получим данные Strava.
5. Получить данные о тренировках из Strava
Хорошо! Наконец-то мы можем сделать запрос на получение нужных нам данных из Strava!
Здесь вам нужно сделать запрос GET, который выглядит следующим образом:
curl --location 'https://www.strava.com/api/v3/athlete/activities' \ --header 'Authorization: Bearer <ACCESS_TOKEN>'
Вы будете использовать access_token
, который вы получили выше, в качестве жетона носителя здесь. Убедитесь, что у вас вообще нет тела запроса для этого шага, так как это вызовет ошибку.
Посмотрите ответ на этот запрос. У вас есть данные Strava, с которыми вы можете работать! Вы можете добавить это на свой личный веб-сайт, создать панель тренировок для себя, создать таблицу лидеров с друзьями или что-то еще, что вы можете придумать!
7. Управление обновлением токена доступа
Последнее, о чем мы хотим позаботиться, — это убедиться, что вы можете обновить свой токен по истечении срока его действия. Для этого вам нужно отслеживать последнее полученное поле expires_at
. Когда текущее время больше, чем значение значения expires_at
, пришло время для нового access_token
.
Вы сделаете этот запрос POST, чтобы получить новый токен:
curl --location --request POST 'https://www.strava.com/oauth/token
Вот параметры запроса, которые вы будете использовать, и их значения:
client_id
: вы можете получить это из своей учетной записи Stravaclient_secret
: вы можете получить это из своей учетной записи Strava code
: вы должны были получить это на последнем шаге по URL-адресуgrant_type
: установите это to refresh_token
:
refresh_tokenrefresh_token
из вашего последнего успешного запроса аутентификации
Вот полный запрос с заданными параметрами запроса:
?client_id=xxxxxxx&client_secret=xxxxxxxxxxxxxxxxxxxxxx&grant_type=refresh_token&refresh_token=25bd1cf38exxxxxxxxxxxxxxxxxxxxx'
Ответ будет выглядеть так:
{ "token_type": "Bearer", "access_token": "6e6e9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "expires_at": 1681430228, "expires_in": 21600, "refresh_token": "25bdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }
Теперь все готово! Вы можете отправлять запросы в Strava, чтобы получить значимые данные о своих действиях, и вы можете создать новый токен доступа!
Отсюда вы захотите собрать все вместе во что-то, что вы можете использовать на своем сервере. Вот код, который я использую для интеграции Strava, который я написал для своего личного веб-сайта:
const isStravaTokenExpired = (currentExpirationTime) => { const currentEpochTime = Date.now(); if (currentExpirationTime === 'undefined') { return `There is an error with the currentEpirationTime, it's value is: ${currentExpirationTime}.` } return currentEpochTime > currentExpirationTime; } const generateNewToken = async () => { console.log('Generating new token...'); const requestOptions = { method: 'POST', redirect: 'follow' }; const requestURL = `https://www.strava.com/oauth/token?client_id=${process.env.STRAVA_CLIENT_ID}&client_secret=${process.env.STRAVA_CLIENT_SECRET}&grant_type=refresh_token&refresh_token=ReplaceWithRefreshToken&refresh_token=${process.env.STRAVA_CACHED_REFRESH_TOKEN}`; try { let response = await fetch(requestURL, requestOptions); response = await response.json(); if (response.message === 'Bad Request') { console.log(response); return; } return { refreshToken: await response.refresh_token, expirationTime: await response.expires_at, accessToken: await response.access_token } } catch (error) { console.log(error); } } const persistNewTokenData = async (newTokenData) => { // Read the .env file const envBuffer = fs.readFileSync('.env'); const envConfig = dotenv.parse(envBuffer); // Update the relevant key with the new value envConfig['STRAVA_EXPIRATION_TIME'] = newTokenData.expirationTime, envConfig['STRAVA_CACHED_REFRESH_TOKEN'] = newTokenData.refreshToken, envConfig['STRAVA_CACHED_TOKEN'] = newTokenData.accessToken // Write the updated key-value pair to the file const envText = Object.keys(envConfig).map(key => `${key}=${envConfig[key]}`).join('\n'); await fs.promises.writeFile('.env', envText); }; const getStravaActivityData = async () => { console.log('Requesting activity data from Strava...'); let myHeaders = new Headers(); myHeaders.append("Authorization", `Bearer ${process.env.STRAVA_CACHED_TOKEN}`); const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; try { const response = await fetch("https://www.strava.com/api/v3/athlete/activities", requestOptions); return response.json(); } catch (error) { console.log('error', error) } } //check to see if the expiration time has passed const executeStravaLogic = async () => { const isTokenExpired = isStravaTokenExpired(process.env.STRAVA_EXPIRATION_TIME); if (typeof isTokenExpired === 'string') { console.log('Please resolve the error with the current expiration time stored in the .env file.'); return; } else if (isTokenExpired) { console.log('The expiration time has passed. Generating a new token...'); //if yes - generate a new token const newTokenData = await generateNewToken(); if (!newTokenData.expirationTime) { console.log('There was an error getting refresh token data.') return; } //save the new token info to .env persistNewTokenData(newTokenData); } //make request to Strava activities endpoint const stravaActivityData = await getStravaActivityData(); return stravaActivityData; }; app.get('/api/strava', executeStravaLogic);
Не стесняйтесь использовать то, что работает для вас, и отказываться от того, что не работает.
Наслаждаться!
Повышение уровня кодирования
Спасибо, что являетесь частью нашего сообщества! Перед тем, как ты уйдешь:
- 👏 Хлопайте за историю и подписывайтесь на автора 👉
- 📰 Смотрите больше контента в публикации Level Up Coding
- 💰 Бесплатный курс собеседования по программированию ⇒ Просмотреть курс
- 🔔 Подписывайтесь на нас: Twitter | ЛинкедИн | "Новостная рассылка"
🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите прекрасную работу