google-apps-scripturlfetchsmart-devicenest-device-access

Why I can get my Nest thermostat ID but not other people using the same script?


I have that listDevice function in a script to get the thermostat ID (same as here):

function listDevices() {
 
  // specify the endpoint
  const endpoint = '/enterprises/' + PROJECT_ID + '/devices';
 
  // blank array to hold device data
  let deviceArray = [];
 
  // make request to smart api
  const data = makeRequest(endpoint);
  const deviceData = data.devices;
  console.log(deviceData);
 
  deviceData.forEach(device => {
    const name = device.name;
    const type = device.type;
    deviceArray.push([name,type]);
  });
 
  // get the Sheet
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
 
  // output the data
  sheet.getRange(2,1,deviceArray.length,2).setValues(deviceArray);
 
}

It works fine with my Nest, but when trying to make it work for another person with multiple Nest thermostats, it gives this error:

TypeError: Cannot read properties of undefined (reading 'forEach')

Would you know why this script works for me, but when shared with someone it gives an error?

Here's the makeRequest(endpoint) function that is called by the function above:

function makeRequest(endpoint) {
 
  // get the smart service
  const smartService = getSmartService();
   
  // get the access token
  const access_token = smartService.getAccessToken();
  //console.log(access_token);
 
  // setup the SMD API url
  const url = 'https://smartdevicemanagement.googleapis.com/v1';
  //const endpoint = '/enterprises/' + PROJECT_ID + '/devices';
 
  // setup the headers for the call
  const headers = {
    'Authorization': 'Bearer ' + access_token,
    'Content-Type': 'application/json'
  }
   
  // set up params
  const params = {
    'headers': headers,
    'method': 'get',
    'muteHttpExceptions': true
  }
   
  // try calling API
  try {
    const response = UrlFetchApp.fetch(url + endpoint, params);
    const responseBody = JSON.parse(response.getContentText());
     
    return responseBody;
  }
  catch(e) {
    console.log('Error: ' + e);
  }
}

Solution

  • After replacing the makeRequest(endpoint) function with that one, the script works and provides me the devices ID without needing to run the listDevice function anymore:

    function makeRequesttest() {
     
      // get the smart service
      const smartService = getSmartService();
       
      // get the access token
      const access_token = smartService.getAccessToken();
      //console.log(access_token);
     
      // setup the SMD API url
      const url = 'https://smartdevicemanagement.googleapis.com/v1';
      const endpoint = '/enterprises/' + PROJECT_ID + '/devices';
     
      // setup the headers for the call
      const headers = {
        'Authorization': 'Bearer ' + access_token,
        'Content-Type': 'application/json'
      }
       
      // set up params
      const params = {
        'headers': headers,
        'method': 'get',
        'muteHttpExceptions': true
      }
       
      // try calling API
      try {
        const response = UrlFetchApp.fetch(url + endpoint, params);
        const responseBody = JSON.parse(response.getContentText());
        Logger.log('response: ' + response);
        return responseBody;
      }
      catch(e) {
        console.log('Error: ' + e);
        //throw e;
      }
    }