1

I have a google sheets workbook that builds a report based on user input, which is run by clicking a "button" (a square shape on the sheet itself). I want to share this workbook with my team, who need to create a copy of the workbook so they can generate multiple reports for themselves.

However, I also want to be able to make changes to the code at a later date, and avoid having them re-download the latest version, so I'm trying to decentralise the Apps Script file by putting it into my company's shared Google Drive, and then the workbook script replaced by a function that loads that file in the drive.

So far I have:

function getApp(){

var folderId = "<folder_id>";
var fileName = "<file_name>";
var scriptId = "<script_id>";

var folder = DriveApp.getFolderById(folderId);
var files = folder.getFilesByName(fileName);

var url = "https://script.google.com/feeds/download/export?id=" +
    scriptId + "&format=json"

var options = {
  "method": "GET",
  "headers": {
    "Authorization": "Bearer " +  ScriptApp.getOAuthToken()
  },

  "muteHttpExceptions": true
};

var response = UrlFetchApp.fetch(url, options);

dataContentAsString = response.getContentText();
fileContents = JSON.parse(dataContentAsString);

var codeFile = fileContents.files[1];

if (codeFile){
  var code = codeFile.source;
  eval(code);
  buildReport();
}
}

Which takes the "file" at index 1 (an object containing all functions in the script) and runs the buildReport function. When I do Logger.log(fileContents) I can see the entire script, so I know the retrieval from google drive is working.

buildReport() is the "main" function, which then calls other functions, however when running it, I get the error below, which indicates an Oauth issue:

Exception: You do not have permission to call SpreadsheetApp.getActive. Required permissions: (https://www.googleapis.com/auth/spreadsheets.currentonly || https://www.googleapis.com/auth/spreadsheets)

  1. Does this mean that despite being able to access the file, the file itself doesn't have access to the sheets (that contain templates which the script manipulates based on the users initial inputs prior to clicking the button) where the macro is being run from?

  2. Is this the best way to achieve what I want?

Update

I added a trigger to the workbook, which runs buildReport just fine when the spreadsheet is opened (not the desired behaviour, but still at least it's working in some way), however when clicking the "Build Report" button it shows the error still.

  1. Why would the local script (i.e. local to the google sheet) be able to successfully import from google drive and run buildReport() when using a trigger, but not when clicking a button to do the same thing?
5
  • Note : I haven't set this up using GCP projects Commented Feb 7, 2023 at 13:49
  • Do you use Simple Triggers in any part of your implementation? like an onOpen(e), onInstall(e), onEdit(e), onSelectionChange(e), doGet(e) or doPost(e). Commented Feb 7, 2023 at 16:10
  • No, the script saved in google drive is just run entirely after a single button is pressed, no triggers needed really. As highlighted in the update above, using the UI to add a trigger seems to run the script imported from gDrive, but that isn't what I'm intending on doing (it should run on button-press) Commented Feb 7, 2023 at 17:10
  • 2
    I'm intrigued that with an onOpen edit you can "do stuff" with the Speradsheet without giving Spreadsheets permissions before. Anyway, when they press the button they have to grant permissions for Drive (DriveApp) and connect to external service (urlFetchApp). You can add a "dummy" line and comment it (//SpreadseetApp.getActive; for example) so that, when the button is pressed they grant permission for editing gsheets. You can also deploy your script as a library and they wouldn't use Drive or urlFetchapp permissions Commented Feb 7, 2023 at 20:49
  • I know right, it's quite strange. Adding the dummy line worked, thank you! Please can you add as an answer? Commented Feb 8, 2023 at 9:30

1 Answer 1

2

If you have an standalone script that will "modify" the user current Spreadsheet (or slides, or...) but the script bounded to the Spreadsheet only "calls" the external script, you can add a dummy/commented line to the bound script, so that when the user runs the bound script, permissions for the standalone script will also be asked. Sorry, for my english :D Adding this line, anywhere, will do the trick:

//SpreadsheetApp.getActive()

BTW, I found very useful your way to share scripts!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.