Home > Mobile >  Google Apps Script Permissions for a function with inputs
Google Apps Script Permissions for a function with inputs

Time:02-16

I know this topic has bee covered before sort of, but none of it really makes sense to me. Basically I wrote a function that will generate a PDF from some API data using user inputs. It looks vaguely like this and works when I run it in the script editor.

enter image description here

function myfunction(InputA,InputB,InputC,InputD,InputE) {

......

var sourceSpreadsheet = SpreadsheetApp.getActive();
    var parents = DriveApp.getFileById(sourceSpreadsheet.getId()).getParents();
    if (parents.hasNext()) {
      var folder = parents.next();
    }

    var response = UrlFetchApp.fetch(url, options)
    var blob = response.getAs('application/pdf').setName(InputA   InputB   InputC)
    var newFile = folder.createFile(blob);

    return newFile
}
  

The problem is Google permissions. The classic: "You don't have permission to access the drive".

I have tried publishing the script as a private sheets addon and enabled it on my spreadsheet. But that didn't really do anything. And I don't really know why because I authorized the app for all the required scopes when I approved the add on. I can see it in the extensions menu but I am still getting errors when I try to call the function.

The button method of enabling permissions doesn't work for me because I need to run the code several times based on parameters defined in the Sheet. I tried simple triggers since I want the code to run weekly anyways, but found the same problem.

Can someone give me the step by step of how I'm supposed to do this.

Please don't send links to the google documentation because I have read the related pages and still don't know what I'm doing wrong.

CodePudding user response:

I recommend you use an installable onEdit trigger. I have this approach and see if it works for you.

Sample Data:

sample

  • Assuming url is from Input D column.
  • Create a column of checkboxes that will trigger the installed trigger. In my case, ticking it will create the file and unticking it will remove the file created.
  • Ticking rows where an input (at least 1) is missing, will cancel the creation of the file and then untick the checkbox ticked.

Drive folder:

folder

Script:

function createFileTrigger(e) {
  var spreadsheet = e.source;
  var sheet = spreadsheet.getActiveSheet();
  var range = e.range;
  var value = e.value;
  var row = range.getRow();
  var col = range.getColumn();

  // proceed if edited cell is Sheet1!H2:H
  if(sheet.getSheetName() == 'Sheet1' && col == 8 && row > 1) {
    // if checkbox is ticked
    if(value == 'TRUE') {
      // inputs = [Input A, Input B, Input C, Input D, Input E]
      var inputs = range.offset(0, -6, 1, 5).getValues().flat();

      var parents = DriveApp.getFileById(spreadsheet.getId()).getParents();
      var folder = parents.next();

      // set some conditions here to pre-check the inputs
      // e.g. if at least 1 input is blank, cancel file creation (return)
      if(inputs.filter(String).length < 5) {
        // untick the checkbox ticked
        range.setValue('FALSE');
        // skip creation of file
        return;
      }

      // assuming url is from Input D (removed options as not needed for presentation)
      var response = UrlFetchApp.fetch(inputs[3]);
      var newFileName = `${inputs[0]} ${inputs[1]} ${inputs[2]}`;

      // if file is existing (which should not happen but just in case)
      if(folder.getFilesByName(newFileName).hasNext()) {
        // do something else that is needed to be done to avoid duplication of file
        // e.g. overwrite or skip creating file
        console.log(newFileName   ' is already existing in the parent folder'); 
      }
      // if not existing
      else {
        // create the file
        var blob = response.getAs('application/pdf').setName(newFileName)
        // for presenation purposes, will write the id of the created file
        range.offset(0, -1).setValue(folder.createFile(blob).getId());
      }
    }
    // if checkbox is unticked
    else {
      // do something else that is needed to be done
      // e.g. delete the file using the id returned (using Drive Advanced Services)
      var fileIdRange = range.offset(0, -1);
      Drive.Files.remove(fileIdRange.getValue());
      // remove file id content on the cell
      fileIdRange.clearContent();
    }
  }
}

Ticking checkbox (folder):

checkbox folder

Ticking checkbox (sheet):

checkbox sheet

Note:

  • This can still be improved, but should already be enough for your case.
  • Related