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

Anyone getting 403 error from Garmin Connect starting today? #61

Open
fulmar2 opened this issue Sep 26, 2023 · 23 comments
Open

Anyone getting 403 error from Garmin Connect starting today? #61

fulmar2 opened this issue Sep 26, 2023 · 23 comments

Comments

@fulmar2
Copy link

fulmar2 commented Sep 26, 2023

The code has been working for a while, but today started getting a 403 error from Garmin Connect. Anyone else experiencing that?

@cabby26
Copy link

cabby26 commented Sep 26, 2023

Same

@ltcomd
Copy link

ltcomd commented Sep 26, 2023

Same here. Some days ago it was working...

@fulmar2
Copy link
Author

fulmar2 commented Sep 27, 2023

I am guessing that Garmin changed the URL. But i don’t know how to figure out what the new URL is (assuming they still support this).

@DaveWilcock
Copy link
Member

Are you getting a 403 when trying to login or is it a 403 when performing one of the requests for data?

@fulmar2
Copy link
Author

fulmar2 commented Sep 27, 2023

Seems like this URL at least produces a blank page:

https://connect.garmin.com/modern/proxy/activitylist-service/activities/search/activities

I log in using a browser and try to visit this URL and it is just two HTML tags. No error is generated during the log in process that I know of…

@DaveWilcock
Copy link
Member

Seems like this URL at least produces a blank page:

https://connect.garmin.com/modern/proxy/activitylist-service/activities/search/activities

I log in using a browser and try to visit this URL and it is just two HTML tags. No error is generated during the log in process that I know of…

I'm not sure if this is new, but a request to the search endpoint here in the browser, looks like it's passing a bearer token in the request header, which indicates that this search endpoint is now behind some auth mechanism. Will do some more investigation when I've got some time.

@anniew86
Copy link

perhaps it should be https://connect.garmin.com/activitylist-service/activities/ ... ?

@fulmar2
Copy link
Author

fulmar2 commented Sep 29, 2023

perhaps it should be https://connect.garmin.com/activitylist-service/activities/ ... ?

Thanks, I just tried that link which produces an error page. Appreciate the suggestion, though.

@teibaz
Copy link

teibaz commented Sep 29, 2023

I can see that everyone who uses garmin connect in all programming languages faces the same issue. I found very nice options here:
pe-st/garmin-connect-export#95

but it takes time to test and develop everything. If someone will do the same - let us know, otherwise I will try to sit this weekend and try to change the code.

@anniew86
Copy link

anniew86 commented Oct 7, 2023

@fulmar2
Copy link
Author

fulmar2 commented Oct 15, 2023

here some other issues (and solutions) mostly for python clients:

petergardfjall/garminexport#102 petergardfjall/garminexport#103 petergardfjall/garminexport#104 petergardfjall/garminexport#105 cyberjunky/python-garminconnect#144

Thanks for the links anniew. Do you see how to integrate Garth with this PHP project? I’m at a loss.

@jpgnz
Copy link

jpgnz commented Oct 16, 2023

Not easily. Essentially there needs to be a rewrite of a large chunk of the authentication workflow of this library to match what Garth is doing in Python.

@DaveWilcock
Copy link
Member

DaveWilcock commented Oct 16, 2023 via email

@jpgnz
Copy link

jpgnz commented Oct 16, 2023

@DaveWilcock I found this comment pretty useful: petergardfjall/garminexport#104 (comment)

I got curl-impersonate to compile and have it loaded into my php install (docs here) and was hopeful it would just work like the comment suggested on their library, but it didn't, same 403 error. I was going to attempt to see what else I might need to adjust in your library but I ran out of time.

I don't think it's necessarily feasible for all users to be able to compile and adjust their php configuration, but unsure. For me it would be completely acceptable to require that.

The Garth solution definitely appears to be the best long term way as it seems to impersonate the mobile application, but looks like quite a bit of work.

@anniew86
Copy link

anniew86 commented Oct 16, 2023

Thanks for the links anniew. Do you see how to integrate Garth with this PHP project? I’m at a loss.

Hi,

I was able to integrate the python solution https://github.com/cyberjunky/python-garminconnect (thank you very much cyberjunky ) with my own PHP program. It is not Garth alone but a very helpful python project which is using Garth.

Below step-by-step description of my approach, please keep in mind, that I'm using Linux Debian.

  1. install python and pip (python packet manager):
    $ apt-get install python3 pip

  2. install python package 'garminconnect' and dependecies in the local directory 'python_packages':
    $ pip install --target=python_packages garminconnect

  3. create the python script 'garmin.py' with execution rights, which will be called from php, the script can be called with 4 params, calls 3 possible api's and returns the response with json, here the content:

#!/usr/bin/env python3

import sys
import os
import json
from garth.exc import GarthHTTPError
from garminconnect import (
    Garmin,
    GarminConnectAuthenticationError,
    GarminConnectConnectionError,
    GarminConnectTooManyRequestsError,
)

userid = sys.argv[1]
password = sys.argv[2]
command = sys.argv[3]

tokenstore = os.getcwd() + '/garmin_tokenstore/' + userid

def init_api(email, password):

    try:
        # Trying to login to Garmin Connect using token data from '{tokenstore}'
        garmin = Garmin()
        garmin.login(tokenstore)
    except (FileNotFoundError, GarthHTTPError, GarminConnectAuthenticationError):
        # Login tokens not present or session is expired, login with your Garmin Connect credentials to generate them
        # They will be stored in '{tokenstore}' for future use.
        try:
            garmin = Garmin(email, password)
            garmin.login()
            # Save tokens for next login
            garmin.garth.dump(tokenstore)

        except (FileNotFoundError, GarthHTTPError, GarminConnectAuthenticationError, requests.exceptions.HTTPError) as err:
            logger.error(err)
            return None

    return garmin

