Sunday, July 7, 2013

Cyclemeter Upload to Strava with Google Apps Script

As a long time Cyclemeter user I have logged about 6000 off-road miles and love the app and it's feature set.  When Strava made it way onto the scene, I was impressed with the community and analytic features that were offered but since Strava has their own mobile apps I have waited long enough for Cyclemeter to add a direct auto-share to their app so I wrote a Google Apps Script to do this for me.

If you use GMail, you are in luck since Google give you Apps Script to add some major automation to a number of their services.  Here is how I did it...

Step 1: Setup Cyclemeter to email you the GPX link to your GMail account.  Go to More -> Settings -> Email Updates (turn on) ->Auto Send Settings -> Done ->Just add the GPX link to the email.


Step 2: Then in GMail setup a filter to label these emails "StravaUpload" by selecting specific information in the Subject.  In my case I used " Cyclemeter Cycle (Mountain)" so it only uploads my MTB rides and not my other activities like runs.  I am going to assume you know how to add filters and labels in GMail.


Step 3: Now the Script.  This part might be a stretch for some but I will share a simple way to do this.  Google Apps Scripts can exist on their own in Google Drive but to create them you need to connect the Google Apps Script to Drive by clicking on the "Connect More Apps" link at the bottom and searching for "Google Apps Script".  You can also create a Doc or Sheet and go to the "Tools" menu and select "Script Editor".  I write a lot of code for GAS so I use the direct method.  Either way, you can get into the script editor and add this function:

 function uploadToStrava() {  
  //Call GMail to look for StraveUpload labeled emails (should only be one)  
  var ulemail = GmailApp.getUserLabelByName('StravaUpload').getThreads();  
  //Quit if email is missing  
  if (ulemail.length != 0){  
   //Get only the first email in the matching array  
   var ulmessage = ulemail[0].getMessages();  
   //Get the entire body of the email  
   var ulbody = ulmessage[0].getBody();  
   //Calculate start position of gpx url  
   var ulbstart = ulbody.indexOf('http://share.abvio.com/');  
   //Calculate start position of extension of gpx  
   var ulbend = ulbody.indexOf('.gpx');  
   //Get only substring of link  
   var ullink = ulbody.substr(ulbstart, (ulbend - ulbstart+4));  
   //Fetch gpx file from url  
   var gpxfile = UrlFetchApp.fetch(ullink).getBlob();  
   gpxfile.getAs('application/gpx+xml');  
   var gpxname = gpxfile.getName();  
   gpxfile.setContentType('application/gpx+xml');  
   gpxfile.setName(gpxname);  
   //Send email to Strava Upload email with gpx attachment  
   MailApp.sendEmail( {  
    to: 'upload@strava.com',  
    subject: 'Upload to Strava',   
    htmlBody: "Upload attached.",  
    attachments: gpxfile  
   })  
   //Move Cyclemeter email to trash  
   ulmessage[0].moveToTrash();  
  }  
 }  

Since Cyclemeter does not create an attachment in the Auto Send options, I had to get the URL and get the attachment from the link.  Now we need this script to trigger daily... I also didn't care for it to parse a number of rides at once so I left out the looping for uploads for now. 

Step 4: Trigger the script to run at whatever interval you like.  I usually ride in the am so I had the script trigger between 9 - 10am but you can pick the interval you like.


Now I can complete my ride, hit Done in Cyclemeter and my email will send and once the trigger for the GAS runs, the email is evaluated, an email is sent to Strava's upload email with a GPX attachment and my ride shows up in Strava without me having to manually upload it.  Works for me but I hope Cyclemeter adds this into the app or simply adds email GPX attachments in their auto share settings.  Hope this helps you. ~Lou