Retrieving your Strava data with Google App Scripts

I run whenever I can. I use Strava to record my run. I check the speed, my heart rate, and the ranking of my run. I like looking at all the graphs. There is one data I’d like to check but doesn’t exist in Strava. I would like to see the graph of the average heart rates vs runs and the max hearts vs runs.

Strava has an API through which you can retrieve all sorts of data. I’ve been thinking of doing this for months but I’ve been postponing it because you have to connect to the API with OAuth2. It has been always a pain in the arse for me to authenticate through OAuth2. If something goes wrong and you can’t connect, you never receive a meaningful error because of ‘security reasons’.

Nevertheless last week, I finally decided to work on this. I decided to use Google App Scripts to retrieve the data and a Google Spreadsheet to save and visualize the data. To my surprise I found a OAuth2 library by Google for Google App Scripts. I found an example code for Github. I gave it a try. And it worked like a charm.

I retrieved my runs. Extracted the running time, average heart rate and maximum heart rate data. Inserted it in a script. Plotted it in the spreadsheet. To have up-to-date data, I added a trigger that retrieves the data every hour to Google App Scripts.

Here is what you need to do if you’d like to implement this yourself.

  1. Create a Google Apps Script project.
    1. Open Chrome and install the Google Apps Script extension.
    2. Open Google Drive, and click New > More > Google Apps Script.I called the file StravaData.
  2. Create a Spreadsheet for storing the data and for the graph. I named this one StravaData as well.
  3. Now the very big step: Connecting to the Strava API through OAuth2.
    1. I opened the Google Apps Script project I created. This is what you should see:
    2. I copied the sample code and changed it for Strava.
    3. For the code to run we need to add a library. In the Google App Scripts menu go to Resources>Libraries and Add Library with the script id 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF.  (See the Setup part in https://github.com/googlesamples/apps-script-oauth2)
    4. To be able to connect to Strava, I need to have a ClientId and Client Secret from Strava. So I created an application in the Strava Developer Web App.
      1. Login to Strava.
      2. Go to https://www.strava.com/settings/api . Create an app.
      3. Copy the the Client Id and Client Secret into the script.
    5. For OAuth2 to run we need to have a link that we can send to Strava that it can call after the authentication. This is called the callback.
      1. First we need to publish our Google App Scripts project. You can do this by going to Publish > Deploy as Web App. In the window that opens choose Project version as “New”, Execute the app as “Me”, and “Who has access to the app” should be “Anone, even anonymous”, so that the Strava Authentication can call the callback link.
      2. There is one more setting in Strava. You need to tell Strava the domain of the callback link. Go to https://www.strava.com/settings/api . Scroll down the page and enter “script.google.com” for “Authorization Callback Domain”
    6. Now the final step. Run the function that connects to Strava.
      1. In the menu above the Google App Scripts project, choose run and click the Play icon.
      2. If you read the code in the run function, you’ll see that it logs the link for Strava authorization. So now we have to check the logs to find the link. Go to View > Logs. A new window will open up. You’ll see the log and the link.
      3. Go to the link in the logs. This will authenticate against the Strava API. You should be redirected to the page that says “Success!”
  4. Retrieve the data.
    1. Before you retrieve the data you need to enter two more information about the Spreadsheet. First you need to enter the SPREADSHEET_ID. You can find the spreadsheet id from the spreadsheet url. The part between /d/ and /edit/ is the spreadsheet id. https://docs.google.com/spreadsheets/d/<SpreadsheetId>/edit#gid=0

      var SPREADSHEET_ID = “1-u1X8jS8rfasfasdfasfyozUd9aqKnwftAaoSuIgkJI4”;
      var SHEET_NAME = “Sheet1”;

      The Sheet_Name is Sheet1 if you haven’t changed the default name.

    2. Run the function to retrieve your data. Choose the function “retrieveData” and run it. 
    3. Go and check your spreadsheet. You should be able to see the data.
  5. Now you can easily visualize your data in the Spreadsheet.
    1. Go to Insert > Graph.
    2. I chose the line graph. And this is the result.Yaayyy!
  6. Whenever you’d like to retrieve new data you need to run the retrieveData function. You can also setup a trigger in the Google App Script project, so that the data is retrieved automatically. I setup an hourly trigger. (Strava changed its authentication mechanism, check step 7 too.)
    1. Go to Edit > Current Project’s Triggers.
    2. Add new trigger. Choose “retrieveData” and the frequency that the function should be called. 
  1. Strava updated its authentication mechanism. They used to give you tokens that were forever valid. The new token is valid for 6 hours, and if you want to access your data without authenticating again, you need to refresh after the 5th hour until the 6 hours are over. I use an hourly trigger.

That’s it. Let me know if you run into issues.

How to retrieve data other than AvgHeartRate, MaxHeartRate

Find the names of the data you would like to retrieve from this page (On the right side, under Sample Response):  https://developers.strava.com/docs/reference/#api-Activities-getLoggedInAthleteActivities

Let’s say we would like to add ‘distance’. Add it to the end of the DATA_FIELDS list. Also add a heading for the item in the sheet at the end of the HEADING_FOR_DATA_FIELDS list.

var DATA_FIELDS = [‘start_date_local’, ‘max_heartrate’, ‘average_heartrate’, ‘distance’];
var HEADING_FOR_DATA_FIELDS = [‘Date’, ‘MaxHeartRate’, ‘AvgHeartRate’, ‘Distance’];

Strava returns the distance in meters. I added a code to convert it to kms. If you don’t want that you should remove the code below which is in the convertData function.

//distance is returned in meters, that’s why I divide it into 1000 to have kms
if (field_name == ‘distance’) {
single_data = single_data/1000;
}

Retrieving more data and filtering by type

I updated the code so now you can:

  • retrieve data without heart rate just by setting a variable at the top of the code,
    • var ONLY_WITH_HEARTRATE = false;
  • retrieve more details about the activity, such as the ‘description’ field,
    • var RETRIEVE_DETAILS = true;
  • filter to retrieve activities by only one type.
    • var FILTER_BY_TYPE = “Ride”;

/* If you want to retrieve details such as ‘description’ you need to make the value of RETRIEVE_DETAILS = true; */
var RETRIEVE_DETAILS = false;
var ONLY_WITH_HEARTRATE = true;
/* If you want to retrieves only one type of activity, you should write the activity type below. Ex: var FILTER_BY_TYPE = “Ride”; */
var FILTER_BY_TYPE = “”;

62 Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.