How do I locate the path of the folder in which the current script file is located?
Asked Answered
S

7

6

How do I locate the path of the current folder? I just want to be able to get the path of the folder so that I can manipulate the files in the folder without typing the path into the scripts.

Suggest answered 8/2, 2013 at 10:40 Comment(1)
Do you have a standalone script or something that is embedded in a Spreadsheet ?Dix
R
9

For a Spreadsheet I found this to work:

thisFileId = SpreadsheetApp.getActive().getId();
var thisFile = DriveApp.getFileById(thisFileId);
var parentFolder = thisFile.getParents()[0].getName();
Rigdon answered 18/5, 2013 at 16:22 Comment(3)
For a Document use: thisFileId = DocumentApp.getActiveDocument().getId(); instead.Pagination
@Pagination if only there was some way to get the active no matter what kind it was...Sentry
I got this error: Cannot read properties of undefined (reading 'getName'). Why?Nimwegen
V
4

Thanks to Corey's answer and to Thomas'one, here is a "full featured" version that shows the folder tree in the logger and every parents id as well... just for fun ;-)

function getScriptFolderTree() {
  var thisScript = getThisScriptInDrive();
  var names = []
  var Ids = []
  var folder = thisScript.getParents()[0];
  while (folder.getName() != "Root"){
      names.unshift(folder.getName());
      Ids.unshift(folder.getId());
    var parents = folder.getParents();
       var folder = parents[0];
  }
Logger.log('Root/'+names.join().replace(/,/g,'/'))  
Ids.unshift(DriveApp.getRootFolder().getId())
Logger.log(Ids)  
}


function getThisScriptInDrive() {
  return DriveApp.getFileById("poiuytrezazertyujhgfdsdcvcxyydryfhchfh");
}

enter image description here

(ID's are truncated intentionally)

Note that this script is working nicely but it strangely stops working if the 'random string' is modified... I imagine that the search engine in drive doesn't like the change but I have no serious explanation (comments welcome) but after a few minutes it works again ;-)

Vindictive answered 8/2, 2013 at 23:34 Comment(5)
Procrastination pays. Thanks Serge. You saved me some time. The delay is probably caused by all the indexing.Redon
Hi Michael, you're right about indexing.... strangely today it is almost instantaneous ;-) - That said, the script is not yet perfect, some "special cases" where a file is in 2 folders simultaneously (which you can't make with the Drive web UI but is feasible with GAS) are not handled correctly... Anyway, I'm not concerned by this special case as I prefer not to have these kind of weird arrangement ^^Vindictive
Hi Serge, It is possible to make one folder the child of 2 other folders. see:webapps.stackexchange.com/questions/26010/… So this script is FAR from perfect.Espinosa
Thanks for the link, I didn't know the 'command click' selection... even if I'm pretty sure I won't ever use it :-) - That said, feel free to suggest a better version that handles every possible combination, I'll be happy to vote it up.Vindictive
What random string? Is poiuytrezazertyujhgfdsdcvcxyydryfhchfh a random string or the id of the script or the spreadsheet that is bound to the script or the form id that is bound to the spreadsheet or ?????Venuti
S
3

Add a function like this to your script

function getThisScriptInDrive() {
  return DriveApp.find("some unique string that wont be anywhere else")[0];
}

This will search Drive and find this script itself because it contains that string - right there in the function call! - no need to declare it anywhere else. As long as you use an obscure enough string - i'd recommend mashing a few hundred chars on your keyboard - it will be unique across drive and therefore just work.

Once you have a File for this script, you can call getParents() etc.

Siliceous answered 8/2, 2013 at 18:5 Comment(1)
This answer is obsolete as DriveApp.find is not listed on developers.google.com/apps-script/reference/drive/drive-app and is not included in the Deprecated methods section either.Therefrom
M
2

I was able to get the folder containing the script that was running:

