I'm looking to create a script that makes a copy of the active spreadsheet, gives edit access to the person who created the sheet, but then sets me as the owner.
This works when I run it using the owner account, but I receive
Exception: Access denied: DriveApp
when triggered from a separate Google account.
I thought my script would add both accounts as editors, then set my personal as the owner.
Any idea why?
function makeCopy() {
var title = SpreadsheetApp.getActiveSheet().getRange("B1").getValue();
SpreadsheetApp.getActive().toast("Your Sheet is being created", "Good Luck!", 5);
var email = Session.getActiveUser().getEmail(); //get the user's email who ran the script
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId(); //get the current Spreadsheet's ID
var copyID = DriveApp.getFileById(ssID).makeCopy().setName(title).getId(); //make a copy of the spreadsheet and retrieve the new ID
DriveApp.getFileById(copyID).addEditor(email); //add the user as an editor to the new copy
DriveApp.getFileById(copyID).addEditor("[email protected]")
DriveApp.getFileById(copyID).setOwner("[email protected]");
var newsheet = SpreadsheetApp.openById(copyID);
// Get the file associated with the sheet
var file = DriveApp.getFileById(newsheet.getId());
// Set the permissions to allow anyone to edit the file
file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
//var sheet = newsheet.getSheetByName("Sheet");
//sheet.deleteRows(15,3)
// var sheetId = "1234567890abcdefghijklm";
// Open the sheet in a new tab
var url = "https://docs.google.com/spreadsheets/d/" + copyID;
var html = HtmlService.createHtmlOutput('<script>window.open("' + url + '");</script>').setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi().showModelessDialog(html, "Showtime!");
}
Exception: Access denied:
.When these points are reflected in your script, how about the following modification?
Before you test this script, please enable Drive API at Advanced Google services.
function makeCopy() {
var title = SpreadsheetApp.getActiveSheet().getRange("B1").getValue();
SpreadsheetApp.getActive().toast("Your Sheet is being created", "Good Luck!", 5);
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var copyID = DriveApp.getFileById(ssID).makeCopy().setName(title).getId();
Drive.Permissions.insert({ role: "writer", type: "user", value: "[email protected]", pendingOwner: true }, copyID);
DriveApp.getFileById(copyID).setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
var url = "https://docs.google.com/spreadsheets/d/" + copyID;
var html = HtmlService.createHtmlOutput('<script>window.open("' + url + '");</script>').setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi().showModelessDialog(html, "Showtime!");
}
From your following reply,
but is there a way for the permission to automatically go through? Unfortunately, I won't be able to accept the emails quick enough - I was hoping in the script it can just automatically set the owner. Any thoughts? This is amazing though.
In this case, as a pattern 2, I would like to propose using Web Apps as I mentioned in my comment.
Please copy and paste the following script to the script editor of Spreadsheet and save the script.
function doGet(e) {
const { spreadsheetId, email, title, key } = e.parameter;
if (key == "samplekey") {
var file = DriveApp.getFileById(spreadsheetId).makeCopy(DriveApp.getRootFolder()).setName(title);
file.addEditor(email);
file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
return ContentService.createTextOutput(JSON.stringify({ id: file.getId() }));
}
return ContentService.createTextOutput(JSON.stringify({ error: "Invalid key." }));
}
function makeCopy() {
var webAppsUrl = "https://script.google.com/macros/s/###/exec"; // Please set your Web Apps URL.
var title = SpreadsheetApp.getActiveSheet().getRange("B1").getValue();
SpreadsheetApp.getActive().toast("Your Sheet is being created", "Good Luck!", 5);
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var email = Session.getActiveUser().getEmail();
var res = UrlFetchApp.fetch(`${webAppsUrl}?spreadsheetId=${ssID}&email=${email}&title=${title}&key=samplekey`);
var obj = JSON.parse(res.getContentText());
if (obj.error) return;
var url = "https://docs.google.com/spreadsheets/d/" + obj.id;
var html = HtmlService.createHtmlOutput('<script>window.open("' + url + '");</script>').setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi().showModelessDialog(html, "Showtime!");
}
The detailed information can be seen in the official document.
Please set this using the new IDE of the script editor.
https://script.google.com/macros/s/###/exec
. This URL is used for your HTML.var webAppsUrl = "https://script.google.com/macros/s/###/exec";
of the above script.When you modified the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
You can see the detail of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".
When other user who is not you (the owner of Spreadsheet) is run makeCopy()
, the active Spreadsheet is copied to your root folder by you (the owner). By this, you are the owner of copied Spreadsheet. And, the executed user is added as a writer.
When you modified the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
You can see the detail of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".