api = init_api(userid, password)

if command == 'getActivityList':
    count = sys.argv[4]
    response = api.get_activities(0,count)
    print(json.dumps(response))
elif command == 'getActivity':
    activity_id = sys.argv[4]
    response = api.get_activity_evaluation(activity_id)
    print(json.dumps(response))
elif command == 'getActivityWeather':
    activity_id = sys.argv[4]
    response = api.get_activity_weather(activity_id)
    print(json.dumps(response))
else:
    print('invalid command')    
  1. call the script from PHP in such way:
  $userid = 'YOUR_GARMIN_USER';
  $password = 'YOUR_GARMIN_PASS';
  $count = 10;
  $home = getcwd();  
  $response_json = shell_exec( "PYTHONPATH=python_packages {$home}/garmin.py $userid $password getActivityList $count" );
  echo json_decode($response_json, true);

It is a workaround for me, if possible I would like to use back this PHP project and have a pure PHP solution,

I hope it helps,
Annie

@hogeh
Copy link

hogeh commented Oct 26, 2023

Anybody with a php solution meanwhile?? Desperately waiting for it...Thanks to everybody who helps to get this working again!
Ho

@fulmar2
Copy link
Author

fulmar2 commented Oct 26, 2023

Not sure this is any help, but I ended up using their API. I signed up as a developer, and got my codes. The app got approved; this part was easy. Trying to learn the API with the paucity of documentation was difficult… but in a nutshell, Garmin will “ping” your web hook when a new activity is uploaded. The ping contains a json that only has a little information, but one item is a special URL for the activity - which includes an activity ID (that does NOT match the activity ID that you are used to) and a token. All of this is a major pain to learn, but over the course of a few days and another php Garmin connector on git hub, I was able to get it to work. Now that it is working, I am glad I chose that route instead of relying on the spoof browser method. I really love that creative people have worked so hard on this project, but as it is written now, it will continue to break whenever Garmin changes their website.

@teibaz
Copy link

teibaz commented Oct 26, 2023

I had no time and ended up using python-garminconnect by cyberjunky - once the file is in server all the parsing part and the rest project is being done by php as before.

@ChristianManunzio
Copy link

Not sure this is any help, but I ended up using their API. I signed up as a developer, and got my codes. The app got approved; this part was easy. Trying to learn the API with the paucity of documentation was difficult… but in a nutshell, Garmin will “ping” your web hook when a new activity is uploaded. The ping contains a json that only has a little information, but one item is a special URL for the activity - which includes an activity ID (that does NOT match the activity ID that you are used to) and a token. All of this is a major pain to learn, but over the course of a few days and another php Garmin connector on git hub, I was able to get it to work. Now that it is working, I am glad I chose that route instead of relying on the spoof browser method. I really love that creative people have worked so hard on this project, but as it is written now, it will continue to break whenever Garmin changes their website.

Can you share which garmin connector on github you used to learn this? I´m still struggeling to get it to work 🙈

@fulmar2
Copy link
Author

fulmar2 commented Oct 27, 2023

Christian-

i installed this:

https://github.com/stoufa06/php-garmin-connect-api

It did not work initially, as I had to make a change to one line of code as described here (uriFor vs uri_for):

stoufa06/php-garmin-connect-api#12

That will save you a lot of time!

Once I got the example working, it gives me a summary of activities. Quite happy with that… but then i used my Garmin API Developer account, and from there I can manage “pings” from the API to my webhooks. All new activities come to my specified URL (by the way, you will have to dig on the Garmin developer page to find your API settings to specify the endpoints).

Now that I have done all this work, I am quite happy, and feel like my tools will be more reliable in the future. It’s a 100% PHP solution.

@DaveWilcock
Copy link
Member

DaveWilcock commented Oct 27, 2023 via email

@fulmar2
Copy link
Author

fulmar2 commented Oct 27, 2023

Thanks for this info Brian. Do you know if the developer access to their APIs is limited in any way? e.g. by time or API call rate limiting, etc.

Dave -
I am signed up for an evaluation account. I did not see an easy way to migrate to a production account, but maybe it does not matter. I actually created the developer portal account 28 months ago last time your code was broken by Garmin. There may be rate limiting, but I cannot find any information about that online. As you know, their documentation is very opaque. It seems that their API works in two ways.

One way is that you can send requests using the https://github.com/stoufa06/php-garmin-connect-api tool. The other way is (once you have an account), for any user who has agreed to share their data, new activities can be "pinged" to a webhook you specify here:

https://apis.garmin.com/tools/login (note that you need an approved account to log in here)

You manage your app/team here:

https://developerportal.garmin.com/

To me, it seems pretty round-about, and definitely not "clean". Having worked with the Strava API, I find it much more intuitive... but this is what we are faced with. I hope this helps others. Also, Dave: Thanks for your work all these years keeping this project working. Really appreciate it.

@stoufa06
Copy link

stoufa06 commented Aug 12, 2024

@fulmar2 Thank you for the mention
The gamin api package that i am actually using has much more features and well maintained. I have developed it but i can not share it.
This package is just an example of work https://github.com/stoufa06/php-garmin-connect-api that i have created it on my own time.
If you want good advice from my own experience with garmin:

  • Garmin does not want you to use it api back and forth.
  • Once an activity is created is sends a notification of new activity
  • You have to get the data from their api once and save it somewhere.
  • Their api behaves like an old hag that tells you Something like take this s**t, slaps in your back neck and tell you to never come back.
  • The best way i found is to save the fit file data somewhere and use it to extract data.

If anyone needs help with garmin api thing i have an upwork account so you can hire me.

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

10 participants