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

GraphQL endpoints for Garmin Connect #210

Closed
psdupvi opened this issue Jun 14, 2024 · 5 comments
Closed

GraphQL endpoints for Garmin Connect #210

psdupvi opened this issue Jun 14, 2024 · 5 comments

Comments

@psdupvi
Copy link
Contributor

psdupvi commented Jun 14, 2024

Inspired by #207 , I noticed that there are GraphQL endpoints which appear to populate the new Garmin Connect home page.

The existing endpoints which we utilize still populate the Reports pages (and so on), but it may be worth investigating what's available from the Garmin GraphQL endpoints and whether we can effectively query them.

The endpoints all appear to be just https://connect.garmin.com/graphql-gateway/graphql, with a payload that specifies the query.

For example, I suspect that the Weight widget is populated by a request to https://connect.garmin.com/graphql-gateway/graphql with the payload {"query":"query{weightScalar(startDate:\"2024-06-07\", endDate:\"2024-06-13\")}"}

The response for that endpoint is at the bottom of this issue.

In general, this may be a larger request, and may not be worth doing if the data returned from these endpoints is basically the same as what we currently get.

{
    "data": {
        "weightScalar": {
            "dailyWeightSummaries": [
                {
                    "summaryDate": "2024-06-13",
                    "numOfWeightEntries": 1,
                    "minWeight": 80013.0,
                    "maxWeight": 80013.0,
                    "latestWeight": {
                        "samplePk": 1718274304474,
                        "date": 1718236800000,
                        "calendarDate": "2024-06-13",
                        "weight": 80013.0,
                        "bmi": null,
                        "bodyFat": null,
                        "bodyWater": null,
                        "boneMass": null,
                        "muscleMass": null,
                        "physiqueRating": null,
                        "visceralFat": null,
                        "metabolicAge": null,
                        "sourceType": "MFP",
                        "timestampGMT": 1718274291000,
                        "weightDelta": -725.7477919999975
                    },
                    "allWeightMetrics": []
                },
                {
                    "summaryDate": "2024-06-12",
                    "numOfWeightEntries": 1,
                    "minWeight": 80739.0,
                    "maxWeight": 80739.0,
                    "latestWeight": {
                        "samplePk": 1718189655482,
                        "date": 1718150400000,
                        "calendarDate": "2024-06-12",
                        "weight": 80739.0,
                        "bmi": null,
                        "bodyFat": null,
                        "bodyWater": null,
                        "boneMass": null,
                        "muscleMass": null,
                        "physiqueRating": null,
                        "visceralFat": null,
                        "metabolicAge": null,
                        "sourceType": "MFP",
                        "timestampGMT": 1718189629000,
                        "weightDelta": -181.4369480000026
                    },
                    "allWeightMetrics": []
                },
                {
                    "summaryDate": "2024-06-11",
                    "numOfWeightEntries": 1,
                    "minWeight": 80920.0,
                    "maxWeight": 80920.0,
                    "latestWeight": {
                        "samplePk": 1718102495476,
                        "date": 1718064000000,
                        "calendarDate": "2024-06-11",
                        "weight": 80920.0,
                        "bmi": null,
                        "bodyFat": null,
                        "bodyWater": null,
                        "boneMass": null,
                        "muscleMass": null,
                        "physiqueRating": null,
                        "visceralFat": null,
                        "metabolicAge": null,
                        "sourceType": "MFP",
                        "timestampGMT": 1718102479000,
                        "weightDelta": -90.71847399999484
                    },
                    "allWeightMetrics": []
                },
                {
                    "summaryDate": "2024-06-10",
                    "numOfWeightEntries": 1,
                    "minWeight": 81011.0,
                    "maxWeight": 81011.0,
                    "latestWeight": {
                        "samplePk": 1718016576746,
                        "date": 1717977600000,
                        "calendarDate": "2024-06-10",
                        "weight": 81011.0,
                        "bmi": null,
                        "bodyFat": null,
                        "bodyWater": null,
                        "boneMass": null,
                        "muscleMass": null,
                        "physiqueRating": null,
                        "visceralFat": null,
                        "metabolicAge": null,
                        "sourceType": "MFP",
                        "timestampGMT": 1718016528000,
                        "weightDelta": -1542.2140580000025
                    },
                    "allWeightMetrics": []
                },
                {
                    "summaryDate": "2024-06-09",
                    "numOfWeightEntries": 1,
                    "minWeight": 82553.0,
                    "maxWeight": 82553.0,
                    "latestWeight": {
                        "samplePk": 1717933876536,
                        "date": 1717891200000,
                        "calendarDate": "2024-06-09",
                        "weight": 82553.0,
                        "bmi": null,
                        "bodyFat": null,
                        "bodyWater": null,
                        "boneMass": null,
                        "muscleMass": null,
                        "physiqueRating": null,
                        "visceralFat": null,
                        "metabolicAge": null,
                        "sourceType": "MFP",
                        "timestampGMT": 1717933834000,
                        "weightDelta": 997.9032139999949
                    },
                    "allWeightMetrics": []
                },
                {
                    "summaryDate": "2024-06-08",
                    "numOfWeightEntries": 1,
                    "minWeight": 81555.0,
                    "maxWeight": 81555.0,
                    "latestWeight": {
                        "samplePk": 1717845539380,
                        "date": 1717804800000,
                        "calendarDate": "2024-06-08",
                        "weight": 81555.0,
                        "bmi": null,
                        "bodyFat": null,
                        "bodyWater": null,
                        "boneMass": null,
                        "muscleMass": null,
                        "physiqueRating": null,
                        "visceralFat": null,
                        "metabolicAge": null,
                        "sourceType": "MFP",
                        "timestampGMT": 1717845508000,
                        "weightDelta": 181.4369480000026
                    },
                    "allWeightMetrics": []
                }
            ],
            "totalAverage": {
                "from": 1717718400000,
                "until": 1718323199999,
                "weight": 81131.83333333333,
                "bmi": null,
                "bodyFat": null,
                "bodyWater": null,
                "boneMass": null,
                "muscleMass": null,
                "physiqueRating": null,
                "visceralFat": null,
                "metabolicAge": null
            },
            "previousDateWeight": {
                "samplePk": 1717672393134,
                "date": 1717632000000,
                "calendarDate": "2024-06-06",
                "weight": 81374.0,
                "bmi": null,
                "bodyFat": null,
                "bodyWater": null,
                "boneMass": null,
                "muscleMass": null,
                "physiqueRating": null,
                "visceralFat": null,
                "metabolicAge": null,
                "sourceType": "MFP",
                "timestampGMT": 1717672390000,
                "weightDelta": null
            },
            "nextDateWeight": {
                "samplePk": null,
                "date": null,
                "calendarDate": null,
                "weight": null,
                "bmi": null,
                "bodyFat": null,
                "bodyWater": null,
                "boneMass": null,
                "muscleMass": null,
                "physiqueRating": null,
                "visceralFat": null,
                "metabolicAge": null,
                "sourceType": null,
                "timestampGMT": null,
                "weightDelta": null
            }
        }
    }
}
@cyberjunky
Copy link
Owner

