Get Strava activity and stats

This is a sample flow to display strava activities and stats in the UI. Include the last track as image.

One flow with http request. Two flows with strava api access token.

Modify the design with CSS. Insert your api token and your athlete id in the marked nodes.

[{"id":"6150bb62.28c0f4","type":"html","z":"b8c0412b.95d0a","name":"","property":"payload","outproperty":"payload","tag":"#activity-totals","ret":"html","as":"single","x":727.87890625,"y":358.5859375,"wires":[["1ac9e2ce.0abd1d"]]},{"id":"ad51c440.72c268","type":"ui_template","z":"b8c0412b.95d0a","group":"37541ec6.84e1a2","name":"Month ride totals","order":2,"width":"0","height":"0","format":"<div><h3>Current month</h3></div>\n<div ng-bind-html=\"msg.payload\"></div>\n\n<style>\n    {{msg.style}}\n</style>\n\n\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":1069.9921875,"y":357.59368896484375,"wires":[["f9bd8b33.c8ba18"]]},{"id":"b1f41f83.88fce","type":"function","z":"b8c0412b.95d0a","name":"","func":"sec = msg.payload.ytd_ride_totals.moving_time;\nhr = Math.floor(sec / 3600);\nmin = Math.floor((sec % 3600) / 60);\ndistance =  Math.floor(msg.payload.ytd_ride_totals.distance/1000);\nelevation = Math.floor(msg.payload.ytd_ride_totals.elevation_gain);\n\n\nmsg.payload = {\n  ytd_ride_totals: {\n    distance: distance,\n    elevation: elevation,\n    moving_time: {\n      hr: hr,\n      min: min,\n    },\n  }\n}\n\nreturn msg;\n\n\n\n\n\n","outputs":1,"noerr":0,"x":698.9765625,"y":443.66400146484375,"wires":[["1622bf4a.bd0471"]]},{"id":"2d81246d.a0236c","type":"ui_template","z":"b8c0412b.95d0a","group":"37541ec6.84e1a2","name":"Years ride totals","order":3,"width":"0","height":"0","format":"<div>\n    <h3>Total rides this Year</h3>\n    <ul class=\"inline-stats\" id=\"activity-totals\">\n        <li>\n            <strong>{{msg.payload.ytd_ride_totals.distance}}<abbr class=\"unit\" title=\"Kilometer\">km</abbr></strong><div class=\"label\">DISTANCE</div>\n        </li>\n        <li>\n            <strong>{{msg.payload.ytd_ride_totals.moving_time.hr}}<abbr class=\"unit\" title=\"Stunde\">h</abbr> {{msg.payload.ytd_ride_totals.moving_time.min}}<abbr class=\"unit\" title=\"Minute\">min</abbr></strong>\n            <div class=\"label\">TIME</div>\n        </li>\n        <li>\n            <strong>{{msg.payload.ytd_ride_totals.elevation}}<abbr class=\"unit\" title=\"Meter\">m</abbr></strong><div class=\"label\">ELEVATION</div>\n        </li>\n    </ul>\n</div>\n<style>\n    {{msg.style}}\n</style>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":1046.4765625,"y":442.66400146484375,"wires":[["f9bd8b33.c8ba18"]]},{"id":"1ac9e2ce.0abd1d","type":"template","z":"b8c0412b.95d0a","name":"css","field":"style","fieldType":"msg","format":"css","syntax":"mustache","template":"\n.nr-dashboard-template li {\n    display:inline-block;\n    list-style-type: none;\n    font-size: 16px;\n    font-weight: 300;\n    color: #99999e;\n    overflow: auto;\n    padding: 5px;\n}\n\n.nr-dashboard-template {\n    height: auto !important;\n    text-align: center;\n}\n\n\n\n\n\n","output":"str","x":907.4765625,"y":357.66400146484375,"wires":[["ad51c440.72c268"]]},{"id":"1622bf4a.bd0471","type":"template","z":"b8c0412b.95d0a","name":"css","field":"style","fieldType":"msg","format":"css","syntax":"mustache","template":"#activity-totals{\n    padding: 5px;\n}\n\nabbr {\n    text-decoration: none;\n}\n\n\n","output":"str","x":858.4765625,"y":442.66400146484375,"wires":[["2d81246d.a0236c"]]},{"id":"b072f7f6.d06958","type":"function","z":"b8c0412b.95d0a","name":"","func":"moving_time = msg.payload[0].moving_time;\nhr = Math.floor(moving_time / 3600);\nmin = Math.floor((moving_time % 3600) / 60);\nsec = Math.floor(moving_time % 60);\ndistance =  (msg.payload[0].distance/1000).toFixed(2);\n\nelevation = Math.floor(msg.payload[0].total_elevation_gain);\nname = msg.payload[0].name;\nkudos = msg.payload[0].kudos_count;\nheartrate = msg.payload[0].average_heartrate;\ntemp = msg.payload[0].average_temp;\npolyline = msg.payload[0].map.summary_polyline;\n\nurl = \"https://maps.googleapis.com/maps/api/staticmap?size=400x400&path=weight:3%7Ccolor:0xFC4C02FF%7Cenc:\";\nurl += polyline;\n\nmsg.payload = {\n  last_ride: {\n    name: name,\n    distance: distance,\n    elevation: elevation,\n    heartrate: heartrate,\n    kudos: kudos,\n    temp: temp,\n    moving_time: {\n      hr: hr,\n      min: min,\n      sec: sec,\n    },\n    polyline : polyline,\n    url : url,\n  }\n}\n\nreturn msg;\n\n\n\n\n\n","outputs":1,"noerr":0,"x":711.4765625,"y":283.66400146484375,"wires":[["9545f926.d18a98"]]},{"id":"9545f926.d18a98","type":"template","z":"b8c0412b.95d0a","name":"css","field":"style","fieldType":"msg","format":"css","syntax":"mustache","template":"#last-ride{\n    padding: 5px;\n    }\n\nabbr {\n    text-decoration: none;\n    }\n\nh3 {\n    color: #99999e;\n    }\n    \n\n.map-image {\n    max-width: 100%;\n    max-height: 100%;\n    }\n\n.nr-dashboard-cardcontainer>* {\n    position: initial;\n}\n\n#Übersicht_Strava_cards > md-card {\n    height: auto;  \n}\n","output":"str","x":877.4765625,"y":283.66400146484375,"wires":[["3ae40a44.671106"]]},{"id":"563d93a5.7d1bbc","type":"comment","z":"b8c0412b.95d0a","name":"insert api token and athlete id","info":"","x":259,"y":402,"wires":[]},{"id":"cf22f6ec.6c4f48","type":"http request","z":"b8c0412b.95d0a","name":"last activity","method":"GET","ret":"obj","url":"https://www.strava.com/api/v3/athlete/activities?per_page=1&access_token={{{token}}}","tls":"","x":521.0000610351562,"y":283,"wires":[["b072f7f6.d06958"]]},{"id":"88a2eed.c2a931","type":"inject","z":"b8c0412b.95d0a","name":"inject","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":"","x":109,"y":280.0000305175781,"wires":[["7aef6c4e.2b5c84"]]},{"id":"463a3222.03569c","type":"http request","z":"b8c0412b.95d0a","name":"","method":"GET","ret":"txt","url":"https://www.strava.com/athletes/{{{athlete_id}}}","tls":"","x":505.3867492675781,"y":358.90631103515625,"wires":[["6150bb62.28c0f4"]]},{"id":"26c51787.305518","type":"http request","z":"b8c0412b.95d0a","name":"athletes stats","method":"GET","ret":"obj","url":"https://www.strava.com/api/v3/athletes/{{{athlete_id}}}/stats?access_token={{{token}}}","tls":"","x":510.98046875,"y":443.9961242675781,"wires":[["b1f41f83.88fce"]]},{"id":"f9bd8b33.c8ba18","type":"debug","z":"b8c0412b.95d0a","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1289,"y":355,"wires":[]},{"id":"7aef6c4e.2b5c84","type":"change","z":"b8c0412b.95d0a","name":"credentials","rules":[{"t":"set","p":"token","pt":"msg","to":"<strava token>","tot":"str"},{"t":"set","p":"athlete_id","pt":"msg","to":"<athlete id>","tot":"str"},{"t":"set","p":"google_api_key","pt":"msg","to":"<google api key>","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":304,"y":348,"wires":[["cf22f6ec.6c4f48","463a3222.03569c","26c51787.305518"]]},{"id":"3ae40a44.671106","type":"ui_template","z":"b8c0412b.95d0a","group":"37541ec6.84e1a2","name":"Last Ride","order":1,"width":"0","height":"0","format":"<div>\n    <h3>{{msg.payload.last_ride.name}}</h3>\n    <div class=\"picture\">\n    <img class=\"map-image\" ng-src=\"https://maps.googleapis.com/maps/api/staticmap?key={{msg.google_api_key}}&size=400x400&path=weight:3%7Ccolor:0xFC4C02FF%7Cenc:{{msg.payload.last_ride.polyline}}\" alt=\"Image\"/>\n    </div>\n    <div>\n        <ul class=\"inline-stats\" id=\"last-ride\">\n            <li>\n                <strong>{{msg.payload.last_ride.distance}}<abbr class=\"unit\" title=\"Kilometer\">km</abbr></strong><div class=\"label\">DISTANCE</div>\n            </li>\n            <li>\n                <strong>{{msg.payload.last_ride.moving_time.hr}}<abbr class=\"unit\" title=\"Hours\">h</abbr>\n                {{msg.payload.last_ride.moving_time.min}}<abbr class=\"unit\" title=\"Minutes\">m</abbr>\n                {{msg.payload.last_ride.moving_time.sec}}<abbr class=\"unit\" title=\"Seconds\">s</abbr>\n                </strong>\n                <div class=\"label\">TIME</div>\n            </li>\n            <li>\n                <strong>{{msg.payload.last_ride.elevation}}<abbr class=\"unit\" title=\"Meter\">m</abbr></strong><div class=\"label\">ELEVATION</div>\n            </li>\n            <li>\n                <strong>{{msg.payload.last_ride.kudos}}</strong><div class=\"label\">KUDOS</div>\n            </li>        \n            <li>\n                <strong>{{msg.payload.last_ride.temp}}<abbr class=\"unit\" title=\"Grad Celsius\">°C</abbr></strong><div class=\"label\">TEMPERATURE</div>\n            </li>        \n    </ul>\n    </div>\n</div>\n<style>\n    {{msg.style}}\n</style>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":1054,"y":283,"wires":[["f9bd8b33.c8ba18"]]},{"id":"37541ec6.84e1a2","type":"ui_group","z":"","name":"Strava","tab":"5d86edbf.ced464","order":2,"disp":true,"width":"6","collapse":false},{"id":"5d86edbf.ced464","type":"ui_tab","z":"","name":"Übersicht","icon":"dashboard","order":1}]

Flow Info

Created 7 years, 5 months ago
Rating: not yet rated

Owner

Actions

Rate:

Node Types

Core
  • change (x1)
  • comment (x1)
  • debug (x1)
  • function (x2)
  • html (x1)
  • http request (x3)
  • inject (x1)
  • template (x3)
Other
  • ui_group (x1)
  • ui_tab (x1)
  • ui_template (x3)

Tags

  • strava
  • template
  • api
  • request
  • css
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option