Git Product home page Git Product logo

php-garmin-connect's Introduction

PHP Garmin Connect

A PHP adapter for interrogating the Garmin Connect "API"

Preamble

Garmin doesn't really have a proper API for their Connect tool. Well, they sort of do, but it's half-baked; they appear to have either abandoned it or let it go stale, the documentation is very thin on the ground and there appears to be no "proper" way of authenticating the user.

So thanks to Collin @tapiriik and his wonderful public python repo (https://github.com/cpfair/tapiriik), this project was born for those of us that prefer elephants to snakes ;)

The code is pretty well documented, and it has to be because some things we have to do is pretty gnarly. Once authentication is done though, it's pretty much good old RESTFUL API stuff. Oh, but we're using the CURL cookie handling to maintain session state. Ugh.

Full Example

We simply connect using our Garmin Connect credentials.

<?php
$arrCredentials = array(
   'username' => 'xxx',
   'password' => 'xxx',
);

try {
   $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);

   $objResults = $objGarminConnect->getActivityList(0, 1, 'cycling');
   foreach($objResults->results->activities as $objActivity) {
      print_r($objActivity->activity);
   }

} catch (Exception $objException) {
   echo "Oops: " . $objException->getMessage();
}

API Functions

The library implements a few basic API functions that you can use to retrieve useful information. The method signatures are as follows:

Method Parameters Returns
getActivityTypes() - Array
getActivityList() integer $intStart, integer $intLimit, string $strActivityType stdClass
getActivitySummary() integer $intActivityID stdClass
getActivityDetails() integer $intActivityID stdClass
getDataFile string $strType, integer $intActivityID string
getUser - string
getWellnessData string $strFrom, string $strTo string
getWeightData string $strFrom, string $strTo string
getSleepData string
getWorkoutList integer $intStart, integer $intLimit, bool $myWorkoutsOnly, bool $sharedWorkoutsOnly string
createWorkout string $data string
deleteWorkout integer $id string
createStepNote integer $stepID, string $note, integer $workoutID string
scheduleWorkout integer $id, string $payload string

getActivityTypes()

Returns a stdClass object, which contains an array called dictionary, that contains stdClass objects that represent an activity type.

Example

try {
   $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
   $obj_results = $objGarminConnect->getActivityTypes();
   foreach ($obj_results->dictionary as $item) {
      print_r($item);
   }

   } catch (Exception $objException) {
      echo "Oops: " . $objException->getMessage();
   }

Response

