ulfben

Fetch Google Fit data to Google Spreadsheet

Jul 13th, 2018
86
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // add your Google API Project OAuth client ID and client secret here
  2. var ClientID = '';
  3. var ClientSecret = '';
  4. var NANOSECONDS_TO_MILLISECONDS = 1.0 / 1000000.0;
  5. var LOCAL_UTC_OFFSET = 2 * (60 * 60 * 1000); //Sweden is UTC+2 during summer.
  6. var SHEET_NAME = '2018'; //the name of your spreadsheet tab
  7.  
  8. function onOpen() {
  9.   var ui = SpreadsheetApp.getUi();
  10.   ui.createMenu('Google Fit')
  11.       .addItem('Authorize if needed (does nothing if already authorized)', 'showSidebar')
  12.       .addItem('Get todays weight', 'getWeight')
  13.       .addToUi();
  14. }
  15.  
  16. function getWeight() {  
  17.   var start = new Date();
  18.   start.setHours(0,0,0,0);  
  19.   var end = new Date();
  20.   end.setHours(23,59,59,999);  
  21.  
  22.   var fitService = getFitService();
  23.   var request = {
  24.     "aggregateBy": [{
  25.       "dataTypeName": "com.google.weight.summary",
  26.       "dataSourceId": "derived:com.google.weight:com.google.android.gms:merge_weight"
  27.     }],
  28.     "bucketByTime": { "durationMillis": 86400000 },
  29.     "startTimeMillis": start.getTime(),
  30.     "endTimeMillis": end.getTime()
  31.   };
  32.  
  33.   var response = UrlFetchApp.fetch('https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate', {
  34.     headers: {
  35.       Authorization: 'Bearer ' + fitService.getAccessToken()
  36.     },
  37.     'method' : 'post',
  38.     'contentType' : 'application/json',
  39.     'payload' : JSON.stringify(request, null, 2)
  40.   });
  41.  
  42.   var json = JSON.parse(response.getContentText());
  43.   var weight = parseFloat(json.bucket[0].dataset[0].point[0].value[0].fpVal);
  44.   var measuredAt = parseInt(json.bucket[0].dataset[0].point[0].endTimeNanos) * NANOSECONDS_TO_MILLISECONDS;
  45.   measuredAt += LOCAL_UTC_OFFSET;
  46.  
  47.   var ss = SpreadsheetApp.getActiveSpreadsheet();
  48.   var sheet = ss.getSheetByName(SHEET_NAME);
  49.   var dateString = new Date(measuredAt).toISOString().split("T")[0];
  50.   sheet.appendRow([dateString, weight]);
  51. }
  52.  
  53. // functions below adapted from Google OAuth example at https://github.com/googlesamples/apps-script-oauth2
  54. function getFitService() {  
  55.   return OAuth2.createService('fit')
  56.       // Set the endpoint URLs, which are the same for all Google services.
  57.       .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
  58.       .setTokenUrl('https://accounts.google.com/o/oauth2/token')
  59.      
  60.       // Set the client ID and secret, from your Google Developers Console.
  61.       .setClientId(ClientID)
  62.       .setClientSecret(ClientSecret)
  63.  
  64.       // Set the name of the callback function in the script referenced
  65.       // above that should be invoked to complete the OAuth flow.
  66.       .setCallbackFunction('authCallback')
  67.  
  68.       // Set the property store where authorized tokens should be persisted.
  69.       .setPropertyStore(PropertiesService.getUserProperties())
  70.  
  71.       // Set the scopes to request (space-separated for Google services).
  72.       // see https://developers.google.com/fit/rest/v1/authorization for a list of Google Fit scopes
  73.       .setScope('https://www.googleapis.com/auth/fitness.activity.read')
  74.  
  75.       // Below are Google-specific OAuth2 parameters.
  76.  
  77.       // Sets the login hint, which will prevent the account chooser screen
  78.       // from being shown to users logged in with multiple accounts.
  79.       .setParam('login_hint', Session.getActiveUser().getEmail())
  80.  
  81.       // Requests offline access.
  82.       .setParam('access_type', 'offline')
  83.  
  84.       // Forces the approval prompt every time. This is useful for testing,
  85.       // but not desirable in a production application.
  86.       //.setParam('approval_prompt', 'force');
  87. }
  88.  
  89. function showSidebar() {
  90.   var fitService = getFitService();
  91.   if (!fitService.hasAccess()) {
  92.     var authorizationUrl = fitService.getAuthorizationUrl();
  93.     var template = HtmlService.createTemplate(
  94.         '<a href="<?= authorizationUrl ?>" target="_blank">Authorize</a>. ' +
  95.         'Close this after you have finished.');
  96.     template.authorizationUrl = authorizationUrl;
  97.     var page = template.evaluate();
  98.     SpreadsheetApp.getUi().showSidebar(page);
  99.   } else {
  100.      // ...
  101.   }
  102. }
  103.  
  104. function authCallback(request) {
  105.   var fitService = getFitService();
  106.   var isAuthorized = fitService.handleCallback(request);
  107.   if (isAuthorized) {
  108.     return HtmlService.createHtmlOutput('Success! You can close this tab.');
  109.   } else {
  110.     return HtmlService.createHtmlOutput('Denied. You can close this tab');
  111.   }
  112. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×