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
I followed your advice and it worked great.
ReplyDeleteIt save me a lot of hassles.
Kudos!
Glad to share.
DeleteI've been trying to do something like this using IFTTT, and just couldn't get it to work (Strava didn't like the attachment). However, this works a treat. Thanks for sharing.
ReplyDeleteI'll also note I change the script to upload TCX files (as I don't believe GPX files have cadence information in them), which I achieved by doing a global search/replace of "gpx" to "tcx".
DeleteNice! Glad to help out.
DeleteI might have gotten a little obsessed today and expanded your version so that it processes whole threads, archives instead of deletes, and tries to compensate for messages with multiple URLs.
ReplyDelete/**
* Process messages meant for Strava
*/
function uploadToStrava() {
//Call GMail to look for StravaUpload labeled emails
var ulthread = GmailApp.getUserLabelByName('StravaUpload').getThreads();
//Process all threads with label
for (var k = 0; k < ulthread.length; k++) {
//Only operate on threads in Inbox
if (ulthread[k].isInInbox() == 1) {
//Get array of messages in thread
var ulmsg = ulthread[k].getMessages();
//Process all messages in thread
for (var l = 0; l < ulthread[k].getMessageCount(); l++) {
//Get the entire body of the email
var ulbody = ulmsg[l].getBody();
//Calculate start position of extension of tcx
var ulbend = ulbody.indexOf('.tcx');
//Process only if extension (and presumably URL) is present
if (ulbend != -1) {
//Calculate start position of tcx url
var ulbstart = ulbody.indexOf('TCX Link: ');
//Get only substring of link
var ullink = ulbody.substr((ulbstart+10), (ulbend - ulbstart - 6));
//Fetch tcx file from url
var tcxfile = UrlFetchApp.fetch(ullink).getBlob();
tcxfile.getAs('application/tcx+xml');
var tcxname = tcxfile.getName();
tcxfile.setContentType('application/tcx+xml');
tcxfile.setName(tcxname);
//Send email to Strava Upload email with tcx attachment
MailApp.sendEmail( {
to: 'upload@strava.com',
subject: 'Upload to Strava',
htmlBody: "Upload attached.",
attachments: tcxfile
})
}
//Delete Cyclemeter message
//ulmsg[l].moveToTrash();
}
}
//Move Cyclemeter thread to archive
ulthread[k].markRead()
ulthread[k].moveToArchive()
}
};
Nice! I have since built a web app that I can trigger in the event I ride after the trigger so it show up after. So much fun with gapps scripts!
DeleteDoes this still work okay for you guys?
ReplyDeleteI am having real trouble getting the sendEmail function to actually send the mail. It seems to get as far as copying the email to my 'Sent' mail folder but doesn't actually send it. I can view it in the Sent folder and everything looks good. It has all the right information and attachments but the recipient never receives it (and I have tried numerous recipient addresses during testing!).
I have tried using MailApp.sendEmail and GmailApp.sendEmail as I thought the 'replyTo' field might be causing issues but neither seem to work. Same result - mail in Sent folder but never received.
Any help would be appreciated.
I have discovered that the sendEmail functions only appear to work from standard Gmail accounts - not from Google Apps (for Business) accounts. No idea why.
DeleteAnyway I have got it working now through my non-Apps account :-)
Should not matter. I have used this method in both vannilla and GApps accounts. Wonder if the permissions were never granted or are messed up. Are you still having issues?
ReplyDeleteHi,
ReplyDeleteGreat post! I was wondering how the script needs to be modified to work with TCX files. Strava's not seeing any time data in my GPX files, however is working with the TCX files. Is it just a matter of replacing the GPX link with the TCX link?
Thanks!
Chris
http://cjrcycl.es
You would need to change the areas that say GPX in the code to read TCX, make sure Cyclemeter email sends that file instead and change the mime type to match too. There is another comment above that does this as well as a reference.
Delete