garmin / connectiq-apps

A collection of Connect IQ apps.
Apache License 2.0
492 stars 155 forks source link

Strava Widget does not build #30

Closed ssk2 closed 5 years ago

ssk2 commented 5 years ago

I'm trying to build this in Eclipse using the latest version of the SDK and the Eclipse plug-in.

The app fails to build with these errors-

BUILD: ERROR: /Users/sunilsh/workspace/connectiq-apps/widgets/strava-api/source/StravaLogin.mc:46:  Undefined symbol "ClientSecret" detected.
BUILD: ERROR: /Users/sunilsh/workspace/connectiq-apps/widgets/strava-api/source/StravaLogin.mc:46:  Undefined symbol "ClientId" detected.
BUILD: ERROR: /Users/sunilsh/workspace/connectiq-apps/widgets/strava-api/source/StravaLogin.mc:82:  Undefined symbol "ClientId" detected.
travisvitek commented 5 years ago

The Strava sample app uses OAuth2 to authenticate with the Strava service. You need to browse to

https://www.strava.com/settings/api

and create an app. When you do this, you'll get a ClientID and a ClientSecret for your app. In the strava-api/source folder, you'll find a file named Keys.mc.sample. You need to rename this to Keys.mc and update the contents of the file to reflect your personal API keys.

ssk2 commented 5 years ago

Ah, got it, thanks!

droustchev commented 7 months ago

Sorry for digging this old issue up, but I'm running into an issue building a ConnectIQ app that makes use of Communications.makeOAuthRequest() and I stumbled across this repo and the Strava Widget example. I followed the above instructions and in the simulator I get the Strava login page, but that's about it after authorizing the app.

My understanding is that Strava returns the authorization code as part of the query in the redirect URL and I think the method registered via Communications.registerForOAuthMessages() can't parse it from there?

I modified the example to print out the value.data in the accessCodeResult metod and it returns an empty dictionary {}, which results in getAccessToken() being called, but with null and Strava then returns and error:

{errors=>[{field=>code, code=>invalid, resource=>AuthorizationCode}], message=>Bad Request}

when I print the data that handleAccessResponse() gets called with.

Am I doing something wrong here, or does the OAuth flow provided by Toybox.Communications depend on responses being JSON?

TravisConnectIQ commented 7 months ago

Am I doing something wrong here, or does the OAuth flow provided by Toybox.Communications depend on responses being JSON?

You aren't doing anything wrong, it is just that this app hasn't been updated to follow the new Strava API requirements. The issue is that "public" is not a valid value for the "scope" parameter.

https://developers.strava.com/docs/authentication/#detailsaboutrequestingaccess

Changing that to "read" is sufficient for getting the sample app to work in my testing.

Based on my reading, it looks like Strava is making additional changes to their API and access, so more changes may be needed in the near future.

droustchev commented 7 months ago

Thank you for the quick response on a long weekend @TravisConnectIQ.

Good catch on the API scope!

I made those changes and my local copy that I had extensively played around with was still not working. I saw you pushed two commits, so I pulled a fresh copy and the widget indeed works.

After some diffing I think I finally found the issue I was having with both the widget and my project, posting it here for posterity in case other folks run into this:

Based on https://developer.garmin.com/connect-iq/core-topics/authenticated-web-services/, I had tried both http://localhost (and connectiq://oauth, despite using the Communications class) for the redirect. However, it seems it needs to be https://localhost, note the use of the HTTPS protocol, otherwise the result keys, aka the authorization code, will not be populated properly it seems.

FWIW, the API docs (https://developer.garmin.com/connect-iq/api-docs/Toybox/Communications.html#makeOAuthRequest-instance_function) also use http://localhost. Maybe both these documentations need to be updated?

From my testing changing

- const RedirectUri = "https://localhost";
+ const RedirectUri = "http://localhost";

in the StravaApp.mc file does replicate this issue consistently (when also making sure to reset the simulator in order to clear cached tokens).

TravisConnectIQ commented 7 months ago

I'll update the docs. Thanks!

droustchev commented 7 months ago

Awesome, thanks Travis! Appreciate your swift responses and consequently helping me figure out my issue 👍