Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error retrieving new activities #3

Closed
ShiveringPenguin opened this issue Sep 27, 2023 · 12 comments
Closed

Error retrieving new activities #3

ShiveringPenguin opened this issue Sep 27, 2023 · 12 comments

Comments

@ShiveringPenguin
Copy link

About 2 days ago, this script began failing. The error occurs at line 266 during the $SearchResults request.

A similar issue cropped up earlier. Your previous fix involved adjusting the headers to mimic regular browser traffic. That fix has worked flawlessly until now. Do you think a similar patch will work again?

I took a look at the headers during a normal browsing session and I see some new entries: "sentry-trace" and "baggage". These might be harder to spoof.

Thanks as always for your work on this project.

@ShiveringPenguin
Copy link
Author

Looking deeper into this, I think the api endpoint has changed.

The $ActivitySearchURL used to be:
https://connect.garmin.com/modern/proxy/activitylist-service/activities/search/activities

During an active browser session, the calls are now going to:
https://connect.garmin.com/activitylist-service/activities/search/activities

This request comes along with the following cookies and headers which don't appear to be accounted for in the script.

New Cookies:

  • GarminUserPrefs
  • notice_behavior
  • SESSIONID
  • JWT_FGP
  • SameSite
  • ADRUM_BTs
  • ADRUM_BT1
  • ADRUM_BTa

New Headers:

  • Accept-Encoding
  • X-app-ver
  • X-lang
  • DI-Backend
  • Authorization
  • sentry-trace
  • baggage
  • TE

If I swap in the new endpoint, and steal cookies and headers from an active browsing session (lines 266-280), then I can make requests without triggering 404 or 403 errors. However, the content that I receive is scrambled (encrypted?) so I'm still doing something wrong. The request doesn't include a status code, so I can't tell if it's "successful". It's just a scrambled string.

Do you have any thoughts on how to reformulate this request?

@mvaneijken
Copy link
Owner

I have to look into this, it seems that Garmin has changed something.

@ShiveringPenguin
Copy link
Author

You're probably aware, but it appears that other garmin connect projects have also broken. There is some interesting discussion in this thread regarding updates to endpoints / headers / data structure.

The only successful projects I've see have used garth to authenticate using cached OAuth tokens. I hope that's not necessary.

@mvaneijken
Copy link
Owner

Good point. I checked it breefly, but did not manage to get it working yet. They changed it quitte a bit.

@ShiveringPenguin
Copy link
Author

Yes, there are so many changes that it's hard to know where to start debugging. I'm glad other groups are working on this too.

@ShiveringPenguin
Copy link
Author

There has been some progress in petergardfjall's project. They appear to have cracked the authentication issue and I don't see any mention of the previous 'garth' work-around (good news!). They've figured out a simple and elegant way to fetch oauth token and update service URLs . I think this has been our primary hangup so far.

If we're lucky, maybe that's the only update needed.

However, we might still have to bypass cloudflare's bot detection. Peter's solution includes an option to utilize a python package called curl_cffi. I'm not sure if powershell's browser emulation is good enough to avoid cloudflare's bot detection on its own, or if something similar to curl_cffi would be required.

@mvaneijken
Copy link
Owner

Thanks for pointing to this repo. I did not find the time yet to have a detailed look at it due a busy schedule, I'll try to do that in the coming weeks.

@ShiveringPenguin
Copy link
Author

I was able to successfully download my current activity list and download all file types.

Essentially, I grabbed cookies and tokens from an active browser session and plugged those into your code. Everything post-authentication seems to be working with the updated service urls and request headers.

The next piece to tackle is authentication.

Attached are my notes and abstracted code. I haven't submitted code on github before so please let me know if this is helpful, or if you'd prefer some other method.

getGarmin_abstract.txt

@ShiveringPenguin
Copy link
Author

No rush. Thanks for everything you've done so far. I'm just trying to be helpful.

@ShiveringPenguin
Copy link
Author

OK, it looks like the authentication process is actually pretty simple. Your current flow is fine up until the $PostLoginURL call
Invoke-RestMethod -Uri ($PostLoginURL + "?ticket=" + $SSOCookie) -WebSession $GarminConnectSession

The next step should be something like this:
$exchangeToken = Invoke-WebRequest -UseBasicParsing -Uri "https://connect.garmin.com/modern/di-oauth/exchange" -Method POST -WebSession $GarminConnectSession -UserAgent $agent -Headers @{
"Accept" = "application/json, text/plain, */*"
"Accept-Language" = "en-US,en;q=0.5"
"Accept-Encoding" = "gzip, deflate"
"Referer" = "https://connect.garmin.com/modern/"
"NK" = "NT"
"X-app-ver" = "4.73.4.1"
"Origin" = "https://connect.garmin.com"
"DNT" = "1"
"Sec-GPC" = "1"
"Sec-Fetch-Dest" = "empty"
"Sec-Fetch-Mode" = "cors"
"Sec-Fetch-Site" = "same-origin"
"TE" = "trailers"
}

Then extract the token:
$exchangeTokenResponse = $exchangeToken.Content | ConvertFrom-Json
$authToken = $exchangeTokenResponse.token_type + " " + $exchangeTokenResponse.access_token

Once you have $authToken, you can add it to your request headers to request activity lists and download files (examples above).

I think we have all the major pieces now. Please don't think I'm trying to push you along. I was just curious how far I could get on my own. I'm sorry if my documentation is messy. Let me know if you want me to clarify anything.

Thanks again.

mvaneijken added a commit that referenced this issue Apr 2, 2024
Add support for KML files
Updated user-agent
Remove Garmin Connect Actvity Export -Program Settings.xml deoendency
Layout and output improvements
@mvaneijken mvaneijken mentioned this issue Apr 2, 2024
Merged
@mvaneijken
Copy link
Owner

@ShiveringPenguin it took a while before I found time to get in to this. Your suggestions helped allot in fixing this!

@ShiveringPenguin
Copy link
Author

Great! I'm glad you were able to make sense out of my notes. Thanks for the fix and nice follow-up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants