/
metriport.ts
320 lines (297 loc) · 11.8 KB
/
metriport.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
import axios, { AxiosInstance } from "axios";
import {
API_KEY_HEADER,
BASE_ADDRESS,
BASE_ADDRESS_SANDBOX,
DEFAULT_AXIOS_TIMEOUT_MILLIS,
} from "../../shared";
import { Activity } from "../models/activity";
import { Biometrics } from "../models/biometrics";
import { Body } from "../models/body";
import { ProviderSource } from "../models/common/provider-source";
import { Nutrition } from "../models/nutrition";
import { Sleep } from "../models/sleep";
import { User } from "../models/user";
import { GetConnectTokenResponse } from "./models/get-connect-token-response";
import { GetMetriportUserIDResponse } from "./models/get-metriport-user-id-response";
import { SettingsResponse } from "./models/settings-response";
import { WebhookStatusResponse } from "./models/webhook-status-response";
import { GetConnectedUsersResponse } from "./models/get-connected-users-response";
import { ConnectedUserInfo } from "../models/common/connected-user-info";
import { dateIsValid } from "./util/date-util";
import { isValidTimezone } from "./util/timezone-util";
export type Options = {
sandbox?: boolean;
timeout?: number;
baseAddress?: string;
};
export class MetriportDevicesApi {
private api: AxiosInstance;
/**
* Creates a new instance of the Metriport Devices API client.
*
* @param apiKey - Your Metriport API key.
* @param options - Optional parameters
* @param options.sandbox - Indicates whether to connect to the sandbox, default false.
* @param options.timeout - Connection timeout in milliseconds, default 20 seconds.
*/
constructor(apiKey: string, options: Options = {}) {
const { sandbox, timeout } = options;
const baseURL = options.baseAddress || (sandbox ? BASE_ADDRESS_SANDBOX : BASE_ADDRESS);
this.api = axios.create({
timeout: timeout ?? DEFAULT_AXIOS_TIMEOUT_MILLIS,
baseURL,
headers: { [API_KEY_HEADER]: apiKey },
});
}
/**
* For your given user ID, returns the Metriport user ID used for identifying
* the user and making subsequent calls for the user's data.
*
* @param {string} appUserId - The unique ID for the user in your app.
* @returns The userId of the user.
*/
async getMetriportUserId(appUserId: string): Promise<string> {
const resp = await this.api.post<GetMetriportUserIDResponse>("/user", null, {
params: { appUserId: appUserId },
});
return resp.data.userId;
}
/**
* For your given user ID, returns the user's connected providers
*
* @param {string} userId - The unique ID for the user in your app.
* @returns Object containing array of connected providers.
*/
async getConnectedProviders(userId: string): Promise<{ connectedProviders: string[] }> {
const resp = await this.api.get<{ connectedProviders: string[] }>(
`/user/${userId}/connected-providers`
);
return resp.data;
}
/**
* Returns all your users and their connected providers.
*
* @returns List of connected users, containing their ids and providers.
*/
async getConnectedUsers(): Promise<{ connectedUsers: ConnectedUserInfo[] }> {
const resp = await this.api.get<GetConnectedUsersResponse>("/user");
return resp.data;
}
/**
* For the given user ID, get a token to be used for a Metriport Connect session.
*
* @param {string} userId - The user ID of the user that will be using the Connect widget.
* @returns The Metriport Connect session token.
*/
async getConnectToken(userId: string): Promise<string> {
const resp = await this.api.get<GetConnectTokenResponse>("/user/connect/token", {
params: { userId: userId },
});
return resp.data.token;
}
/**
* For the given user ID, revokes the user's access to the specified provider.
*
* @param {string} userId - The user ID of the user for which to revoke access.
* @param {ProviderSource} provider - The data provider to revoke access to.
* @returns void.
*/
async revokeUserAccessToProvider(userId: string, provider: ProviderSource): Promise<void> {
await this.api.delete(`/user/${userId}/revoke`, {
params: { provider: provider.toString() },
});
}
/**
* For the given user ID, revokes access tokens for all providers and deletes the user.
*
* @param {string} userId - The user ID of the user to be deleted.
* @returns void.
*/
async deleteUser(userId: string): Promise<void> {
await this.api.delete(`/user/${userId}`);
}
/**
* Connects the user to a remote patient monitoring (RPM) device provider.
*
* @param {string} provider - A healthcare data provider (currently only includes `tenovi`).
* @param {string} token - The connect token that was generated by the getConnectToken method.
* @param {string[]} deviceIds - A list of device IDs to connect to the user.
* @param {string} deviceUserId - The user ID (patient ID, for Tenovi) of the user that is connected to the device.
*/
async connectRpmProvider(
provider: ProviderSource.tenovi,
token: string,
deviceIds: string[],
deviceUserId: string
): Promise<void> {
await this.api.post(
`/connect/rpm/${provider}/?token=${token}&deviceIds=${deviceIds.join(
","
)}&deviceUserId=${deviceUserId}`
);
}
/**
* Disconnects a single RPM device from the user.
* @param userId - The Metriport user ID of the user to disconnect the given device from.
* @param provider - The RPM device provider (currently only includes `tenovi`).
* @param deviceId - The HWI ID of the device to be disconnected.
* @param x_tenovi_api_key - Your Tenovi API key.
* @param x_tenovi_client_name - Your Tenovi Client name.
*/
async disconnectDevice(
userId: string,
provider: ProviderSource.tenovi,
deviceId: string,
x_tenovi_api_key: string,
x_tenovi_client_name: string
): Promise<void> {
await this.api.delete(`/user/${userId}/device/?provider=${provider}&deviceId=${deviceId}`, {
headers: {
"x-tenovi-api-key": x_tenovi_api_key,
"x-tenovi-client-name": x_tenovi_client_name,
},
});
}
/**
* Gets the activity info for the specified user ID and date.
*
* @param {string} userId - The userId of the user you want to get data for.
* @param {string} date - The date you want to get the data for (YYYY-MM-DD).
* @param {string} timezoneId - The timezoneId to get the user's data for (for example: America/Los_Angeles).
* @returns An array of activity data from each connected provider.
*/
async getActivityData(userId: string, date: string, timezoneId?: string): Promise<Activity[]> {
const resp = await this.api.get<Activity[]>("/activity", {
params: this.validateAndBuildParams(userId, date, timezoneId),
});
return resp.data;
}
/**
* Gets the body data for the specified user ID and date.
*
* @param {string} userId - The userId of the user you want to get data for.
* @param {string} date - The date you want to get the data for (YYYY-MM-DD).
* @param {string} timezoneId - The timezoneId to get the user's data for (for example: America/Los_Angeles).
* @returns An array of body data from each connected provider.
*/
async getBodyData(userId: string, date: string, timezoneId?: string): Promise<Body[]> {
const resp = await this.api.get<Body[]>("/body", {
params: this.validateAndBuildParams(userId, date, timezoneId),
});
return resp.data;
}
/**
* Gets the biometrics data for the specified user ID and date.
*
* @param {string} userId - The userId of the user you want to get data for.
* @param {string} date - The date you want to get the data for (YYYY-MM-DD).
* @param {string} timezoneId - The timezoneId to get the user's data for (for example: America/Los_Angeles).
* @returns An array of biometrics data from each connected provider.
*/
async getBiometricsData(
userId: string,
date: string,
timezoneId?: string
): Promise<Biometrics[]> {
const resp = await this.api.get<Biometrics[]>("/biometrics", {
params: this.validateAndBuildParams(userId, date, timezoneId),
});
return resp.data;
}
/**
* Gets the nutrition data for the specified user ID and date.
*
* @param {string} userId - The userId of the user you want to get data for.
* @param {string} date - The date you want to get the data for (YYYY-MM-DD).
* @param {string} timezoneId - The timezoneId to get the user's data for (for example: America/Los_Angeles).
* @returns An array of nutrition data from each connected provider.
*/
async getNutritionData(userId: string, date: string, timezoneId?: string): Promise<Nutrition[]> {
const resp = await this.api.get<Nutrition[]>("/nutrition", {
params: this.validateAndBuildParams(userId, date, timezoneId),
});
return resp.data;
}
/**
* Gets the sleep data for the specified user ID and date.
*
* @param {string} userId - The userId of the user you want to get data for.
* @param {string} date - The date you want to get the data for (YYYY-MM-DD).
* @param {string} timezoneId - The timezoneId to get the user's data for (for example: America/Los_Angeles).
* @returns An array of sleep data from each connected provider.
*/
async getSleepData(userId: string, date: string, timezoneId?: string): Promise<Sleep[]> {
const resp = await this.api.get<Sleep[]>("/sleep", {
params: this.validateAndBuildParams(userId, date, timezoneId),
});
return resp.data;
}
/**
* Gets the user info for the specified user ID and date.
*
* @param {string} userId - The userId of the user you want to get data for.
* @param {string} date - The date you want to get the data for (YYYY-MM-DD).
* @param {string} timezoneId - The timezoneId to get the user's data for (for example: America/Los_Angeles).
* @returns An array of user data from each connected provider.
*/
async getUserData(userId: string, date: string, timezoneId?: string): Promise<User[]> {
const resp = await this.api.get<User[]>("/user", {
params: this.validateAndBuildParams(userId, date, timezoneId),
});
return resp.data;
}
/**
* If the userId is empty or the date is not in the correct format, throw an error. Otherwise, return
* an object with the userId and date.
*
* @param {string} userId - The userId of the user you want to get the data for.
* @param {string} date - The date to get the user's data for.
* @param {string} timezoneId - The timezoneId to get the user's data for (for example: America/Los_Angeles).
* @returns an object with the userId and date properties.
*/
private validateAndBuildParams(userId: string, date: string, timezoneId?: string) {
if (userId.trim().length < 1) throw Error(`userId must not be empty!`);
if (!dateIsValid(date)) throw Error(`date must be in format YYYY-MM-DD!`);
if (timezoneId && !isValidTimezone(timezoneId))
throw Error(`timezoneId must be a valid timezoneId!`);
return { userId, date, timezoneId };
}
/**
* Gets the settings for your account.
*
* @returns Your account settings.
*/
async getSettings(): Promise<SettingsResponse> {
const resp = await this.api.get<SettingsResponse>("/settings");
return resp.data;
}
/**
* Update the settings for your account.
*
* @returns Your updated account settings.
*/
async updateSettings(webhookUrl: string): Promise<SettingsResponse> {
const resp = await this.api.post<SettingsResponse>("/settings", {
webhookUrl,
});
return resp.data;
}
/**
* Gets the status of communication with your app's webhook.
*
* @returns The status of communication with your app's webhook.
*/
async getWebhookStatus(): Promise<WebhookStatusResponse> {
const resp = await this.api.get<WebhookStatusResponse>("/settings/webhook");
return resp.data;
}
/**
* Retries failed webhook requests.
*
* @returns void
*/
async retryWebhookRequests(): Promise<void> {
await this.api.post("/settings/webhook/retry");
}
}