Array
(
    [0] => stdClass Object
        (
            [typeId] => 1
            [typeKey] => running
            [parentTypeId] => 17
            [sortOrder] => 3
        )

    [1] => stdClass Object
        (
            [typeId] => 2
            [typeKey] => cycling
            [parentTypeId] => 17
            [sortOrder] => 8
        )

getActivityList(integer $intStart, integer $intLimit, string $strActivityType)

Returns a stdClass object, which contains an array called results, that contains stdClass objects that represents an activity. It accepts three parameters - start, limit and activity type; start is the record that you wish to start from, limit is the number of records that you would like returned, and activity type is the (optional) string representation of the activity type returned from getActivityTypes()

Example

   try {
      $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
      $obj_results = $objGarminConnect->getActivityList(0, 1);
      print_r($obj_results);
   } catch (Exception $objException) {
      echo "Oops: " . $objException->getMessage();
   }

Response (not exhaustive)

stdClass Object
(
[results] => stdClass Object
    (
        [activities] => Array
            (
                [0] => stdClass Object
                    (
                        [activity] => stdClass Object
                            (
                                [activityId] => 593520370
                                [activityName] => stdClass Object
                                    (
                                        [value] => Untitled
                                    )

                                [activityDescription] => stdClass Object
                                    (
                                        [value] => 
                                    )

                                [locationName] => stdClass Object
                                    (
                                        [value] => 
                                    )

                                [userId] => 1653429
                                [username] => [email protected]
                                [uploadDate] => stdClass Object
                                    (
                                        [display] => Thu, 18 Sep 2014 1:34 PM
                                        [value] => 2014-09-18
                                        [withDay] => Thu, 18 Sep 2014
                                        [abbr] => 18 Sep 2014
                                        [millis] => 1411047273000
                                    )

                                [uploadedWith] => stdClass Object
                                    (
                                        [key] => garminExpressWin
                                        [display] => Garmin Express Windows
                                        [displaySingular] => Garmin Express Windows
                                        [version] => 2.9.6.10
                                    )

                                [device] => stdClass Object
                                    (
                                        [key] => edge510
                                        [display] => Garmin Edge 510
                                        [displaySingular] => Garmin Edge 510
                                        [version] => 3.10.0.0
                                    )

getActivitySummary(integer $intActvityID)

Returns a stdClass object, that contains a stdClass object called activity, which contains a, and I quote, BUTT LOAD of data representative of the activity ID that you have passed in as the parameter. This activity ID can be taken from the getActivityList() response (e.g. $objResponse->results->activities[0]->activity->activityId).

Example

try {
   $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
   $obj_results = $objGarminConnect->getActivitySummary(593520370);
   print_r($obj_results);
} catch (Exception $objException) {
   echo "Oops: " . $objException->getMessage();
}

Response

I'm afraid that response is far too large to put here - you'll just have to execute the above and check it out for yourself!

getActivityDetails(integer $intActivityID)

If you think the previous function returned a lot of data, you had better sit down - this is a big one!

As usual, this returns a stdClass object that contains a stdClass object called "com.garmin.activity.details.json.ActivityDetails" (yep!) that contains a bunch of members and objects that represents the RAW data of your activity. As such, all of the raw exercise data is also returned (metrics). You might consider this a textual representation of GPX data, for example.

It contains an array (measurements) of stdClass objects, which are the indexes for the metric data. For example, this information shows you that metric index 3 represents the data for Temperature, and index 1 is Bike Cadence, etc.

The metric data is found in the metric array, which is a bunch of stdClass objects that contain arrays called metrics, which indexes can be found in the measurements data.

It makes sense when you see it.

Note: This method may take a while to return any data, as it can be vast.

Example

try {
   $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
   $obj_results = $objGarminConnect->getActivityDetails(593520370);
   print_r($obj_results);
} catch (Exception $objException) {
   echo "Oops: " . $objException->getMessage();
}

Response

No chance!

getDataFile(string $strType, integer $intActivityID)

Returns a string representation of requested data type, for the given activity ID. The first parameter is one of:

Type Returns
\dawguk\GarminConnect::DATA_TYPE_FIT Original .fit file, zipped
\dawguk\GarminConnect::DATA_TYPE_GPX GPX as XML string
\dawguk\GarminConnect::DATA_TYPE_TCX TCX as XML string
\dawguk\GarminConnect::DATA_TYPE_GOOGLE_EARTH Google Earth as XML string

Example

   try {
      $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
      $obj_results = $objGarminConnect->getDataFile(\dawguk\GarminConnect::DATA_TYPE_GPX, 593520370);
      print_r($obj_results);
   } catch (Exception $objException) {
      echo "Oops: " . $objException->getMessage();
   }

Response (Not exhaustive)

<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="Garmin Connect" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd" xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <metadata>
      <link href="connect.garmin.com">
         <text>Garmin Connect</text>
      </link>
      <time>2014-09-18T17:22:50.000Z</time>
   </metadata>
   <trk>
      <name>Untitled</name>
      <trkseg>
         <trkpt lon="-2.246061209589243" lat="53.48290401510894">
            <ele>54.599998474121094</ele>
            <time>2014-09-18T17:22:50.000Z</time>
            <extensions>
               <gpxtpx:TrackPointExtension>
                  <gpxtpx:atemp>22.0</gpxtpx:atemp>
                  <gpxtpx:cad>0</gpxtpx:cad>
               </gpxtpx:TrackPointExtension>
            </extensions>

getWorkoutList(integer $intStart, integer $intLimit, bool $myWorkoutsOnly, bool $sharedWorkoutsOnly)

Returns an array of stdClass objects.

Example

try {
   $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
   $obj_results = $objGarminConnect->getWorkoutList(0, 10);
   print_r($obj_results);
} catch (Exception $objException) {
   echo "Oops: " . $objException->getMessage();
}

Response

[

    {
        "workoutId": 12345678,
        "ownerId": 12345678,
        "workoutName": "1.5h run",
        "description": null,
        "updateDate": "2020-04-20T15:26:05.0",
        "createdDate": "2020-04-20T15:26:05.0",
        "sportType": {
            "sportTypeId": 1,
            "sportTypeKey": "running",
            "displayOrder": 1
        },
        "trainingPlanId": null,
        "author": {
            "userProfilePk": null,
            "displayName": null,
            "fullName": null,
            "profileImgNameLarge": null,
            "profileImgNameMedium": null,
            "profileImgNameSmall": null,
            "userPro": false,
            "vivokidUser": false
        },
        "estimatedDurationInSecs": null,
        "estimatedDistanceInMeters": null,
        "poolLength": 0.0,
        "poolLengthUnit": {
            "unitId": null,
            "unitKey": null,
            "factor": null
        },
        "workoutProvider": null,
        "workoutSourceId": null,
        "consumer": null,
        "atpPlanId": null,
        "workoutNameI18nKey": null,
        "descriptionI18nKey": null,
        "exerciseCriteria": null,
        "shared": false,
        "estimated": true
    }
]

createWorkout(string $data)

Returns a JSON object of the created workout.

Example

try {
   $data = ''; 
   $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
   $obj_results = $objGarminConnect->createWorkout($data);
   print_r($obj_results);
} catch (Exception $objException) {
   echo "Oops: " . $objException->getMessage();
}

Response

{"workoutId":204516560,"ownerId":80242598,"workoutName":"Testing 1, 2, 3...","description":null,"updatedDate":"2020-04-20T16:06:19.0","createdDate":"2020-04-20T16:06:19.0",...}

deleteWorkout(integer $id)

Deletes a workout from the Garmin website and returns no content.

Example

try {
   $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
   $obj_results = $objGarminConnect->deleteWorkout(593520370);
   print_r($obj_results);
} catch (Exception $objException) {
   echo "Oops: " . $objException->getMessage();
}

createStepNote(integer $stepID, string $note, integer $workoutID)

Creates a new note and attaches it to a step. No content is returned from Garmin - 204.

Example

try {
   $data = '';
   $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
   $obj_results = $objGarminConnect->createStepNote(593520370, 'Hello World', 123456789);
   print_r($obj_results);
} catch (Exception $objException) {
   echo "Oops: " . $objException->getMessage();
}

scheduleWorkout(integer $id, string $data)

Creates a new event on your calendar and returns a JSON object as the response.

Example

try {
   $data = '';
   $objGarminConnect = new \dawguk\GarminConnect($arrCredentials);
   $obj_results = $objGarminConnect->scheduleWorkout(593520370, $data);
   print_r($obj_results);
} catch (Exception $objException) {
   echo "Oops: " . $objException->getMessage();
}

Response

{"workoutScheduleId":305583643,"workout":{"workoutId":204503966,"ownerId":80242598,"workoutName":"3h run","description":null,"updatedDate":"2020-04-20T15:26:06.0","createdDate":"2020-04-20T15:26:06.0","sportType":{"sportTypeId":1,"sportTypeKey":"running", ...}

php-garmin-connect's People

Contributors

amyboyd avatar annewielis avatar davereid avatar davewilcock avatar evanbarter avatar gear4dave avatar ifery avatar javiermartinz avatar jentscke avatar lsolesen avatar pygoubet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-garmin-connect's Issues

getActivitySummary() doesn't work

Oops: An unexpected response code was found: 410
[url] => https://connect.garmin.com/proxy/activity-service-1.3/json/activity/3599xxxx
[content_type] => text/html
[http_code] => 410
[header_size] => 662
[request_size] => 369
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.31838
[namelookup_time] => 0.000137
[connect_time] => 0.028485
[pretransfer_time] => 0.113492
[size_upload] => 0
[size_download] => 33
[speed_download] => 103
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0.318213
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => 104.17.3.69
[certinfo] => Array
(
)

[primary_port] => 443
[local_ip] => 192.168.178.51
[local_port] => 55690

Auth fails

Hello,

Tried the lib and it throws the following authentication error. Any idea how to fix this?

PHP Notice:  Undefined offset: 0 in ../php-garmin-connect/src/dawguk/GarminConnect.php on line 140
Oops: Looks like the authentication failed

http 402

Anyone else getting this?

Fatal error: Uncaught dawguk\GarminConnect\exceptions\UnexpectedResponseCodeException: An unexpected response code was found: 402

402 is Payment Required, seems like they are blocking requests from my IP.

getDataFile fails with exception : an unexpected response code was found: 503

I have tried your API with
$objGarminConnect = new \dawguk\GarminConnect($this->credentials)
$objGarminConnect->getActivityList($i, 10);
//parse results find $activityid
$objGarminConnect->getDataFile(\dawguk\GarminConnect::DATA_TYPE_TCX, $activityId));
=> exception : An unexpected response code was found: 503

Note that it works if I change the line
//$strResponse = $this->objConnector->get("https://connect.garmin.com/proxy/activity-service-1.1/" . $strType . "/activity/" . $intActivityID . "?full=true");
//to
$strResponse = $this->objConnector->get("https://connect.garmin.com/proxy/activity-service-1.2/" . $strType . "/activity/" . $intActivityID . "?full=true");

Access denied

Seems like Garmin has changed protocol, I get an Access denied. Anyone else?

I'm using newest code v 1.7

Oops: Ticket value wasn't found in response

Hi, I having this problem when I write a invalid passoword gives

Oops: Ticket value wasn't found in response - looks like the authentication failed.please refresh page!

Then when I write a valid password still gives the same error!

-Best

Getting HTTP 500 Error

Hi,

I tried to use the test example for this but it keeps giving me 500 error code and php (5.6) log saying the following:
[10-Sep-2017 15:55:47 Europe/Helsinki] PHP Fatal error: Class 'dawguk\GarminConnect' not found in /home/user/public_html/garmin/garmin_test.php on line 9

If I add a require_once 'src/dawguk/GarminConnect.php'; then the floowing error is showing in the log:
PHP Fatal error: Class 'dawguk\GarminConnect\Connector' not found in /home/user/public_html/garmin/src/dawguk/GarminConnect.php on line 62

What am I doing wrong here? Please advice.

Garmin API endpoints have changed - some help is required

I have recently found that Garmin have deprecated a lot of the API endpoints that were being used in this library. I have snooped enough to fix the authentication mechanism, and the ability to get activities, but that's about it at the minute. I would appreciate help from anyone in identifying the other URLs that need to be updated. The are currently for the following methods:

  • getActivityTypes()
  • getActivitySummary()
  • getActivityDetails()
  • getExtendedActivityDetails()
  • getDataFile()

The way that I captured authentication and getActivityList(), was to login to Garmin Connect in Google Chrome with Developer Tools open, hit the Record button in the Network tab, and filter all XHR requests - these are invariable the API calls being made at various points.

Even more data?

Hi there,

activity Data is fine and i love it. But would be even more interested in

  • sleep quality
  • weight
  • stress Level

and so on.

Any chance to query that? I'd be happy to implement it myself and make it available for pull, but i lack the API documentation for reaearch.

issues with authentication process

Authorize function is returning the error "Authentication failed - please check your credentials" because the login form needs a csrf value, apparently. Has anyone gone over this?

Authentication issue

I have been using this wonderful script for a while now but now suddenly I get an error: "Oops: "lt" value wasn't found in response"

Did garmin change the authentication somehow and could you provide a fix?

can not get activities back (using v1.0.2)

I've a Garmin vivosmart HR and it's syncing it's data with Garmin Connect. If I try to get the recorded activities by calling getActivityList(), all I get back is this:

stdClass Object
(
    [results] => stdClass Object
        (
            [search] => stdClass Object
                (
                    [query] => stdClass Object
                        (
                            [filters] => stdClass Object
                                (
                                    [userId] => 51301577
                                    [userId_oper] => =
                                )

                            [sortOrder] => DESC
                            [sortField] => activitySummaryBeginTimestampGmt
                            [activityStart] => 0
                            [activitiesPerPage] => 10
                            [explore] => false
                            [ignoreUntitled] => false
                            [ignoreNonGPS] => false
                        )

                    [currentPage] => 1
                    [totalFound] => 0
                    [totalPages] => 0
                )

        )

)

So, what's wrong?

fatal error when it errs on the login credentials

Hello,
first thank a lot for your work.
Sorry for my english but i m french.
when I'm wrong about connection information
a receive a fatal error.
and i break my site.
Fatal error: Uncaught dawguk\GarminConnect\exceptions\AuthenticationException: Looks like the authentication failed in src/dawguk/GarminConnect.php:143 Stack trace: #0 src/dawguk/GarminConnect.php(76): dawguk\GarminConnect->authorize('xxx...', 'xxx') #1 modules/page/choix_app.php(188): dawguk\GarminConnect->__construct(Array) #2 index.php(34): include('/var/www/html/s...') #3 {main} thrown in /src/dawguk/GarminConnect.php on line 143

can you help me.

Authentication Issue...

I'm getting the "Oops: "lt" value wasn't found in response" as was described in issue #12.

Has Garmin's authentication changed again or am I doing something wrong?

Manipulate the Garmin data

Is there any way to manipulate the Garmin data - e.g. put activities on the strength training session or fix the title of the individual training sessions?

Access denied - This website is using a security service to protect itself from online attacks.

The Garmin Service SSO (single sign on) returns access denied.
Additional Information:

  • This website is using a security service to protect itself from online attacks.
  • Error reference number: 1020

Trouble Shooting

  • I tried to fake the User-Agent, but this does not help.
  • I tried to change the ip adress by using a vpn network
  • The URI https://sso.garmin.com/sso/login returns the error "An unexpected error has occurred." I Think this is a common SSO-service problem by garmin. :-(
    grafik

Doese any one have the same issue?
Is there a possibility to use the service?

Oops: SSO prestart error (code: 0, message: )

Hello,

I've installed the API on my server. When I try to run the "full example", I get the following error:
Oops: SSO prestart error (code: 0, message: )

Can you provide some support please ?

Thanks

Can't get summary of newwest activities

Hello,

I have problem with getting summary of activities using getActivitySummary($intActivityID) which are done after 1 of August (probably). I think Garmin changed something in their API because:

This one was created 25.07 and it works:
https://connect.garmin.com/modern/proxy/activity-service/activity/1875872198

This one was created 03.08 and it's the same type of activity:
https://connect.garmin.com/modern/proxy/activity-service/activity/1893087702

as you can see, response is:
{"message":"HTTP 403 Forbidden","error":"WebApplicationException"}

Nothing was changed in privacy settings in Garmin account. Activity made 29.07 works too. Maybe you faced similar issue earlier?

Cheers,
Maciej.

Authentication failed

Hi,

it looks like the class GarminConnect is not working anymore for me.
The authorize function returns "Authentication failed - please check your credentials".

Any other is receiving this error since today?

Thank you

Kind regards,
Luis Estéfano

Getting all activities or just selected ones

Hi,

ok so I got this working now. And if I use the $obj_results = $objGarminConnect->getActivityList(0, 1);
it will show me a result and I have a total of 142 activities.
So when I try to add a bigger limit like $obj_results = $objGarminConnect->getActivityList(0, 150);
it gives an http 400 error.

Any way to only list / print only selected activities like cycling?

Br.
Toube

getActivityList returns 403 error

Every function is working except the getActivityList. The service returns:

An unexpected response code was found: 403

Every other function is working and authentication is also working

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.