@psdupvi interesting!

@psdupvi
Copy link
Contributor Author

psdupvi commented Jul 8, 2024

These endpoints are accessible through in the following way:

query = {"query":"query {trainingReadinessRangeScalar(startDate:\"2024-06-11\", endDate:\"2024-07-08\")}"}
r = api.garth.post("connectapi","graphql-gateway/graphql", json=query)
data = r.json()

Note that we're using api.garth.post, since these are all POST requests. You get a 405 Method Not Allowed error if you try to use a Get request.

Now that I know how to access these, I'll take a look at comparing the available data from these vs. existing endpoints and collecting a list of known queries. The good news is it looks like Garmin (stupidly) sends a GraphQL request even for widgets that you haven't selected -- e.g., I've never used the new Jet Lag functionality, but I still see a jetLagScalar query

This will take some time, but I think it's valuable, especially since there may possibly be more functionality here

psdupvi added a commit to psdupvi/python-garminconnect that referenced this issue Jul 10, 2024
@psdupvi
Copy link
Contributor Author

psdupvi commented Jul 17, 2024

This file contains the queries I was able to find for this endpoint. There are 35 of them.

queries.json

This file contains queries and responses, with (hopefully) all my PII removed
queries-and-responses.json

@psdupvi psdupvi closed this as completed Sep 23, 2024
@cyberjunky
Copy link
Owner

@psdupvi I'm thinking we should keep this information, maybe on an developer wiki page here?

@cyberjunky
Copy link
Owner

I have renamed the file to an .txt extension otherwise the lint tools went bonkers ;-)

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