How to get the file URL from file name in Google Sheets with correct Authorization via custom function/script

后端 未结 3 1860
小蘑菇
小蘑菇 2020-12-11 13:43

I would like to create a custom function that pulls a Drive URL from a file name in Google Sheets.

So, using the code below:

  1. If I have a valid file nam
相关标签:
3条回答
  • 2020-12-11 14:23

    This may be a solution for some needs.

    My particular need was: loop through a column of file names and pull the Google Docs URL at a set interval. The code below just loops through filenames in "Column A" of "My Sheet" and returns the value into the adjacent cell of "Column B" (starting at row 2 because I had column headers). I'm not concerned about security because I'm only referencing internal organization files.

    To get the code below to work you need to:

    1. Google Sheet Doc Nav > Tools > Script Editor
    2. Create a .gs file & input code below (Referencing The Respective Sheet
    3. Within Script Editor > Edit > Current Project’s Triggers > Name Your Project
    4. Within Script Editor > Edit > Current Project’s Triggers > Click on modal link “No triggers set up. Click here to add one now” > set your time-based trigger (reference replaceFileColumn in the select field within that modal)

    My mistake was: thinking that I needed to use a custom function in each cell to do so. (I still don't fully understand the auth reasons why this wouldn't work, so if anyone could explain in lay-man's terms that would be fabulous; my solution is just a workaround for expediency's sake).

    In my spreadsheet I have a time-driven trigger calling replaceFileColumn()

    Hope this helps someone!

    function getMyFile(cell) {
      var filename = encodeURI(cell);
      var files = DriveApp.getFilesByName(cell);
      while (files.hasNext()) {
        var file = files.next();
        if(file){
          var fileValue = file.getUrl();
          return(fileValue);
        };
      };
    }
    
    function replaceFileColumn() {
      var spreadsheet = SpreadsheetApp.getActive().getSheetByName('My Sheet');
      var range = spreadsheet.getRange("A2:A");
      var range_update = spreadsheet.getRange("B2:B");
      var values = range.getValues();
      for (var i = 0; i < values.length; i++) {
        var fileName = values[i];
        var getFileUrl = getMyFile(fileName);
        values[i][0] = getFileUrl;
      }
      range_update.setValues(values);
    }
    
    0 讨论(0)
  • 2020-12-11 14:25

    Custom functions runs as if run by a anonymous animal(user). ScriptApp.getOAuthToken will return a anonymous token without the required scopes. What you're attempting is not possible, unless the file in question is public.

    References:

    • Custom functions permissions
    • Custom functions access services
    0 讨论(0)
  • 2020-12-11 14:29

    @I'-'I's answer is correct. Although I'm not sure whether this is what you want, how about this workaround? I have also experienced the same issue. At that time, I had used the following workaround.

    • Set and get access token using PropertiesService.

    The flow is as follows.

    Flow:

    1. Set access token every 1 hour by the time-driven trigger.
      • By this, the access token is updated every 1 hour. Because the expiration time of access token is 1 hour.
    2. When the custom function is run, it gets the access token using PropertiesService.
      • By this, the access token can be used.

    Modified script:

    Please install this function as the time-driven trigger. Of course, you can run manually this function.

    function setAccessToken() {
      PropertiesService.getScriptProperties().setProperty("accessToken", ScriptApp.getOAuthToken());
    }
    

    In your script, please modify as follows.

    From:
    var params = {
      method: "GET",
      headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
      muteHttpExceptions: true
    };
    
    To:
    var params = {
      method: "GET",
      headers: {"Authorization": "Bearer " + PropertiesService.getScriptProperties().getProperty("accessToken")},
      muteHttpExceptions: true
    };
    

    Note:

    • In this case, the owner of access token is the owner of project.
    • I think that this can be also used by CacheService.

    Reference:

    • PropertiesService
    0 讨论(0)
提交回复
热议问题