SHARE
TWEET

Fetch Google Fit data to Google Spreadsheet

ulfben Jul 13th, 2018 (edited) 19 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top