UNPKG

@careevolution/mydatahelps-js

Version:

MyDataHelps client to be used by external applications for integrations inside the MyDataHelps platform

1,237 lines 73.1 kB
// @ts-ignore : let rollup handle CSS injection class MyDataHelps { // Surveys startSurvey(surveyName, options) { if (this.isStandaloneMode()) { const params = new URLSearchParams(); params.set('surveyName', surveyName); if (options?.editResultID) { params.set('editResultID', options.editResultID); } if (options?.event) { params.set('event', options.event); } this.startDelegatedSurvey(`${this.baseUrl}/survey?${params.toString()}`); } else if (window.webkit.messageHandlers.StartParticipantSurvey) { let messageID = this.nextMessageID(); window.webkit.messageHandlers.StartParticipantSurvey.postMessage({ messageID: messageID, surveyName: surveyName, options: options }); } } completeStep(answer) { if (answer === undefined || answer === null) answer = ''; if (typeof answer !== 'string') { answer = JSON.stringify(answer); } if (window.webkit.messageHandlers.ResearchKit) { window.webkit.messageHandlers.ResearchKit.postMessage(answer); } else if (window.webkit.messageHandlers.CompleteStep) { let messageID = this.nextMessageID(); window.webkit.messageHandlers.CompleteStep.postMessage({ messageID: messageID, answer: answer }); } } querySurveyAnswers(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("surveyName")) { queryParameters.surveyName = MyDataHelps.reduceArrayAndEscape(queryParameters.surveyName); } if (queryParameters.hasOwnProperty("stepIdentifier")) { queryParameters.stepIdentifier = MyDataHelps.reduceArrayAndEscape(queryParameters.stepIdentifier); } if (queryParameters.hasOwnProperty("resultIdentifier")) { queryParameters.resultIdentifier = MyDataHelps.reduceArrayAndEscape(queryParameters.resultIdentifier); } if (queryParameters.hasOwnProperty("answer")) { queryParameters.answer = MyDataHelps.reduceArrayAndEscape(queryParameters.answer); } if (queryParameters.hasOwnProperty("before")) { queryParameters.before = MyDataHelps.convertDateToIsoString(queryParameters.before); } if (queryParameters.hasOwnProperty("after")) { queryParameters.after = MyDataHelps.convertDateToIsoString(queryParameters.after); } if (queryParameters.hasOwnProperty("event")) { queryParameters.event = MyDataHelps.reduceArrayAndEscape(queryParameters.event); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'surveyanswers?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } querySurveyResults(queryParameters) { queryParameters = { ...queryParameters }; if (queryParameters.hasOwnProperty("surveyName")) { queryParameters.surveyName = MyDataHelps.reduceArrayAndEscape(queryParameters.surveyName); } if (queryParameters.hasOwnProperty("event")) { queryParameters.event = MyDataHelps.reduceArrayAndEscape(queryParameters.event); } if (queryParameters.hasOwnProperty("before")) { queryParameters.before = MyDataHelps.convertDateToIsoString(queryParameters.before); } if (queryParameters.hasOwnProperty("after")) { queryParameters.after = MyDataHelps.convertDateToIsoString(queryParameters.after); } if (queryParameters.hasOwnProperty("insertedBefore")) { queryParameters.insertedBefore = MyDataHelps.convertDateToIsoString(queryParameters.insertedBefore); } if (queryParameters.hasOwnProperty("insertedAfter")) { queryParameters.insertedAfter = MyDataHelps.convertDateToIsoString(queryParameters.insertedAfter); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'surveyresults?' + queryString; return this.connect() .then(() => this.makeRequest(endpoint, 'GET', null)) .then(MyDataHelps.validateResponse) .then(response => response.json()); } deleteSurveyResult(resultID) { const endpoint = 'surveyresults/' + encodeURIComponent(resultID); const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'DELETE', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function () { return; }); } querySurveyTasks(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("status")) { queryParameters.status = MyDataHelps.reduceArrayAndEscape(queryParameters.status); } if (queryParameters.hasOwnProperty("surveyName")) { queryParameters.surveyName = MyDataHelps.reduceArrayAndEscape(queryParameters.surveyName); } if (queryParameters.hasOwnProperty("event")) { queryParameters.event = MyDataHelps.reduceArrayAndEscape(queryParameters.event); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'surveytasks?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } queryInboxItems(queryParameters) { const assignDefined = (target, source) => { for (const key of Object.keys(source)) { const value = source[key]; if (value !== undefined) { target[key] = value; } } return target; }; queryParameters = assignDefined({}, queryParameters); if (queryParameters.hasOwnProperty("type")) { queryParameters.type = MyDataHelps.reduceArrayAndEscape(queryParameters.type); } if (queryParameters.hasOwnProperty("status")) { queryParameters.status = MyDataHelps.reduceArrayAndEscape(queryParameters.status); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'inbox?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } getInboxItem(id) { const endpoint = `inbox/${id}`; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } updateInboxItem(id, update) { const endpoint = `inbox/${id}/${update}`; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'PUT', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } startEmbeddedSurvey(linkIdentifier, surveyName, language) { if (!language) { language = this.getCurrentLanguage(); } let surveyUrl = this.baseUrl + "mydatahelps/" + linkIdentifier + '/surveylink/' + surveyName + "?lang=" + language; return this.startEmbeddedSurveyInternal(surveyUrl); } // Navigation openExternalUrl(url) { if (window.webkit.messageHandlers.OpenExternalLink) { window.webkit.messageHandlers.OpenExternalLink.postMessage(url); } } openEmbeddedUrl(url) { if (window.webkit.messageHandlers.OpenEmbeddedLink) { window.webkit.messageHandlers.OpenEmbeddedLink.postMessage(url); } } showTab(tabKey) { if (window.webkit.messageHandlers.ShowTab) { window.webkit.messageHandlers.ShowTab.postMessage(tabKey); } } openApplication(url, options) { if (window.webkit.messageHandlers.OpenExternalApplication) { let messageID = this.nextMessageID(); window.webkit.messageHandlers.OpenExternalApplication.postMessage({ messageID: messageID, url: url, modal: !!(options && options.modal) }); } } openSecondaryView(projectId, viewKey, options) { this.lookupSecondaryView(projectId, viewKey).then(secondaryView => { return this.openApplication(secondaryView.url, options); }); } ; lookupSecondaryView(projectId, viewKey) { let baseUrl = this.baseUrl; if (!baseUrl.endsWith("/")) { baseUrl += "/"; } const viewLookupUrl = `${baseUrl}api/v1/public/projects/${projectId}/views/${viewKey}`; return fetch(viewLookupUrl, { method: 'GET', headers: { 'Accept': 'application/json' } }) .then(response => { if (!response.ok) { return response.text().then(text => { throw new Error(`Failed to fetch secondary view: ${response.status} ${response.statusText}${text ? ' - ' + text : ''}`); }); } return response.json(); }); } dismiss() { if (window.webkit.messageHandlers.Dismiss) { window.webkit.messageHandlers.Dismiss.postMessage({}); } } back() { if (window.webkit.messageHandlers.PopNavigation) { window.webkit.messageHandlers.PopNavigation.postMessage({}); } } showDashboard(dashboardKey, options) { if (window.webkit.messageHandlers.ShowParticipantDashboard) { window.webkit.messageHandlers.ShowParticipantDashboard.postMessage({ dashboardKey: dashboardKey, modal: !!(options && options.modal), title: options && options.title ? options.title : undefined }); } } showWebVisualization(visualizationKey, parameters, options) { if (window.webkit.messageHandlers.ShowParticipantWebVisualization) { window.webkit.messageHandlers.ShowParticipantWebVisualization.postMessage({ visualizationKey: visualizationKey, parameters: parameters, modal: !!(options && options.modal), title: options && options.title ? options.title : undefined }); } } showWebVisualizationPdf(visualizationKey, parameters, options) { if (window.webkit.messageHandlers.ShowParticipantWebVisualizationPDF) { window.webkit.messageHandlers.ShowParticipantWebVisualizationPDF.postMessage({ visualizationKey: visualizationKey, parameters: parameters, landscape: !!(options && options.landscape), htmlViewerZoom: options && options.htmlViewerZoom }); } } showProject(projectCode) { if (window.webkit.messageHandlers.ShowProject) { window.webkit.messageHandlers.ShowProject.postMessage({ code: projectCode }); } } joinProject(projectCode) { if (window.webkit.messageHandlers.JoinProject) { window.webkit.messageHandlers.JoinProject.postMessage({ code: projectCode }); } } //Events on(eventName, callback) { if (!this.supportedEvents.includes(eventName)) { throw new Error(eventName + " is not a supported event type."); } if (!this.registeredEventHandlers[eventName]) { this.registeredEventHandlers[eventName] = []; } this.registeredEventHandlers[eventName].push(callback); } off(eventName, callback) { if (!this.supportedEvents.includes(eventName)) { throw new Error(eventName + " is not a supported event type."); } if (!this.registeredEventHandlers[eventName]) return; let eventHandlerIndex = this.registeredEventHandlers[eventName].indexOf(callback); if (eventHandlerIndex !== -1) { this.registeredEventHandlers[eventName].splice(eventHandlerIndex, 1); } } triggerEvent(event) { let eventName = event.type; if (this.supportedEvents.includes(eventName) && this.registeredEventHandlers[eventName]) { this.registeredEventHandlers[eventName].forEach(function (handler) { handler(event); }); } } setActionResult(data) { if (Object.prototype.hasOwnProperty.call(this.messageHandlers, data.messageID) && typeof this.messageHandlers[data.messageID] === 'function') { this.messageHandlers[data.messageID](data); } else { console.error(`Invalid messageID: ${data.messageID}`); } } // Participant Info getParticipantInfo() { const mdh = this; const endpoint = 'participant'; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } persistParticipantInfo(demographics, customFields) { const endpoint = 'participant'; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'PUT', { demographics, customFields }); }) .then(async function (response) { if (!response.ok) { var errorJson = await response.json(); throw errorJson.message; } return response.json(); }) .catch(function (error) { console.log("Unable to persist participant: " + error); }); } getProjectInfo() { const mdh = this; const endpoint = 'project'; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } // Device Data getDeviceDataPoint(id) { const endpoint = 'devicedata/' + id; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } deleteDeviceDataPoint(id) { const endpoint = 'devicedata/' + id; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'DELETE', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function () { return; }); } queryDeviceData(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("type")) { queryParameters.type = MyDataHelps.reduceArrayAndEscape(queryParameters.type); } if (queryParameters.hasOwnProperty("observedBefore")) { queryParameters.observedBefore = MyDataHelps.convertDateToIsoString(queryParameters.observedBefore); } if (queryParameters.hasOwnProperty("observedAfter")) { queryParameters.observedAfter = MyDataHelps.convertDateToIsoString(queryParameters.observedAfter); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'devicedata?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } persistDeviceData(deviceDataPoints) { const endpoint = 'devicedata'; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'POST', deviceDataPoints); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function () { return; }); } getDeviceDataAllDataTypes(enabled, namespace) { const queryParameters = {}; if (enabled !== undefined) { queryParameters['enabled'] = enabled.toString(); } if (namespace) { queryParameters['namespace'] = namespace; } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = `devicedata/allDataTypes?${queryString}`; return this.connect() .then(() => this.makeRequest(endpoint, 'GET', null)) .then(MyDataHelps.validateResponse) .then(response => response.json()); } // Device Data V2 queryDeviceDataV2(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("observedBefore")) { queryParameters.observedBefore = MyDataHelps.convertDateToIsoString(queryParameters.observedBefore); } if (queryParameters.hasOwnProperty("observedAfter")) { queryParameters.observedAfter = MyDataHelps.convertDateToIsoString(queryParameters.observedAfter); } if (queryParameters.hasOwnProperty("insertedBefore")) { queryParameters.insertedBefore = MyDataHelps.convertDateToIsoString(queryParameters.insertedBefore); } if (queryParameters.hasOwnProperty("insertedAfter")) { queryParameters.insertedAfter = MyDataHelps.convertDateToIsoString(queryParameters.insertedAfter); } if (queryParameters.hasOwnProperty("modifiedBefore")) { queryParameters.modifiedBefore = MyDataHelps.convertDateToIsoString(queryParameters.modifiedBefore); } if (queryParameters.hasOwnProperty("modifiedAfter")) { queryParameters.modifiedAfter = MyDataHelps.convertDateToIsoString(queryParameters.modifiedAfter); } MyDataHelps.flattenPropertyShallow(queryParameters, "dataSource"); MyDataHelps.flattenPropertyShallow(queryParameters, "properties"); const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'devicedata?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null, 'v2'); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } queryDeviceDataV2Aggregate(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("aggregateFunctions")) { queryParameters.aggregateFunctions = MyDataHelps.reduceArrayAndEscape(queryParameters.aggregateFunctions); } if (queryParameters.hasOwnProperty("observedBefore")) { queryParameters.observedBefore = MyDataHelps.convertDateToIsoString(queryParameters.observedBefore); } if (queryParameters.hasOwnProperty("observedAfter")) { queryParameters.observedAfter = MyDataHelps.convertDateToIsoString(queryParameters.observedAfter); } if (queryParameters.hasOwnProperty("insertedBefore")) { queryParameters.insertedBefore = MyDataHelps.convertDateToIsoString(queryParameters.insertedBefore); } if (queryParameters.hasOwnProperty("insertedAfter")) { queryParameters.insertedAfter = MyDataHelps.convertDateToIsoString(queryParameters.insertedAfter); } if (queryParameters.hasOwnProperty("modifiedBefore")) { queryParameters.modifiedBefore = MyDataHelps.convertDateToIsoString(queryParameters.modifiedBefore); } if (queryParameters.hasOwnProperty("modifiedAfter")) { queryParameters.modifiedAfter = MyDataHelps.convertDateToIsoString(queryParameters.modifiedAfter); } MyDataHelps.flattenPropertyShallow(queryParameters, "dataSource"); MyDataHelps.flattenPropertyShallow(queryParameters, "properties"); const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'devicedata/aggregate?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null, 'v2'); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } queryDeviceDataV2DailySleep(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("observedBefore")) { queryParameters.observedBefore = MyDataHelps.convertDateToIsoString(queryParameters.observedBefore); } if (queryParameters.hasOwnProperty("observedAfter")) { queryParameters.observedAfter = MyDataHelps.convertDateToIsoString(queryParameters.observedAfter); } if (queryParameters.hasOwnProperty("insertedBefore")) { queryParameters.insertedBefore = MyDataHelps.convertDateToIsoString(queryParameters.insertedBefore); } if (queryParameters.hasOwnProperty("insertedAfter")) { queryParameters.insertedAfter = MyDataHelps.convertDateToIsoString(queryParameters.insertedAfter); } if (queryParameters.hasOwnProperty("modifiedBefore")) { queryParameters.modifiedBefore = MyDataHelps.convertDateToIsoString(queryParameters.modifiedBefore); } if (queryParameters.hasOwnProperty("modifiedAfter")) { queryParameters.modifiedAfter = MyDataHelps.convertDateToIsoString(queryParameters.modifiedAfter); } MyDataHelps.flattenPropertyShallow(queryParameters, "dataSource"); MyDataHelps.flattenPropertyShallow(queryParameters, "properties"); const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'devicedata/aggregate/dailysleep?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null, 'v2'); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } getDeviceDataV2AllDataTypes(enabled, namespace) { const queryParameters = {}; if (enabled !== undefined) { queryParameters['enabled'] = enabled.toString(); } if (namespace) { queryParameters['namespace'] = namespace; } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = `devicedata/allDataTypes?${queryString}`; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null, 'v2'); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } // External Accounts getExternalAccountProviders(search, category, pageSize, pageNumber) { let searchParameters = {}; if (!!search) searchParameters.search = search; if (!!category) searchParameters.category = category; if (!!pageSize) searchParameters.pageSize = pageSize; if (!!pageNumber) searchParameters.pageNumber = pageNumber; const queryString = new URLSearchParams(searchParameters).toString(); const endpoint = 'externalaccountproviders?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } connectExternalAccount(externalAccountProviderID, options) { return new Promise((resolve, reject) => { const messageID = mdh.nextMessageID(); mdh.messageHandlers[messageID] = function (connectProviderAccountResponse) { if (connectProviderAccountResponse && connectProviderAccountResponse.success) { resolve(); } else { reject(connectProviderAccountResponse.errorMessage); } }; if (this.standaloneMode) { let standaloneModeFinalRedirectPath = options?.standaloneModeFinalRedirectPath || window.location.href; const mdh = this; // DEV: Safari blocks popups in AJAX responses. Work-around is to open a blank window before the request and set the URL later let providerAuthWindow; if (options?.openNewWindow) { standaloneModeFinalRedirectPath = `${standaloneModeFinalRedirectPath.split('?')[0]}?connectExternalAccount=true&messageID=${messageID}&success=%SUCCESSVALUE%`; let windowFeatures = null; if (options?.width && options?.height) { const w = options?.width; const h = options?.height; const y = window.outerHeight / 2 + window.screenY - (h / 2); const x = window.outerWidth / 2 + window.screenX - (w / 2); windowFeatures = "width=" + w + ",height=" + h + ",top=" + y + ",left=" + x; } providerAuthWindow = window.open(`${this.baseUrl}home/loading`, 'providerauth', windowFeatures); } const searchParameters = { finalRedirectPath: standaloneModeFinalRedirectPath }; const queryString = new URLSearchParams(searchParameters).toString(); const endpoint = "externalaccountproviders/" + externalAccountProviderID + "/connect?" + queryString; this .connect() .then(function () { return mdh.makeRequest(endpoint, 'POST', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.text(); }) .then(function (redirectUrl) { if (providerAuthWindow) { providerAuthWindow.location = redirectUrl.replace(/['"]+/g, ''); } else { window.top.location = redirectUrl.replace(/['"]+/g, ''); } }) .catch(function (error) { reject(error); }); } else if (window.webkit.messageHandlers.ConnectExternalAccount) { window.webkit.messageHandlers.ConnectExternalAccount.postMessage({ externalAccountProviderID: externalAccountProviderID, messageID: messageID, ...options }); } }); } getExternalAccounts() { const endpoint = 'externalaccounts'; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } refreshExternalAccount(accountID) { const endpoint = 'externalaccounts/refresh/' + accountID; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'POST', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function () { return; }); } deleteExternalAccount(accountID) { const endpoint = 'externalaccounts/delete/' + encodeURIComponent(accountID); const mdh = this; if (this.isStandaloneMode()) { return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'DELETE', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }); } return new Promise(function (resolve, reject) { if (window.webkit.messageHandlers.DeleteProviderAccount) { const messageID = mdh.nextMessageID(); mdh.messageHandlers[messageID] = function (deleteProviderAccountResponse) { if (!deleteProviderAccountResponse.success) { reject(deleteProviderAccountResponse); } else { resolve(deleteProviderAccountResponse); } }; window.webkit.messageHandlers.DeleteProviderAccount.postMessage({ messageID: messageID, accountID: accountID }); } else { reject(); } }); } getFeaturedProviders(context) { const queryParameters = {}; if (context) { queryParameters['featuredProvidersContext'] = context; } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = `featuredexternalaccountproviders?${queryString}`; return this.connect() .then(() => this.makeRequest(endpoint, 'GET', null)) .then(MyDataHelps.validateResponse) .then(response => response.json()); } // Notifications queryNotifications(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("sentBefore")) { queryParameters.sentBefore = MyDataHelps.convertDateToIsoString(queryParameters.sentBefore); } if (queryParameters.hasOwnProperty("sentAfter")) { queryParameters.sentAfter = MyDataHelps.convertDateToIsoString(queryParameters.sentAfter); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'notifications?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } // Fitbit queryFitbitDailySummaries(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("startDate")) { queryParameters.startDate = MyDataHelps.convertDateToIsoString(queryParameters.startDate); } if (queryParameters.hasOwnProperty("endDate")) { queryParameters.endDate = MyDataHelps.convertDateToIsoString(queryParameters.endDate); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'fitbit/dailySummaries?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } queryFitbitSleepLogs(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("startDate")) { queryParameters.startDate = MyDataHelps.convertDateToIsoString(queryParameters.startDate); } if (queryParameters.hasOwnProperty("endDate")) { queryParameters.endDate = MyDataHelps.convertDateToIsoString(queryParameters.endDate); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'fitbit/sleepLogs?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } // AppleHealth queryAppleHealthActivitySummaries(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("startDate")) { queryParameters.startDate = MyDataHelps.convertDateToIsoString(queryParameters.startDate); } if (queryParameters.hasOwnProperty("endDate")) { queryParameters.endDate = MyDataHelps.convertDateToIsoString(queryParameters.endDate); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'appleHealth/activitySummaries?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } queryAppleHealthWorkouts(queryParameters) { queryParameters = Object.assign({}, queryParameters); if (queryParameters.hasOwnProperty("startDate")) { queryParameters.startDate = MyDataHelps.convertDateToIsoString(queryParameters.startDate); } if (queryParameters.hasOwnProperty("endDate")) { queryParameters.endDate = MyDataHelps.convertDateToIsoString(queryParameters.endDate); } const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'appleHealth/workouts?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } // Files uploadFile(file, category, fileName) { if (file.size > 200 * 1024 * 1024) { throw new Error("File size exceeds the maximum allowed size of 200MB."); } const mdh = this; const endpoint = 'files?category=' + category + '&fileName=' + encodeURIComponent(fileName ?? file.name); return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'POST', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }) .then(function (json) { return fetch(json.preSignedUrl, { method: 'PUT', body: file, headers: { 'Content-Type': file.type, 'x-amz-server-side-encryption': 'AES256' } }); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function () { return; }); } queryFiles(queryParameters) { const queryString = new URLSearchParams(queryParameters).toString(); const endpoint = 'files?' + queryString; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } getFileDownloadUrl(key) { if (!key) throw new Error("Please specify the key of the file to download."); const endpoint = 'files/download?key=' + key; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'GET', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function (response) { return response.json(); }); } deleteFile(key) { if (!key) throw new Error("Please specify the key of the file to delete."); const endpoint = 'files?key=' + key; const mdh = this; return this .connect() .then(function () { return mdh.makeRequest(endpoint, 'DELETE', null); }) .then(function (response) { return MyDataHelps.validateResponse(response); }) .then(function () { return; }); } // Authorization connect() { const mdh = this; let refreshDelegatedAccessToken = function () { mdh.token = null; mdh.refreshTokenPromise = new Promise(function (resolve, reject) { let messageID = mdh.nextMessageID(); mdh.messageHandlers[messageID] = function (tokenResponse) { if (tokenResponse.success) { mdh.tokenExpires = Date.now() + (tokenResponse.data.expires_in * 1000); mdh.token = tokenResponse.data; mdh.baseUrl = tokenResponse.baseUrl; setTimeout(refreshDelegatedAccessToken, ((tokenResponse.data.expires_in - mdh.accessTokenRenewalBufferSeconds) * 1000)); resolve(null); } else { mdh.token = null; reject(tokenResponse.message); } mdh.messageHandlers[messageID] = null; mdh.refreshTokenPromise = null; }; window.webkit.messageHandlers.GetDelegatedAccessToken.postMessage({ messageID: messageID }); }); }; if (this.token && Date.now() < this.tokenExpires) { return Promise.resolve(); } if (this.isStandaloneMode() && !this.isEmbeddedMode()) { let error = this.token ? "access token is expired or invalid" : "access token must be explicitly provided using the setParticipantAccess method"; console.log(error); return Promise.reject(error); } if (!this.refreshTokenPromise) { refreshDelegatedAccessToken(); } // Re-use promise if refresh already in progress return this.refreshTokenPromise; } setParticipantAccessToken(token, baseUrl) { this.enableStandaloneMode(); this.token = token; if (baseUrl) { this.baseUrl = baseUrl; } this.tokenExpires = Date.now() + (this.token.expires_in * 1000); const mdh = this; setTimeout(function () { mdh.triggerEvent({ type: "tokenWillExpire" }); }, ((this.token.expires_in - this.accessTokenRenewalBufferSeconds) * 1000)); } // Miscellaneous isStandaloneMode() { return this.standaloneMode; } isEmbeddedMode() { return this.embeddedMode; } enableStandaloneMode(embeddedMode = false, baseUrl) { this.standaloneMode = true; this.embeddedMode = embeddedMode; if (baseUrl) { this.baseUrl = baseUrl; } if (window.webkit) { window.webkit.messageHandlers = embeddedMode ? { GetDelegatedAccessToken: window.webkit.messageHandlers.GetDelegatedAccessToken, OpenExternalLink: window.webkit.messageHandlers.OpenExternalLink, OpenEmbeddedLink: window.webkit.messageHandlers.OpenEmbeddedLink, OpenExternalApplication: window.webkit.messageHandlers.OpenExternalApplication, PopNavigation: window.webkit.messageHandlers.PopNavigation, Dismiss: window.webkit.messageHandlers.Dismiss, } : {}; } } setStatusBarStyle(style) { if (window.webkit.messageHandlers.SetStatusBarStyle) { window.webkit.messageHandlers.SetStatusBarStyle.postMessage({ style: style }); } } getDeviceInfo() { let mdh = this; return new Promise(function (resolve, reject) { if (mdh.isStandaloneMode()) { resolve(null); } else if (window.webkit.messageHandlers.GetDeviceInfo) { let messageID = mdh.nextMessageID(); mdh.messageHandlers[messageID] = function (deviceInfoResponse) { resolve(deviceInfoResponse.data); }; window.webkit.messageHandlers.GetDeviceInfo.postMessage({ messageID: messageID }); } else { reject(); } }); } setSupportedLanguages(languages) { this.supportedLanguages.length = 0; for (let i = 0; i < languages.length; i++) { this.supportedLanguages.push(languages[i].replace("_", "-")); } } getStepConfiguration() { let mdh = this; return new Promise(function (resolve, reject) { if (mdh.isStandaloneMode()) { resolve(null); } else if (window.webkit.messageHandlers.GetStepConfiguration) { let messageID = mdh.nextMessageID(); mdh.messageHandlers[messageID] = function (stepConfigurationResponse) { resolve(stepConfigurationResponse.data); }; window.webkit.messageHandlers.GetStepConfiguration.postMessage({ messageID: messageID }); } else { reject(); } }); } getSurveyContext() { let mdh = this; return new Promise(function (resolve, reject) { if (mdh.isStandaloneMode()) { resolve(null); } mdh.getDeviceInfo().then(function (deviceInfo) { if (deviceInfo.platform !== "Web") { resolve({ surveyMode: "Survey" }); } else if (window.webkit.messageHandlers.GetSurveyContext) { let messageID = mdh.nextMessageID(); mdh.messageHandlers[messageID] = function (surveyContextResponse) { resolve(surveyContextResponse.data); }; window.webkit.messageHandlers.GetSurveyContext.postMessage({ messageID: messageID }); } else { reject(); } }).catch(function (error) { reject(); }); }); } getCurrentSurveyAnswers() { let mdh = this; return new Promise(function (resolve, reject) { if (mdh.isStandaloneMode()) { resolve(null); } else if (window.webkit.messageHandlers.GetCurrentSurveyAnswers) { let messageID = mdh.nextMessageID(); mdh.messageHandlers[messageID] = function (currentSurveyAnswersResponse) { resolve(currentSurveyAnswersResponse.data); }; window.webkit.messageHandlers.GetCurrentSurveyAnswers.postMessage({ messageID: messageID }); } else { reject(); } }); } setCurrentLanguage(language) { if (language) { let supportedLanguage = this.getSupportedLanguage(language); if (supportedLanguage) { this.language = supportedLanguage; } else { console.warn(`language ${language} not supported`); } } else { this.language = language; } } getCurrentLanguage() { let searchParams = new URLSearchParams(window.location.search); let lang; if (searchParams.has("lang")) { lang = this.getSupportedLanguage(searchParams.get("lang")); if (lang) { return lang; } else { console.warn(`language ${searchParams.get("lang")} not supported`); } } return this.language || navigator.language; } showGoogleFitSettings() { if (window.webkit.messageHandlers.ShowGoogleFitSettings) { window.webkit.messageHandlers.ShowGoogleFitSettings.postMessage({}); } } showHealthConnectSettings() { if (window.webkit.messageHandlers.HealthConnectSettings) { window.webkit.messageHandlers.HealthConnectSettings.postMessage({}); } } showHealthConnectPrompt() { if (window.webkit.messageHandlers.HealthConnectPrompt) { window.webkit.messageHandlers.HealthConnectPrompt.postMessage({}); } } getHealthConnectStatus() { let mdh = this; return new Promise(function (resolve, reject) { if (mdh.isStandaloneMode()) { resolve(null); } else if (window.webkit.messageHandlers.HealthConnectStatus) { let messageID = mdh.nextMessageID(); mdh.messageHandlers[messageID] = function (statusResponse) { resolve(statusResponse.data); }; window.webkit.messageHandlers.HealthConnectStatus.postMessage({ messageID: messageID }); } else { reject(); } }); } showHealthConnectPhrPrompt() { if (window.webkit.messageHandlers.HealthConnectPhrPrompt) { window.webkit.messageHandlers.HealthConnectPhrPrompt.postMessage({}); } } getHealthConnectPhrStatus() { let mdh = this; return new Promise(function (resolve, reject) { if (mdh.isStandaloneMode()) { resolve(null); } else if (window.webkit.messageHandlers.HealthConnectPhrStatus) { let messageID = mdh.nextMessageID(); mdh.messageHandlers[messageID] = function (statusResponse) { resolve(statusResponse.data); }; window.webkit.messageHandlers.HealthConnectPhrStatus.postMessage({ messageID: messag