@flow-js/garmin-connect 1.6.5 → 1.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +705 -523
- package/dist/garmin/GarminConnect.d.ts +293 -4
- package/dist/garmin/GarminConnect.js +311 -56
- package/dist/garmin/GarminConnect.js.map +1 -1
- package/dist/garmin/UrlClass.d.ts +1 -0
- package/dist/garmin/UrlClass.js +3 -0
- package/dist/garmin/UrlClass.js.map +1 -1
- package/dist/garmin/types/calendar.d.ts +82 -158
- package/examples/example-workout.js +1 -1
- package/examples/example.js +1 -1
- package/package.json +1 -1
- package/dist/garmin/workouts/Running.d.ts +0 -16
- package/dist/garmin/workouts/Running.js +0 -64
- package/dist/garmin/workouts/Running.js.map +0 -1
- package/dist/garmin/workouts/templates/RunningTemplate.d.ts +0 -68
- package/dist/garmin/workouts/templates/RunningTemplate.js +0 -78
- package/dist/garmin/workouts/templates/RunningTemplate.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,42 +1,61 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Garmin Connect
|
|
2
2
|
|
|
3
|
-
This is a fork of https://github.com/Pythe1337N/garmin-connect
|
|
3
|
+
This is a fork of https://github.com/Pythe1337N/garmin-connect which was inspired by [https://github.com/matin/garth](https://github.com/matin/garth). Many thanks to contributors.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
A JavaScript library for accessing and managing your Garmin Connect data. It comes with methods to get and set information in your Garmin account, and also supports [custom requests](#custom-requests) using `GET`, `POST`, and `PUT` so you can cover additional needs.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- [x] Login and get user token
|
|
11
|
-
- [x] Garmin URLs works with `garmin.cn` and `garmin.com`
|
|
12
|
-
- [x] Auto refresh Ouath2 token
|
|
13
|
-
- [x] Oauth1,Oauth2 token import and export.
|
|
14
|
-
- [x] Download Activity, countActivities, getActivities, getActivity, getUserProfile, getUserSettings
|
|
15
|
-
- [x] Upload Activity, delete Activity
|
|
16
|
-
- [ ] Implementation of other methods:
|
|
17
|
-
- [ ] Badge
|
|
18
|
-
- [x] Gear
|
|
19
|
-
- [x] Workout
|
|
20
|
-
- [x] Course
|
|
21
|
-
- ...etc
|
|
22
|
-
- [ ] Handle MFA
|
|
23
|
-
- [x] Handle Account locked
|
|
24
|
-
- [ ] Unit test
|
|
25
|
-
- [ ] Listeners
|
|
9
|
+
This document provides detailed information about the public API methods available in the `@flow-js/garmin-connect` library.
|
|
26
10
|
|
|
27
|
-
|
|
11
|
+
## Table of Contents
|
|
28
12
|
|
|
29
|
-
|
|
13
|
+
- [Authentication](#authentication)
|
|
14
|
+
- [Constructor](#constructor)
|
|
15
|
+
- [Login](#login)
|
|
16
|
+
- [Session Management](#session-management)
|
|
17
|
+
- [User Data](#user-data)
|
|
18
|
+
- [User Profile](#user-profile)
|
|
19
|
+
- [User Settings](#user-settings)
|
|
20
|
+
- [Activities](#activities)
|
|
21
|
+
- [Getting Activities](#getting-activities)
|
|
22
|
+
- [Individual Activity Operations](#individual-activity-operations)
|
|
23
|
+
- [Activity Files](#activity-files)
|
|
24
|
+
- [Workouts](#workouts)
|
|
25
|
+
- [Managing Workouts](#managing-workouts)
|
|
26
|
+
- [Workout Scheduling](#workout-scheduling)
|
|
27
|
+
- [Health Data](#health-data)
|
|
28
|
+
- [Steps](#steps)
|
|
29
|
+
- [Sleep](#sleep)
|
|
30
|
+
- [Weight](#weight)
|
|
31
|
+
- [Hydration](#hydration)
|
|
32
|
+
- [Heart Rate](#heart-rate)
|
|
33
|
+
- [Golf](#golf)
|
|
34
|
+
- [Gear](#gear)
|
|
35
|
+
- [GPX and Courses](#gpx-and-courses)
|
|
36
|
+
- [Calendar](#calendar)
|
|
37
|
+
- [Custom Requests](#custom-requests)
|
|
30
38
|
|
|
31
|
-
|
|
39
|
+
## Authentication
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
### Constructor
|
|
42
|
+
|
|
43
|
+
Create a new instance of the Garmin Connect client.
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
const { GarminConnect } = require('@flow-js/garmin-connect');
|
|
34
47
|
|
|
35
|
-
|
|
48
|
+
// Create a new Garmin Connect Client with credentials
|
|
49
|
+
const GCClient = new GarminConnect({
|
|
50
|
+
username: 'my.email@example.com',
|
|
51
|
+
password: 'MySecretPassword'
|
|
52
|
+
});
|
|
36
53
|
|
|
37
|
-
|
|
54
|
+
// Alternatively, create a client using credentials from garmin.config.json
|
|
55
|
+
const GCClient = new GarminConnect();
|
|
56
|
+
```
|
|
38
57
|
|
|
39
|
-
|
|
58
|
+
You can also provide a configuration file named `garmin.config.json` at your project root:
|
|
40
59
|
|
|
41
60
|
```json
|
|
42
61
|
{
|
|
@@ -45,164 +64,144 @@ This library will require you to add a configuration file to your project root c
|
|
|
45
64
|
}
|
|
46
65
|
```
|
|
47
66
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```shell
|
|
51
|
-
$ npm install garmin-connect
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## How to use
|
|
67
|
+
### Login
|
|
55
68
|
|
|
56
69
|
```js
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
await GCClient.login();
|
|
65
|
-
const userProfile = await GCClient.getUserProfile();
|
|
70
|
+
/**
|
|
71
|
+
* Login to Garmin Connect with provided credentials or those set during construction
|
|
72
|
+
* @param username - Optional username to override the one in credentials
|
|
73
|
+
* @param password - Optional password to override the one in credentials
|
|
74
|
+
* @returns The GarminConnect instance for chaining
|
|
75
|
+
*/
|
|
76
|
+
async login(username?: string, password?: string): Promise<GarminConnect>
|
|
66
77
|
```
|
|
67
78
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
## Reusing your session(since v1.6.0)
|
|
71
|
-
|
|
72
|
-
### Save token to file and reuse it.
|
|
79
|
+
Example:
|
|
73
80
|
|
|
74
81
|
```js
|
|
75
|
-
GCClient.
|
|
82
|
+
await GCClient.login();
|
|
83
|
+
// Or with specific credentials
|
|
84
|
+
await GCClient.login('my.email@example.com', 'MySecretPassword');
|
|
76
85
|
```
|
|
77
86
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
$ ls /path/to/save/tokens
|
|
82
|
-
oauth1_token.json oauth2_token.json
|
|
83
|
-
```
|
|
87
|
+
### Session Management
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
#### Export Tokens
|
|
86
90
|
|
|
87
91
|
```js
|
|
88
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Exports OAuth tokens to files in the specified directory
|
|
94
|
+
* @param dirPath - Directory path where token files will be saved
|
|
95
|
+
*/
|
|
96
|
+
exportTokenToFile(dirPath: string): void
|
|
89
97
|
```
|
|
90
98
|
|
|
91
|
-
|
|
99
|
+
Example:
|
|
92
100
|
|
|
93
101
|
```js
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
// save to db or other storage
|
|
97
|
-
...
|
|
102
|
+
GCClient.exportTokenToFile('/path/to/save/tokens');
|
|
103
|
+
// Creates oauth1_token.json and oauth2_token.json in the specified directory
|
|
98
104
|
```
|
|
99
105
|
|
|
100
|
-
|
|
106
|
+
#### Load Tokens from Files
|
|
101
107
|
|
|
102
108
|
```js
|
|
103
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Loads OAuth tokens from files in the specified directory
|
|
111
|
+
* @param dirPath - Directory path where token files are stored
|
|
112
|
+
* @throws Error if directory not found
|
|
113
|
+
*/
|
|
114
|
+
loadTokenByFile(dirPath: string): void
|
|
104
115
|
```
|
|
105
116
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
This is an experimental feature and might not yet provide full stability.
|
|
109
|
-
|
|
110
|
-
After a successful login the `sessionJson` getter and setter can be used to export and restore your session.
|
|
117
|
+
Example:
|
|
111
118
|
|
|
112
119
|
```js
|
|
113
|
-
|
|
114
|
-
const session = GCClient.sessionJson;
|
|
115
|
-
|
|
116
|
-
// Use this instead of GCClient.login() to restore the session
|
|
117
|
-
// This will throw an error if the stored session cannot be reused
|
|
118
|
-
GCClient.restore(session);
|
|
120
|
+
GCClient.loadTokenByFile('/path/to/save/tokens');
|
|
119
121
|
```
|
|
120
122
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
A stored session can only be reused once and will need to be stored after each request. This can be done by attaching some storage to the `sessionChange` event.
|
|
123
|
+
#### Export Tokens as Object
|
|
124
124
|
|
|
125
125
|
```js
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Exports OAuth tokens as an object
|
|
128
|
+
* @returns Object containing OAuth1 and OAuth2 tokens
|
|
129
|
+
* @throws Error if tokens are not found
|
|
130
|
+
*/
|
|
131
|
+
exportToken(): IGarminTokens
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
To make sure to use a stored session if possible, but fallback to regular login, one can use the `restoreOrLogin` method.
|
|
137
|
-
The arguments `username` and `password` are both optional and the regular `.login()` will be
|
|
138
|
-
called if session restore fails.
|
|
134
|
+
#### Load Tokens from Objects
|
|
139
135
|
|
|
140
136
|
```js
|
|
141
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Loads OAuth tokens from provided token objects (e.g., from DB or localStorage)
|
|
139
|
+
* @param oauth1 - OAuth1 token object
|
|
140
|
+
* @param oauth2 - OAuth2 token object
|
|
141
|
+
*/
|
|
142
|
+
loadToken(oauth1: IOauth1Token, oauth2: IOauth2Token): void
|
|
142
143
|
```
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
- `sessionChange` will trigger on a change in the current `sessionJson`
|
|
147
|
-
|
|
148
|
-
To attach a listener to an event, use the `.on()` method.
|
|
145
|
+
Example:
|
|
149
146
|
|
|
150
147
|
```js
|
|
151
|
-
|
|
148
|
+
const oauth1 = GCClient.client.oauth1Token;
|
|
149
|
+
const oauth2 = GCClient.client.oauth2Token;
|
|
150
|
+
// Later, use these to restore the session
|
|
151
|
+
GCClient.loadToken(oauth1, oauth2);
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
## Reading data
|
|
154
|
+
## User Data
|
|
157
155
|
|
|
158
|
-
### User
|
|
159
|
-
|
|
160
|
-
Receive basic user information
|
|
156
|
+
### User Profile
|
|
161
157
|
|
|
162
158
|
```js
|
|
163
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Retrieves the user's social profile from Garmin Connect
|
|
161
|
+
* @returns User's social profile data
|
|
162
|
+
*/
|
|
163
|
+
async getUserProfile(): Promise<ISocialProfile>
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
Receive social user information
|
|
166
|
+
Example:
|
|
169
167
|
|
|
170
168
|
```js
|
|
171
|
-
GCClient.
|
|
169
|
+
const userProfile = await GCClient.getUserProfile();
|
|
170
|
+
console.log(userProfile.userName); // Verify login was successful
|
|
172
171
|
```
|
|
173
172
|
|
|
174
|
-
###
|
|
175
|
-
|
|
176
|
-
Get a list of all social connections
|
|
173
|
+
### User Settings
|
|
177
174
|
|
|
178
175
|
```js
|
|
179
|
-
|
|
176
|
+
/**
|
|
177
|
+
* Retrieves the user's settings from Garmin Connect
|
|
178
|
+
* @returns User settings data
|
|
179
|
+
*/
|
|
180
|
+
async getUserSettings(): Promise<IUserSettings>
|
|
180
181
|
```
|
|
181
182
|
|
|
182
|
-
|
|
183
|
+
## Activities
|
|
183
184
|
|
|
184
|
-
|
|
185
|
+
### Getting Activities
|
|
185
186
|
|
|
186
187
|
```js
|
|
187
|
-
|
|
188
|
+
/**
|
|
189
|
+
* Retrieves a list of activities matching the specified criteria
|
|
190
|
+
* @param start - Optional starting index for pagination
|
|
191
|
+
* @param limit - Optional limit for pagination
|
|
192
|
+
* @param activityType - Optional activity type filter
|
|
193
|
+
* @param subActivityType - Optional activity subtype filter
|
|
194
|
+
* @returns Array of activities matching the criteria
|
|
195
|
+
*/
|
|
196
|
+
async getActivities(
|
|
197
|
+
start?: number,
|
|
198
|
+
limit?: number,
|
|
199
|
+
activityType?: ActivityType,
|
|
200
|
+
subActivityType?: ActivitySubType
|
|
201
|
+
): Promise<IActivity[]>
|
|
188
202
|
```
|
|
189
203
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
Retrieves a list of activities based on specified parameters.
|
|
193
|
-
|
|
194
|
-
#### Parameters:
|
|
195
|
-
|
|
196
|
-
- `start` (number, optonal): Index to start fetching activities.
|
|
197
|
-
- `limit` (number, optonal): Number of activities to retrieve.
|
|
198
|
-
- `activityType` (ActivityType, optional): Type of activity (if specified, start must be null).
|
|
199
|
-
- `subActivityType` (ActivitySubType, optional): Subtype of activity (if specified, start must be null).
|
|
200
|
-
|
|
201
|
-
#### Returns:
|
|
202
|
-
|
|
203
|
-
- `Promise<IActivity[]>`: A Promise that resolves to an array of activities.
|
|
204
|
-
|
|
205
|
-
#### Example:
|
|
204
|
+
Example:
|
|
206
205
|
|
|
207
206
|
```js
|
|
208
207
|
const activities = await GCClient.getActivities(
|
|
@@ -213,415 +212,598 @@ const activities = await GCClient.getActivities(
|
|
|
213
212
|
);
|
|
214
213
|
```
|
|
215
214
|
|
|
216
|
-
### `getActivity(activity: { activityId: GCActivityId }): Promise<IActivity>`
|
|
217
|
-
|
|
218
|
-
Retrieves details for a specific activity based on the provided `activityId`.
|
|
219
|
-
|
|
220
|
-
#### Parameters:
|
|
221
|
-
|
|
222
|
-
- `activity` (object): An object containing the `activityId` property.
|
|
223
|
-
|
|
224
|
-
- `activityId` (GCActivityId): Identifier for the desired activity.
|
|
225
|
-
|
|
226
|
-
#### Returns:
|
|
227
|
-
|
|
228
|
-
- `Promise<IActivity>`: A Promise that resolves to the details of the specified activity.
|
|
229
|
-
|
|
230
|
-
#### Example:
|
|
231
|
-
|
|
232
215
|
```js
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
### News Feed is not implemented yet. // TODO: Implement this function
|
|
239
|
-
|
|
240
|
-
To get a list of activities in your news feed, use the `getNewsFeed` method. This function takes two arguments, _start_ and _limit_, which is used for pagination. Both are optional and will default to whatever Garmin Connect is using. To be sure to get all activities, use this correctly.
|
|
241
|
-
|
|
242
|
-
```js
|
|
243
|
-
// Get the news feed with a default length with most recent activities
|
|
244
|
-
GCClient.getNewsFeed();
|
|
245
|
-
// Get activities in feed, 10 through 15. (start 10, limit 5)
|
|
246
|
-
GCClient.getNewsFeed(10, 5);
|
|
216
|
+
/**
|
|
217
|
+
* Counts lifetime activities
|
|
218
|
+
* @returns Activity statistics including counts by type
|
|
219
|
+
*/
|
|
220
|
+
async countActivities(): Promise<ICountActivities>
|
|
247
221
|
```
|
|
248
222
|
|
|
249
|
-
###
|
|
250
|
-
|
|
251
|
-
Use the activityId to download the original activity data. Usually this is supplied as a .zip file.
|
|
223
|
+
### Individual Activity Operations
|
|
252
224
|
|
|
253
225
|
```js
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Retrieves a specific activity by its ID
|
|
228
|
+
* @param activity - Object containing activityId
|
|
229
|
+
* @returns Details of the specified activity
|
|
230
|
+
* @throws Error if activityId is missing
|
|
231
|
+
*/
|
|
232
|
+
async getActivity(activity: {
|
|
233
|
+
activityId: GCActivityId;
|
|
234
|
+
}): Promise<IActivity>
|
|
258
235
|
```
|
|
259
236
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
Uploads an activity file as a new Activity. The file can be a `gpx`, `tcx`, or `fit` file. If the activity already exists, the result will have a status code of 409.
|
|
263
|
-
Upload fixed in 1.4.4, Garmin changed the upload api, the response `detailedImportResult` doesn't contain the new activityId.
|
|
237
|
+
Example:
|
|
264
238
|
|
|
265
239
|
```js
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const uploadId = upload.detailedImportResult.uploadId;
|
|
240
|
+
const activityDetails = await GCClient.getActivity({
|
|
241
|
+
activityId: 'exampleActivityId'
|
|
242
|
+
});
|
|
270
243
|
```
|
|
271
244
|
|
|
272
|
-
### Upload activity image
|
|
273
|
-
|
|
274
|
-
Uploads an image to activity
|
|
275
|
-
|
|
276
245
|
```js
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
246
|
+
/**
|
|
247
|
+
* Deletes an activity by activityId
|
|
248
|
+
* @param activity - with activityId
|
|
249
|
+
* @returns void
|
|
250
|
+
*
|
|
251
|
+
*/
|
|
252
|
+
async deleteActivity(activity: {
|
|
253
|
+
activityId: GCActivityId;
|
|
254
|
+
}): Promise<void>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
```js
|
|
258
|
+
/**
|
|
259
|
+
* Renames an activity with the given activityId to the newName.
|
|
260
|
+
* @param activityId
|
|
261
|
+
* @param newName
|
|
262
|
+
*/
|
|
263
|
+
async renameActivity(
|
|
264
|
+
activityId: GCActivityId,
|
|
265
|
+
newName: string
|
|
266
|
+
): Promise<void>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Activity Files
|
|
270
|
+
|
|
271
|
+
`````ts
|
|
272
|
+
/**
|
|
273
|
+
* Download activity original data file
|
|
274
|
+
*
|
|
275
|
+
* Use the activityId to download the original activity data. Usually this is supplied as a .zip file.
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```js
|
|
279
|
+
* const [activity] = await GCClient.getActivities(0, 1);
|
|
280
|
+
* // Directory path is optional and defaults to the current working directory.
|
|
281
|
+
* // Downloads filename will be supplied by Garmin.
|
|
282
|
+
* GCClient.downloadOriginalActivityData(activity, './some/path/that/exists');
|
|
283
|
+
* ```
|
|
284
|
+
*
|
|
285
|
+
* @param activity - with activityId
|
|
286
|
+
* @param dir - directory to save the file
|
|
287
|
+
* @param type - 'zip' | 'gpx' | 'tcx' | 'kml' (default: 'zip')
|
|
288
|
+
*/
|
|
289
|
+
async downloadOriginalActivityData(
|
|
290
|
+
activity: { activityId: GCActivityId },
|
|
291
|
+
dir: string,
|
|
292
|
+
type: ExportFileTypeValue = 'zip'
|
|
293
|
+
): Promise<void>
|
|
294
|
+
``` `
|
|
295
|
+
|
|
296
|
+
```js
|
|
297
|
+
/**
|
|
298
|
+
* Uploads an activity file
|
|
299
|
+
*
|
|
300
|
+
* Uploads an activity file as a new Activity. The file can be a 'gpx', 'tcx', or 'fit' file.
|
|
301
|
+
* If the activity already exists, the result will have a status code of 409.
|
|
302
|
+
* Note: Garmin changed the upload API in v1.4.4, the response `detailedImportResult` no longer contains the new activityId.
|
|
303
|
+
*
|
|
304
|
+
* @param file - Path to the activity file
|
|
305
|
+
* @param format - 'fit' | 'gpx' | 'tcx'
|
|
306
|
+
* @returns Response from the upload operation
|
|
307
|
+
*/
|
|
308
|
+
async uploadActivity(
|
|
309
|
+
file: string,
|
|
310
|
+
format: UploadFileTypeTypeValue = 'fit'
|
|
311
|
+
)
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Example:
|
|
288
315
|
|
|
289
316
|
```js
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
317
|
+
const upload = await GCClient.uploadActivity('./some/path/to/file.fit');
|
|
318
|
+
// Note: Garmin changed the upload API in v1.4.4
|
|
319
|
+
// const activityId = upload.detailedImportResult.successes[0].internalId; // Not working
|
|
320
|
+
// const uploadId = upload.detailedImportResult.uploadId;
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Workouts
|
|
324
|
+
|
|
325
|
+
### Managing Workouts
|
|
326
|
+
|
|
327
|
+
```js
|
|
328
|
+
/**
|
|
329
|
+
* Gets the list of workouts
|
|
330
|
+
* @param start
|
|
331
|
+
* @param limit
|
|
332
|
+
*/
|
|
333
|
+
async getWorkouts(start: number, limit: number): Promise<IWorkout[]>
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
```js
|
|
337
|
+
/**
|
|
338
|
+
* Gets the workout detail by workoutId
|
|
339
|
+
* @param workout
|
|
340
|
+
* @returns workout detail - IWorkoutDetail
|
|
341
|
+
*/
|
|
342
|
+
async getWorkoutDetail(workout: {
|
|
343
|
+
workoutId: string;
|
|
344
|
+
}): Promise<IWorkoutDetail>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
````js
|
|
348
|
+
/**
|
|
349
|
+
* Creates a new workout
|
|
350
|
+
*
|
|
351
|
+
* Use workoutBuilder to create the workout object. See the example in the examples/example-workout.js for more complex workouts.
|
|
352
|
+
*
|
|
353
|
+
* @param workout - workout detail
|
|
354
|
+
* @returns Response from the workout creation operation
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* ```js
|
|
358
|
+
* const wb = new WorkoutBuilder(
|
|
359
|
+
* WorkoutType.Running,
|
|
360
|
+
* 'Workout running ' + new Date().toISOString()
|
|
361
|
+
* );
|
|
362
|
+
*
|
|
363
|
+
* wb.addStep(
|
|
364
|
+
* new Step(
|
|
365
|
+
* StepType.Run,
|
|
366
|
+
* TimeDuration.fromSeconds(45),
|
|
367
|
+
* new NoTarget(),
|
|
368
|
+
* 'Comment for the step: Run for 45 seconds'
|
|
369
|
+
* )
|
|
370
|
+
* );
|
|
371
|
+
*
|
|
372
|
+
* GCClient.createWorkout(wb.build());
|
|
373
|
+
* ```
|
|
374
|
+
*/
|
|
375
|
+
async createWorkout(workout: IWorkoutDetail)
|
|
376
|
+
`````
|
|
377
|
+
|
|
378
|
+
````js
|
|
379
|
+
/**
|
|
380
|
+
* Deletes a workout by workoutId
|
|
381
|
+
* @param workout - with workoutId
|
|
382
|
+
*
|
|
383
|
+
* @example
|
|
384
|
+
* ```js
|
|
385
|
+
* const workouts = await GCClient.getWorkouts();
|
|
386
|
+
* const id = workouts[0].workoutId;
|
|
387
|
+
* GCClient.deleteWorkout({ workoutId: id });
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
async deleteWorkout(workout: { workoutId: string })
|
|
391
|
+
````
|
|
392
|
+
|
|
393
|
+
```js
|
|
394
|
+
/**
|
|
395
|
+
* Retrieves all workouts
|
|
396
|
+
* @returns List of workouts
|
|
397
|
+
*/
|
|
398
|
+
async workouts(): Promise<Workout[]>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Workout Scheduling
|
|
402
|
+
|
|
403
|
+
````js
|
|
404
|
+
/**
|
|
405
|
+
* Schedule a workout by workoutId to a specific date
|
|
406
|
+
*
|
|
407
|
+
* To add a workout to your calendar, provide the workout id and the date to schedule it on.
|
|
408
|
+
*
|
|
409
|
+
* @param workout - with workoutId
|
|
410
|
+
* @param scheduleDate - 'YYYY-MM-DD' format date string
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* ```js
|
|
414
|
+
* const workouts = await GCClient.getWorkouts();
|
|
415
|
+
* const id = workouts[0].workoutId;
|
|
416
|
+
* GCClient.scheduleWorkout({ workoutId: id }, new Date('2025-12-01'));
|
|
417
|
+
* ```
|
|
418
|
+
*/
|
|
419
|
+
async scheduleWorkout(
|
|
420
|
+
workout: { workoutId: string },
|
|
421
|
+
scheduleDate: string
|
|
422
|
+
)
|
|
423
|
+
````
|
|
424
|
+
|
|
425
|
+
## Health Data
|
|
426
|
+
|
|
427
|
+
### Steps
|
|
428
|
+
|
|
429
|
+
```js
|
|
430
|
+
/**
|
|
431
|
+
* Retrieves step count for a specific date
|
|
432
|
+
* @param date - The date to get step count for, defaults to current date
|
|
433
|
+
* @returns Total step count for the specified date
|
|
434
|
+
* @throws Error if steps data not found for the date
|
|
435
|
+
*/
|
|
436
|
+
async getSteps(date = new Date()): Promise<number>
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
Example:
|
|
312
440
|
|
|
313
441
|
```js
|
|
314
442
|
const totalSteps = await GCClient.getSteps(new Date('2020-03-24'));
|
|
315
443
|
```
|
|
316
444
|
|
|
317
|
-
###
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
```js
|
|
386
|
-
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
445
|
+
### Sleep
|
|
446
|
+
|
|
447
|
+
```js
|
|
448
|
+
/**
|
|
449
|
+
* Retrieves sleep data for a specific date
|
|
450
|
+
* @param date - The date to get sleep data for, defaults to current date
|
|
451
|
+
* @returns Sleep data for the specified date
|
|
452
|
+
* @throws Error if sleep data is invalid or empty
|
|
453
|
+
*/
|
|
454
|
+
async getSleepData(date = new Date()): Promise<SleepData>
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
````js
|
|
458
|
+
/**
|
|
459
|
+
* Calculates sleep duration for a specific date
|
|
460
|
+
*
|
|
461
|
+
* Retrieves hours and minutes slept for a given date.
|
|
462
|
+
*
|
|
463
|
+
* @param date - The date to get sleep duration for, defaults to current date
|
|
464
|
+
* @returns Object with hours and minutes of sleep
|
|
465
|
+
* @throws Error if sleep data is missing or invalid
|
|
466
|
+
*
|
|
467
|
+
* @example
|
|
468
|
+
* ```js
|
|
469
|
+
* const detailedSleep = await GCClient.getSleepDuration(new Date('2020-03-24'));
|
|
470
|
+
* console.log(`Hours: ${detailedSleep.hours}, Minutes: ${detailedSleep.minutes}`);
|
|
471
|
+
* ```
|
|
472
|
+
*/
|
|
473
|
+
async getSleepDuration(
|
|
474
|
+
date = new Date()
|
|
475
|
+
): Promise<{ hours: number; minutes: number }>
|
|
476
|
+
````
|
|
477
|
+
|
|
478
|
+
### Weight
|
|
479
|
+
|
|
480
|
+
```js
|
|
481
|
+
/**
|
|
482
|
+
* Retrieves weight data for a specific date
|
|
483
|
+
* @param date - The date to get weight data for, defaults to current date
|
|
484
|
+
* @returns Weight data for the specified date
|
|
485
|
+
* @throws Error if weight data is invalid or empty
|
|
486
|
+
*/
|
|
487
|
+
async getDailyWeightData(date = new Date()): Promise<WeightData>
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
```js
|
|
491
|
+
/**
|
|
492
|
+
* Retrieves weight data in pounds for a specific date
|
|
493
|
+
* @param date - The date to get weight data for, defaults to current date
|
|
494
|
+
* @returns Weight in pounds for the specified date
|
|
495
|
+
* @throws Error if valid weight data not found for the date
|
|
496
|
+
*/
|
|
497
|
+
async getDailyWeightInPounds(date = new Date()): Promise<number>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
````js
|
|
501
|
+
/**
|
|
502
|
+
* Updates weight data for a specific date
|
|
503
|
+
*
|
|
504
|
+
* Updates weight information for the specified date.
|
|
505
|
+
*
|
|
506
|
+
* @param date - The date for the weight data, defaults to current date
|
|
507
|
+
* @param lbs - Weight value in pounds
|
|
508
|
+
* @param timezone - Timezone string for correct timestamp conversion
|
|
509
|
+
* @returns Response from the weight update operation
|
|
510
|
+
* @throws Error if update fails
|
|
511
|
+
*
|
|
512
|
+
* @example
|
|
513
|
+
* ```js
|
|
514
|
+
* await GCClient.updateWeight(undefined, 202.9, 'America/Los_Angeles');
|
|
515
|
+
* ```
|
|
516
|
+
*/
|
|
517
|
+
async updateWeight(
|
|
518
|
+
date = new Date(),
|
|
519
|
+
lbs: number,
|
|
520
|
+
timezone: string
|
|
521
|
+
): Promise<UpdateWeight>
|
|
522
|
+
````
|
|
523
|
+
|
|
524
|
+
### Hydration
|
|
525
|
+
|
|
526
|
+
```js
|
|
527
|
+
/**
|
|
528
|
+
* Retrieves hydration data in fluid ounces for a specific date
|
|
529
|
+
* @param date - The date to get hydration data for, defaults to current date
|
|
530
|
+
* @returns Hydration value in fluid ounces for the specified date
|
|
531
|
+
* @throws Error if hydration data is invalid or empty
|
|
532
|
+
*/
|
|
533
|
+
async getDailyHydration(date = new Date()): Promise<number>
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
````js
|
|
537
|
+
/**
|
|
538
|
+
* Updates hydration log with fluid ounces for a specific date
|
|
539
|
+
*
|
|
540
|
+
* Adds a hydration log entry in ounces for a given date.
|
|
541
|
+
*
|
|
542
|
+
* @param date - The date for the hydration data, defaults to current date
|
|
543
|
+
* @param valueInOz - Hydration value in fluid ounces. Accepts negative number.
|
|
544
|
+
* @returns Response from the hydration update operation
|
|
545
|
+
* @throws Error if update fails
|
|
546
|
+
*
|
|
547
|
+
* @example
|
|
548
|
+
* ```js
|
|
549
|
+
* const hydrationLogEntry = await GCClient.updateHydrationLogOunces(
|
|
550
|
+
* new Date('2020-03-24'),
|
|
551
|
+
* 16
|
|
552
|
+
* );
|
|
553
|
+
* ```
|
|
554
|
+
*/
|
|
555
|
+
async updateHydrationLogOunces(
|
|
556
|
+
date = new Date(),
|
|
557
|
+
valueInOz: number
|
|
558
|
+
): Promise<WaterIntake>
|
|
559
|
+
````
|
|
560
|
+
|
|
561
|
+
### Heart Rate
|
|
562
|
+
|
|
563
|
+
````js
|
|
564
|
+
/**
|
|
565
|
+
* Retrieves heart rate data for a specific date
|
|
566
|
+
*
|
|
567
|
+
* Retrieves daily heart rate data for a given date.
|
|
568
|
+
*
|
|
569
|
+
* @param date - The date to get heart rate data for, defaults to current date
|
|
570
|
+
* @returns Heart rate data for the specified date
|
|
571
|
+
* @throws Error if the operation fails
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```js
|
|
575
|
+
* const heartRateData = await GCClient.getHeartRate(new Date('2020-03-24'));
|
|
576
|
+
* ```
|
|
577
|
+
*/
|
|
578
|
+
async getHeartRate(date = new Date()): Promise<HeartRate>
|
|
579
|
+
````
|
|
580
|
+
|
|
581
|
+
## Golf
|
|
582
|
+
|
|
583
|
+
```js
|
|
584
|
+
/**
|
|
585
|
+
* Retrieves golf summary data
|
|
586
|
+
* @returns Summary of golf activities
|
|
587
|
+
* @throws Error if golf summary data is invalid or empty
|
|
588
|
+
*/
|
|
589
|
+
async getGolfSummary(): Promise<GolfSummary>
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
```js
|
|
593
|
+
/**
|
|
594
|
+
* Retrieves golf scorecard for a specific round
|
|
595
|
+
* @param scorecardId - ID of the scorecard to retrieve
|
|
596
|
+
* @returns Golf scorecard data
|
|
597
|
+
* @throws Error if golf scorecard data is invalid or empty
|
|
598
|
+
*/
|
|
599
|
+
async getGolfScorecard(scorecardId: number): Promise<GolfScorecard>
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
## Gear
|
|
603
|
+
|
|
604
|
+
```js
|
|
605
|
+
/**
|
|
606
|
+
* Returns the gear data for the user.
|
|
607
|
+
* @param availableGearDate - Optional date to filter the gear available at the date (format: 'YYYY-MM-DD').
|
|
608
|
+
*/
|
|
609
|
+
async getGear(availableGearDate?: string): Promise<GearData[]>
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
```js
|
|
613
|
+
/**
|
|
614
|
+
* Returns the gear data assigned with a specific activity.
|
|
615
|
+
* @param activityId
|
|
616
|
+
*/
|
|
617
|
+
async getGearsForActivity(activityId: GCActivityId): Promise<GearData[]>
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
```js
|
|
621
|
+
/**
|
|
622
|
+
* Links a gear item to an activity.
|
|
623
|
+
* @param activityId
|
|
624
|
+
* @param gearId - uuid field from GearData
|
|
625
|
+
* @return GearData - the linked gear item data
|
|
626
|
+
*/
|
|
627
|
+
async linkGearToActivity(
|
|
628
|
+
activityId: GCActivityId,
|
|
629
|
+
gearId: GCGearId
|
|
630
|
+
): Promise<GearData>
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
```js
|
|
634
|
+
/**
|
|
635
|
+
* Unlinks a gear item from an activity.
|
|
636
|
+
* @param activityId
|
|
637
|
+
* @param gearId - uuid field from GearData
|
|
638
|
+
* @return GearData - the unlinked gear item data
|
|
639
|
+
*/
|
|
640
|
+
async unlinkGearFromActivity(
|
|
641
|
+
activityId: GCActivityId,
|
|
642
|
+
gearId: GCGearId
|
|
643
|
+
): Promise<GearData>
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
## GPX and Courses
|
|
647
|
+
|
|
648
|
+
````js
|
|
649
|
+
/**
|
|
650
|
+
* Imports GPX file content
|
|
651
|
+
*
|
|
652
|
+
* @example ./examples/example-gpx-file.js
|
|
653
|
+
* @param fileName - Name of the GPX file
|
|
654
|
+
* @param fileContent - Content of the GPX file as string
|
|
655
|
+
* @returns Response from the GPX import operation containing courseName, geoPoints, and coursePoints
|
|
656
|
+
*
|
|
657
|
+
* @example
|
|
658
|
+
* ```js
|
|
659
|
+
* const fileContent = await fs.readFile('paris-marathon.gpx', 'utf8');
|
|
660
|
+
* const response = await GCClient.importGpx('paris-marathon.gpx', fileContent);
|
|
661
|
+
* // The response contains courseName, geoPoints, and coursePoints that can be used with createCourse
|
|
662
|
+
* ```
|
|
663
|
+
*/
|
|
664
|
+
async importGpx(
|
|
665
|
+
fileName: string,
|
|
666
|
+
fileContent: string
|
|
667
|
+
): Promise<ImportedGpxResponse>
|
|
668
|
+
````
|
|
669
|
+
|
|
670
|
+
````js
|
|
671
|
+
/**
|
|
672
|
+
* Creates a course from GPX data
|
|
673
|
+
* You can get geoPoints and coursePoints from the imported GPX file response.
|
|
674
|
+
*
|
|
675
|
+
* @example ./examples/example-gpx-file.js
|
|
676
|
+
* @param activityType - Type of activity for the course
|
|
677
|
+
* @param courseName - Name of the course
|
|
678
|
+
* @param geoPoints - Array of geographical points making up the course
|
|
679
|
+
* @param coursePoints - Optional array of course points (waypoints)
|
|
680
|
+
* @returns Response from the course creation operation containing the courseId
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```js
|
|
684
|
+
* // First import GPX to get geoPoints and coursePoints
|
|
685
|
+
* const response = await GCClient.importGpx('course.gpx', gpxFileContent);
|
|
686
|
+
*
|
|
687
|
+
* // Then create the course
|
|
688
|
+
* const createCourseResponse = await GCClient.createCourse(
|
|
689
|
+
* 1, // activityType (1 = running)
|
|
690
|
+
* response.courseName,
|
|
691
|
+
* response.geoPoints,
|
|
692
|
+
* response.coursePoints
|
|
693
|
+
* );
|
|
694
|
+
*
|
|
695
|
+
* console.log('Course created with id:', createCourseResponse.courseId);
|
|
696
|
+
* ```
|
|
697
|
+
*/
|
|
698
|
+
async createCourse(
|
|
699
|
+
activityType: GpxActivityType,
|
|
700
|
+
courseName: string,
|
|
701
|
+
geoPoints: GeoPoint[],
|
|
702
|
+
coursePoints: CoursePoint[] = []
|
|
703
|
+
)
|
|
704
|
+
````
|
|
705
|
+
|
|
706
|
+
````js
|
|
707
|
+
/**
|
|
708
|
+
* Lists all courses
|
|
709
|
+
* @returns List of courses in ListCoursesResponse format
|
|
710
|
+
*
|
|
711
|
+
* @example
|
|
712
|
+
* ```js
|
|
713
|
+
* const listCourses = await GCClient.listCourses();
|
|
714
|
+
* console.log(
|
|
715
|
+
* 'Last course:',
|
|
716
|
+
* listCourses.coursesForUser[0].courseId,
|
|
717
|
+
* listCourses.coursesForUser[0].courseName
|
|
718
|
+
* );
|
|
719
|
+
* ```
|
|
720
|
+
*/
|
|
721
|
+
async listCourses(): Promise<ListCoursesResponse>
|
|
722
|
+
````
|
|
723
|
+
|
|
724
|
+
````js
|
|
725
|
+
/**
|
|
726
|
+
* Exports a course as GPX file content
|
|
727
|
+
* @param courseId - ID of the course to export
|
|
728
|
+
* @returns GPX file content as string
|
|
729
|
+
*
|
|
730
|
+
* @example
|
|
731
|
+
* ```js
|
|
732
|
+
* const downloadGpx = await GCClient.exportCourseAsGpx(courseId);
|
|
733
|
+
* console.log('Downloaded GPX size:', downloadGpx.length);
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
736
|
+
async exportCourseAsGpx(courseId: number): Promise<string>
|
|
737
|
+
````
|
|
738
|
+
|
|
739
|
+
## Calendar
|
|
740
|
+
|
|
741
|
+
```js
|
|
742
|
+
/**
|
|
743
|
+
* Retrieves calendar events for a specific year.
|
|
744
|
+
* @param year {number} - The year for which to retrieve calendar events.
|
|
745
|
+
*/
|
|
746
|
+
async getYearCalendarEvents(year: number): Promise<YearCalendar>
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
```js
|
|
750
|
+
/**
|
|
751
|
+
* Retrieves calendar events for a specific month and year.
|
|
752
|
+
* @param year {number} - The year for which to retrieve calendar events.
|
|
753
|
+
* @param month {number} - The month (0-11) for which to retrieve calendar events.
|
|
754
|
+
*/
|
|
755
|
+
async getMonthCalendarEvents(
|
|
756
|
+
year: number,
|
|
757
|
+
month: number
|
|
758
|
+
): Promise<MonthCalendar>
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
```js
|
|
762
|
+
/**
|
|
763
|
+
* Retrieves calendar events for a specific week containing the given date.
|
|
764
|
+
* @param year {number} - The year of the date.
|
|
765
|
+
* @param month {number} - The month (0-11) of the date.
|
|
766
|
+
* @param day {number} - The day of the first day of the week.
|
|
767
|
+
* @param firstDayOfWeek {number} - Optional first day of the week, default is 1
|
|
768
|
+
*/
|
|
769
|
+
async getWeekCalendarEvents(
|
|
770
|
+
year: number,
|
|
771
|
+
month: number,
|
|
772
|
+
day: number,
|
|
773
|
+
firstDayOfWeek?: number
|
|
774
|
+
): Promise<any>
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
## Custom Requests
|
|
778
|
+
|
|
779
|
+
The library provides methods for making custom requests to the Garmin Connect API:
|
|
780
|
+
|
|
781
|
+
```js
|
|
782
|
+
/**
|
|
783
|
+
* Performs a GET request to the specified URL
|
|
784
|
+
* @param url - URL to send the request to
|
|
785
|
+
* @param data - Optional query parameters or request configuration
|
|
786
|
+
* @returns Response data of type T
|
|
787
|
+
*/
|
|
788
|
+
async get<T>(url: string, data?: any)
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
```js
|
|
792
|
+
/**
|
|
793
|
+
* Performs a POST request to the specified URL
|
|
794
|
+
* @param url - URL to send the request to
|
|
795
|
+
* @param data - Data to send in the request body
|
|
796
|
+
* @returns Response data of type T
|
|
797
|
+
*/
|
|
798
|
+
async post<T>(url: string, data: any)
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
```js
|
|
802
|
+
/**
|
|
803
|
+
* Performs a PUT request to the specified URL
|
|
804
|
+
* @param url - URL to send the request to
|
|
805
|
+
* @param data - Data to send in the request body
|
|
806
|
+
* @returns Response data of type T
|
|
807
|
+
*/
|
|
808
|
+
async put<T>(url: string, data: any)
|
|
407
809
|
```
|
|
408
|
-
|
|
409
|
-
## `getDailyHydration(date?: Date): Promise<number>`
|
|
410
|
-
|
|
411
|
-
Retrieves the daily hydration data and converts it from milliliters to ounces.
|
|
412
|
-
|
|
413
|
-
### Parameters:
|
|
414
|
-
|
|
415
|
-
- `date` (Date, optional): Date of the requested information. Defaults to the current date.
|
|
416
|
-
|
|
417
|
-
### Returns:
|
|
418
|
-
|
|
419
|
-
- `Promise<number>`: A Promise that resolves to the daily hydration data converted from milliliters to ounces.
|
|
420
|
-
|
|
421
|
-
### Throws:
|
|
422
|
-
|
|
423
|
-
- `Error`: If valid daily hydration data cannot be found for the specified date or if the response is invalid.
|
|
424
|
-
|
|
425
|
-
### Example:
|
|
426
|
-
|
|
427
|
-
```js
|
|
428
|
-
const hydrationInOunces = await GCClient.getDailyHydration(
|
|
429
|
-
new Date('2023-12-25')
|
|
430
|
-
);
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
### `getGolfSummary(): Promise<GolfSummary>`
|
|
434
|
-
|
|
435
|
-
Retrieves a summary of golf scorecard data.
|
|
436
|
-
|
|
437
|
-
#### Returns:
|
|
438
|
-
|
|
439
|
-
- `Promise<GolfSummary>`: A Promise that resolves to the golf scorecard summary.
|
|
440
|
-
|
|
441
|
-
#### Example:
|
|
442
|
-
|
|
443
|
-
```js
|
|
444
|
-
const golfSummary = await GCClient.getGolfSummary();
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
### `getGolfScorecard(scorecardId: number): Promise<GolfScorecard>`
|
|
448
|
-
|
|
449
|
-
Retrieves golf scorecard data for a specific scorecard.
|
|
450
|
-
|
|
451
|
-
#### Parameters:
|
|
452
|
-
|
|
453
|
-
- `scorecardId` (number): Identifier for the desired golf scorecard.
|
|
454
|
-
|
|
455
|
-
#### Returns:
|
|
456
|
-
|
|
457
|
-
- `Promise<GolfScorecard>`: A Promise that resolves to the golf scorecard data.
|
|
458
|
-
|
|
459
|
-
#### Example:
|
|
460
|
-
|
|
461
|
-
```js
|
|
462
|
-
const scorecardId = 123; // Replace with the desired scorecard ID
|
|
463
|
-
const golfScorecard = await GCClient.getGolfScorecard(scorecardId);
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
### `getHeartRate(date?: Date): Promise<HeartRate>`
|
|
467
|
-
|
|
468
|
-
Retrieves daily heart rate data for a given date.
|
|
469
|
-
|
|
470
|
-
#### Parameters:
|
|
471
|
-
|
|
472
|
-
- `date` (Date, optional): Date of the heart rate data requested; defaults to today if no date is supplied.
|
|
473
|
-
|
|
474
|
-
#### Returns:
|
|
475
|
-
|
|
476
|
-
- `Promise<HeartRate>`: A Promise that resolves to the daily heart rate data.
|
|
477
|
-
|
|
478
|
-
#### Example:
|
|
479
|
-
|
|
480
|
-
```js
|
|
481
|
-
const heartRateData = await GCClient.getHeartRate(new Date('2020-03-24'));
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
## Modifying data
|
|
485
|
-
|
|
486
|
-
### Update activity is not implemented yet. // TODO: Implement this function
|
|
487
|
-
|
|
488
|
-
```js
|
|
489
|
-
const activities = await GCClient.getActivities(0, 1);
|
|
490
|
-
const activity = activities[0];
|
|
491
|
-
activity['activityName'] = 'The Updated Name';
|
|
492
|
-
await GCClient.updateActivity(activity);
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
### Delete an activity
|
|
496
|
-
|
|
497
|
-
Deletes an activty.
|
|
498
|
-
|
|
499
|
-
```js
|
|
500
|
-
const activities = await GCClient.getActivities(0, 1);
|
|
501
|
-
const activity = activities[0];
|
|
502
|
-
await GCClient.deleteActivity(activity);
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
### `updateHydrationLogOunces(date?: Date, valueInOz: number): Promise<WaterIntake>`
|
|
506
|
-
|
|
507
|
-
Adds a hydration log entry in ounces for a given date.
|
|
508
|
-
|
|
509
|
-
#### Parameters:
|
|
510
|
-
|
|
511
|
-
- `date` (Date, optional): Date of the log entry; defaults to today if no date is supplied.
|
|
512
|
-
- `valueInOz` (number): Amount of water intake in ounces. Accepts negative number.
|
|
513
|
-
|
|
514
|
-
#### Returns:
|
|
515
|
-
|
|
516
|
-
- `Promise<WaterIntake>`: A Promise that resolves to the hydration log entry.
|
|
517
|
-
|
|
518
|
-
#### Example:
|
|
519
|
-
|
|
520
|
-
```js
|
|
521
|
-
const hydrationLogEntry = await GCClient.addHydrationLogOunces(
|
|
522
|
-
new Date('2020-03-24'),
|
|
523
|
-
16
|
|
524
|
-
);
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
### `updateWeight(date = new Date(), lbs: number, timezone: string): Promise<UpdateWeight>`
|
|
528
|
-
|
|
529
|
-
Updates weight information
|
|
530
|
-
|
|
531
|
-
#### Parameters:
|
|
532
|
-
|
|
533
|
-
- `date` (optional): Date object representing the weight entry date. Defaults to the current date if not provided.
|
|
534
|
-
- `lbs` (number): Weight value in pounds.
|
|
535
|
-
- `timezone` (string): String representing the timezone for the weight entry.
|
|
536
|
-
|
|
537
|
-
#### Returns:
|
|
538
|
-
|
|
539
|
-
- `Promise<UpdateWeight>`: A Promise that resolves to the result of the weight update.
|
|
540
|
-
|
|
541
|
-
#### Example:
|
|
542
|
-
|
|
543
|
-
```js
|
|
544
|
-
await GCClient.updateWeight(undefined, 202.9, 'America/Los_Angeles');
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
### Add workout
|
|
548
|
-
|
|
549
|
-
To add a custom workout, use the `addWorkout` or more specifically `addRunningWorkout`.
|
|
550
|
-
|
|
551
|
-
```js
|
|
552
|
-
GCClient.addRunningWorkout('My 5k run', 5000, 'Some description');
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
Will add a running workout of 5km called 'My 5k run' and return a JSON object representing the saved workout.
|
|
556
|
-
|
|
557
|
-
### Schedule workout
|
|
558
|
-
|
|
559
|
-
To add a workout to your calendar, first find your workout and then add it to a specific date.
|
|
560
|
-
|
|
561
|
-
```js
|
|
562
|
-
const workouts = await GCClient.getWorkouts();
|
|
563
|
-
const id = workouts[0].workoutId;
|
|
564
|
-
GCClient.scheduleWorkout({ workoutId: id }, new Date('2020-03-24'));
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
This will add the workout to a specific date in your calendar and make it show up automatically if you're using any of the Garmin watches.
|
|
568
|
-
|
|
569
|
-
### Delete workout
|
|
570
|
-
|
|
571
|
-
Deleting a workout is very similar to [scheduling](#schedule-workout) one.
|
|
572
|
-
|
|
573
|
-
```js
|
|
574
|
-
const workouts = await GCClient.getWorkouts();
|
|
575
|
-
const id = workouts[0].workoutId;
|
|
576
|
-
GCClient.deleteWorkout({ workoutId: id });
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
## Custom requests
|
|
580
|
-
|
|
581
|
-
This library will handle custom requests to your active Garmin Connect session. There are a lot of different url's that is used, which means that this library probably wont cover them all. By using the network analyze tool you can find url's that are used by Garmin Connect to fetch data.
|
|
582
|
-
|
|
583
|
-
Let's assume I found a `GET` requests to the following url:
|
|
584
|
-
|
|
585
|
-
```
|
|
586
|
-
https://connect.garmin.com/modern/proxy/wellness-service/wellness/dailyHeartRate/22f5f84c-de9d-4ad6-97f2-201097b3b983?date=2020-03-24
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
The request can be sent using `GCClient` by running
|
|
590
|
-
|
|
591
|
-
```js
|
|
592
|
-
// You can get your displayName by using the getUserInfo method;
|
|
593
|
-
const displayName = '22f5f84c-de9d-4ad6-97f2-201097b3b983';
|
|
594
|
-
const url =
|
|
595
|
-
'https://connect.garmin.com/modern/proxy/wellness-service/wellness/dailyHeartRate/';
|
|
596
|
-
const dateString = '2020-03-24';
|
|
597
|
-
GCClient.get(url + displayName, { date: dateString });
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
and will net you the same result as using the provided way
|
|
601
|
-
|
|
602
|
-
```js
|
|
603
|
-
GCClient.getHeartRate();
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
Notice how the client will keep track of the url's, your user information as well as keeping the session alive.
|
|
607
|
-
|
|
608
|
-
## Limitations
|
|
609
|
-
|
|
610
|
-
Many responses from Garmin Connect are missing type definitions and defaults to `unknown`. Feel free to add types by opening a pull request.
|
|
611
|
-
|
|
612
|
-
For now, this library only supports the following:
|
|
613
|
-
|
|
614
|
-
- Get user info
|
|
615
|
-
- Get social user info
|
|
616
|
-
- Get heart rate
|
|
617
|
-
- Set body weight
|
|
618
|
-
- Get list of workouts
|
|
619
|
-
- Add new workouts
|
|
620
|
-
- Add workouts to you calendar
|
|
621
|
-
- Remove previously added workouts
|
|
622
|
-
- Get list of activities
|
|
623
|
-
- Get details about one specific activity
|
|
624
|
-
- Get the step count
|
|
625
|
-
- Get earned badges
|
|
626
|
-
- Get available badges
|
|
627
|
-
- Get details about one specific badge
|