1

Overall Goal:

I'm looping through a variety of files, and trying to figure out a way to dynamically list/capture as much information from a GAS File Object as possible.

If I were to take a NONdynamic approach, I'd type out each property I want to capture like this:

  var zText = 'File Id:' + aFile.getId();
  zText += "\n" + "getName: " + aFile.getName();
  zText += "\n" + "getDateCreated: " + aFile.getDateCreated();
  zText += "\n" + "getSize: " + aFile.getSize();

etc...

While the above approach would eventually get what I want, I'd like to avoid having to lookup all the property names. I'm aware that many properties might not be able to be converted to string, but I'd like to at least have them isolated by name.

What I've Tried

I thought my question was similar to this question that uses stringify. However, that doesn't work on a Google File object (it just returns a string value of {}). I'm guessing this is because a lot of the properties are calling functions?

I can get all of the file's property/functions LISTED as string, by using: Object.keys(aFile).forEach((prop)=> Logger.log(prop ));

However, this doesn't return the RESULT of each function, and many of these are functions I wouldn't want to execute (i.e. makeCopy).

While there may be a better method, I am assuming I'd probably be safe to try to execute all the properties/functions that start with get or is. I don't know of way to do this, nor can I find anything matching this type of use case. I did see this post about using executeFunctionByName, but that didn't work on the App Script environment. If it did work, I'd have used something like this..

var allKeys =  Object.keys(aFile);
for(var i=0;i<allKeys.length;i++){
 var eachProperty = allKeys[i];
 
 if(eachProperty.search(RegExp("^get|^is"))>-1 ){
  //??? run the literal name of function on aFile and print result?
    Logger.log(eachProperty + ':' + executeFunctionByName(eachProperty,aFile));
 }
}

If there's an entirely better approach to this that I'm unaware of, feel free to redirect me.

pgSystemTester
  • 8,979
  • 2
  • 23
  • 49
  • Although I'm not sure whether I could correctly understand `I'm looping through a variety of files, and trying to figure out a way to dynamically list/capture as much information from a GAS File Object as possible.`, I proposed an answer. Please confirm it. If I misunderstood your question and that was not useful, I apologize. – Tanaike May 14 '23 at 01:33

1 Answers1

6

Although I'm not sure whether I could correctly understand your expected result, how about the following sample script?

Sample script:

function getObj_(file) {
  const exclude = ["getAccess", "getAs", "getSecurityUpdateEligible", "getSecurityUpdateEnabled"];
  const obj = {};
  for (let method in file) {
    if (!exclude.includes(method) && /^get|^is/.test(method)) {
      obj[method] = file[method]();
    }
  }
  return obj;
}

function sample1() {
  const file = DriveApp.getFileById("###fileId###");
  const res = getObj_(file);
  console.log(res)
}

function sample2() {
  const res = [];
  const files = DriveApp.getFolderById("###folderId###").getFiles();
  while (files.hasNext()) {
    res.push(getObj_(files.next()));
  }
  console.log(res)
}

Testing:

When this script is run, the following result is obtained. In this test, sample1 is run to Spreadsheet. The keys are the methods. In this case, the Class object is included in the values. Please be careful about this.

When sample2 is run, the following object is included in an array.

{
  "getOwner": DriveUser,
  "getViewers": "",
  "getThumbnail": Blob,
  "getTargetId": null,
  "getDownloadUrl": null,
  "getTargetMimeType": null,
  "getTargetResourceKey": null,
  "getMimeType": "application/vnd.google-apps.spreadsheet",
  "getEditors": "",
  "getName": "filename",
  "getId": "###",
  "getSize": 12345,
  "isStarred": false,
  "getParents": FolderIterator,
  "getDescription": null,
  "isTrashed": false,
  "getUrl": "https://docs.google.com/spreadsheets/d/###/edit?usp=drivesdk",
  "getResourceKey": null,
  "getSharingAccess": "PRIVATE",
  "getSharingPermission": "NONE",
  "getDateCreated": Date,
  "getLastUpdated": Date,
  "getBlob": Blob,
  "isShareableByEditors": true
}

Note:

  • I thought that when Drive API is used as follows, the file metadata can be also retrieved. But, from your question, I guessed that you might want to use the Drive service (DriveApp) instead of Drive API. So, I proposed the above sample script. If your goal includes using Drive API, the following script might be able to be used.

    const obj = Drive.Files.list({ q: `'${folderId}' in parents and trashed=false`, fields: "*", corpora: "allDrives", includeItemsFromAllDrives: true, supportsAllDrives: true, maxResults: 1000 });
    

Reference:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • As usual, you have rescued me once again! Thank you! I always learn so much from your posts. – pgSystemTester May 15 '23 at 16:13
  • 1
    @pgSystemTester Thank you for replying. I'm glad your issue was resolved. And also, I appreciate that you check my posts. Thank you, too. – Tanaike May 15 '23 at 23:57