//
// PrintScriptFolder -- print the name of the folder in which the running script resides.
//
function PrintScriptFolder()
{
  var scriptId = ScriptApp.getScriptId();
  console.info('scriptId = ' + scriptId);
  
  var file = DriveApp.getFileById(scriptId);
  var folders = file.getParents();
  if (folders.hasNext())
  {
    var folder = folders.next();
    var name = folder.getName();
    console.info('script folder name = ' + name);    
  }  
}

The trick is using ScriptApp to get the ID of the running script. From there it's pretty straightforward: use DriveApp to get the file ID, getParents() to get a list of (one) parent folder, next() to get it, and getName() to get its name.

Madura answered 27/7, 2020 at 22:16 Comment(1)
scriptId = 1xe2mbAXd1M8djvRFS_xlN8hG8g1B4C3UuRVxEa4vTQ7dQMe3NlxlYUIC Feb 5, 2021, 11:34:13 AM Error Exception: No item with the given ID could be found. Possibly because you have not edited this item or you do not have permission to access it. Just your function running from my script!?!?Venuti
P
2

I tweaked Serge's code to write a generic function

function getThisFilePath() {
  //let thisFile = DriveApp.getFileById(DocumentApp.getActiveDocument().getId());  // for a Doc
  let thisFile = DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()); // for a Sheet
  let path = {name: '', folder: []};
  let folder = thisFile.getParents().hasNext() ? thisFile.getParents().next() : undefined;
  while (folder) {
    path.folder.unshift({name: folder.getName(), id: folder.getId()});
    folder = folder.getParents().hasNext() ? folder.getParents().next() : undefined; 
  }
  path.folder.forEach(folder => path.name += '/' + folder.name);
  Logger.log(path.name);
  return path;
}

Logging output

11:02:57 AM Info /My Drive/Technology/Development/2022

Prefer answered 15/12, 2021 at 19:35 Comment(0)
C
0

Looking for a simple getPath, I went for a more generic approach with limitations:

    //simple test stub
    function test_getFilePath() {
      const scriptId = ScriptApp.getScriptId();
      const fullPath = getFilePath(scriptId);
      console.log(fullPath);
    }
    
    /**
     * getFilePath
     *  @fileId id of file to find path for
     * 
     *  NB: google allows for multiple parents, which is a PITA
     *  so I'm just taking the first one I find up the tree
     */
    function getFilePath(fileId) {
      const file = DriveApp.getFileById(fileId);
    
      const rootFolder = DriveApp.getRootFolder()
      const rootFolderId = rootFolder.getId();
      const rootFolderName = rootFolder.getName();
    
      let folder = file.getParents().next();
    
      let folderNames = [];
    
      while (folder.getId() !== rootFolderId){
          folderNames.unshift(folder.getName());
          folder = folder.getParents().next();
      }
    
      const fullPath = rootFolderName+'/'+folderNames.join().replace(/,/g,'/');
    
      return fullPath;
    
    }

console:

11:36:40 AM Info My Drive/GAS


Had I more time/inclination, I'd have writen a recursive function to capture and return an array of possible parent paths, but there's no use case for me and who the hell wants to keep a the same file in multiple folders anyway??

Coca answered 2/12, 2022 at 3:43 Comment(0)
E
-1

You could do this:

function myFunction() {
  var thisScript = getThisScriptInDrive();
  var folder = thisScript.getParents()[0];
  while (folder.getName() != "Root"){
    var parents = folder.getParents();
    for (var i in parents){
      var folder = parents[i];
      Logger.log(folder.getName());
    }
  }
}


function getThisScriptInDrive() {
  return DocsList.find("`<jj!?=(<DW+.W/m7SBF:sgu/@B(&Cs3:{ajA~ys@KmN4&]ujhpZ~z[Tv?+dk}MpK,8pY=w&dny8N'74:.9H:~uCgY=7pRt4[Tn5")[0];
}

This only works good if the folder has only 1 parent because it only takes 1 path.

edit: Thanks to Corey G

Espinosa answered 8/2, 2013 at 15:33 Comment(2)
Thank a lot for your reply. How do I get the FOLDER ID of the folder in which the script file is located?Suggest
If you have a standalone script you can'tEspinosa

© 2022 - 2024 — McMap. All rights reserved.