Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@abfo
Created October 2, 2018 01:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abfo/7b7007c926f3709fc9608d297a40ce5e to your computer and use it in GitHub Desktop.
Save abfo/7b7007c926f3709fc9608d297a40ce5e to your computer and use it in GitHub Desktop.
// add your Google API Project OAuth client ID and client secret here
var ClientID = '';
var ClientSecret = '';
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Google Fit')
.addItem('Authorize if needed (does nothing if already authorized)', 'showSidebar')
.addItem('Get Weight for Yesterday', 'getWeight')
.addToUi();
}
// see step count example at https://developers.google.com/fit/scenarios/read-daily-step-total
function getWeight() {
var start = new Date();
start.setHours(0,0,0,0);
start.setDate(start.getDate()-1);
var end = new Date();
end.setHours(23,59,59,999);
end.setDate(end.getDate()-1);
var fitService = getFitService();
var request = {
"aggregateBy": [{
"dataTypeName": "com.google.weight.summary",
"dataSourceId": "derived:com.google.weight:com.google.android.gms:merge_weight"
}],
"bucketByTime": { "durationMillis": 86400000 },
"startTimeMillis": start.getTime(),
"endTimeMillis": end.getTime()
};
var response = UrlFetchApp.fetch('https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate', {
headers: {
Authorization: 'Bearer ' + fitService.getAccessToken()
},
'method' : 'post',
'contentType' : 'application/json',
'payload' : JSON.stringify(request, null, 2)
});
var json = JSON.parse(response.getContentText());
if (json.bucket[0].dataset[0].point.length > 0) {
var weight = json.bucket[0].dataset[0].point[0].value[0].fpVal;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Weight');
sheet.appendRow([start, weight]);
}
}
// functions below adapted from Google OAuth example at https://github.com/googlesamples/apps-script-oauth2
function getFitService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth2.createService('fit')
// Set the endpoint URLs, which are the same for all Google services.
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the client ID and secret, from the Google Developers Console.
.setClientId(ClientID)
.setClientSecret(ClientSecret)
// Set the name of the callback function in the script referenced
// above that should be invoked to complete the OAuth flow.
.setCallbackFunction('authCallback')
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getUserProperties())
// Set the scopes to request (space-separated for Google services).
// see https://developers.google.com/fit/rest/v1/authorization for a list of Google Fit scopes
.setScope('https://www.googleapis.com/auth/fitness.activity.read https://www.googleapis.com/auth/fitness.body.read')
// Below are Google-specific OAuth2 parameters.
// Sets the login hint, which will prevent the account chooser screen
// from being shown to users logged in with multiple accounts.
.setParam('login_hint', Session.getActiveUser().getEmail())
// Requests offline access.
.setParam('access_type', 'offline')
// Forces the approval prompt every time. This is useful for testing,
// but not desirable in a production application.
//.setParam('approval_prompt', 'force');
}
function showSidebar() {
var fitService = getFitService();
if (!fitService.hasAccess()) {
var authorizationUrl = fitService.getAuthorizationUrl();
var template = HtmlService.createTemplate(
'<a href="<?= authorizationUrl ?>" target="_blank">Authorize</a>. ' +
'Close this after you have finished.');
template.authorizationUrl = authorizationUrl;
var page = template.evaluate();
SpreadsheetApp.getUi().showSidebar(page);
} else {
// ...
}
}
function authCallback(request) {
var fitService = getFitService();
var isAuthorized = fitService.handleCallback(request);
if (isAuthorized) {
return HtmlService.createHtmlOutput('Success! You can close this tab.');
} else {
return HtmlService.createHtmlOutput('Denied. You can close this tab');
}
}
function clearProps() {
PropertiesService.getUserProperties().deleteAllProperties();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment