Google Sheet onEdit(e) having permission problem - google-apps-script

ERROR : You do not have permission to call ScriptApp.newTrigger. Required permissions: https://www.googleapis.com/auth/script.scriptapp.
Having permission problem to create time based trigger
function onEdit(e){
var sheetName = e.range.getSheet().getName()
if(sheetName == "Config")
{
if(e.range.getRow()==2 && e.range.getColumn()==1){
createSpreadsheetOpenTrigger()
}
}
}
function createSpreadsheetOpenTrigger() {
Logger.log("hello")
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('myFunction')
.forSpreadsheet(ss)
.onOpen()
.create();
}

For Simple Triggers, just running the script within the App Script Web IDE is enough and should prompt you with an authentication popup: Simple Auth Steps.
However, to programmatically create new Triggers you need to make sure the onEdit Trigger is Installable! This gives you increased permissions to do what you need.
We need to open up the dev console to set up an installable trigger.
We need to create a new trigger tied to our function. For installable triggers, it is best not to use the default simple trigger onEdit() function name.
Done! We should be able to run our functions based on triggers with increased permission scopes.

Related

Install user specific onEdit Trigger using Google Apps Script

I have created a simple OnOpen add-on in Google sheets that installs a trigger to send email based on Edit in the sheet. When I installed it, I authorized it from my account. The script is as follows:
function onOpen(e) {
var ui = SpreadsheetApp.getUi().createMenu("Install Trigger").addItem("Run", "initialize").addToUi();
}
const initialize = () => {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ScriptApp.newTrigger('sendEmail')
.forSpreadsheet(ss)
.onEdit()
.create();
};
The script runs fine and sends emails from my email address which I authorized. Now the issue is when I shared this sheet with another editor, the person does not need to install this trigger and he can send email from my email account without any authorization. Is there a way that we can make every editor in this sheet install their own trigger to send email from their email account instead of using mine?
You could use the method getUserTriggers(spreadsheet) that retrieves all installable triggers owned by the user executing the script:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var triggers = ScriptApp.getUserTriggers(ss);
// Log the event type for the first trigger in the array.
Logger.log(triggers[0].getEventType());
If this comes with a trigger, you know that the user has already installed the trigger.
If this comes empty, means that the user has no triggers in it. Then you could use the method deleteTrigger(trigger) to delete the existing triggers (created by others) in the script and then programatically create a new one:
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
ScriptApp.deleteTrigger(triggers[i]);
}

OnFormSubmit() not firing

I am trying to solve the following case: I have a template that is copied by users and linked to a Google Form. Also, I have a script that does some configuration to the Form Responses tab for its further usage. It works perfectly in the template, however, the installable onFormSubmit() trigger is not copied together with the template. To solve this I added onOpen() trigger that installs the onFormSubmit() which was confirmed to work.
The issue I am facing is that while onFormSubmit() is successfully installed in the template copy, it still does not fire automatically. I assume that this is related to some permissions issue. Is there any way to rewrite the script to avoid additional authorization?
function onOpen(e) {
addFormSubmissionListener();
//// other init...
}
function addFormSubmissionListener() {
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("onFormSubmit")
.forSpreadsheet(sheet)
.onFormSubmit()
.create();
}
function onFormSubmit(e) {
var range = e.range
var sheet = range.getSheet();
var spreadsheet = SpreadsheetApp.getActive();
if(spreadsheet.getSheetByName('Responses') == null) {
sheet.setName('Responses');
sheet.insertColumnsAfter (7,10)
spreadsheet.getRange('Tech!A:J').copyTo(spreadsheet.getRange('Responses!H:O'), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
sheet.hideColumns(16, 2)
var curr_sheet = spreadsheet.getSheetByName('Jira import')
updateFormulasTwoRows(curr_sheet);
}
}
Answer:
If you create a new project you will always have to authorise it, there isn't really a way of getting around this.

Installable trigger is just keep getting disabled

I have been trying to install an installable trigger for a googlesheet workspace addon when a button is clicked. The trigger is meant to get fired whenever a cell is modified.
Unfortunately when a cell is modified, the trigger keeps getting disabled. The "disabled reason" (in Apps Script > Triggers > Last run column in the list) says: This trigger has been disabled for an unknown reason. I have tried calling from onHomepage() also.
Here is the code:
function createWidgetDemoCard() {
return CardService
.newCardBuilder()
.setHeader(...)
.addSection(
CardService.newCardSection()
.setHeader('Simple widgets') // optional
.addWidget(CardService.newTextParagraph().setText('Some text'))
.addWidget(CardService.newImage().setImageUrl('.../trees-autumn-colors-lake-picutre-600w-1827312116.jpg'))
.addWidget(CardService.newButtonSet().addButton(CardService.newTextButton()
.setText('Create trigger')
.setTextButtonStyle(CardService.TextButtonStyle.FILLED)
.setOnClickAction(CardService.newAction().setFunctionName('createSpreadsheetOpenTrigger'))
.setDisabled(false))))
.build();
}
function createSpreadsheetOpenTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('TestMe')
.forSpreadsheet(ss)
.onEdit() //onChange() not working`enter code here`
.create();
}
function TestMe(e) {
var range = e.range;
range.setNote('Last modified: ' + new Date());
}
The authscopes are:
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets.currentonly",
"https://www.googleapis.com/auth/spreadsheets"
]
The code from the TestMe() function works perfectly in a container-bound script. But because I am developing a Workspace addon, I want in a standalone script.
I can't really find a comprehensive documentation about developing an workspace addon.
Thanks!

How to get installable trigger to sense event

I created an installable trigger in a standalone script.
When I change something in the target spreadsheet, nothing happens. I don't get to a brekpoint in onEdit.
So how do I set up the trigger and onEdit to detect Edits?
ScriptApp.newTrigger('myOnEdit'){
.forSpreadsheet('1wfcYwChzLmbqxoXoSZUrXgZJIVbtEyNUIpfxmJihAcY')
.onEdit()
.create();
)
function onEdit(e){
// Set a comment on the edited cell to indicate when it was changed.
var range = e.range;
var ct = e.changeType
var ov=e.oldValue
var nv =e.value
var sc=e.triggerUid
range.setNote('Last modified: ' + new Date());
}
onEdit is a reserved function name to be used for on edit simple trigger. It should not be used for functions that will be called by an installable triggers as this could cause undesired effects as executing the function twice by a single event.
The installable trigger is being created to call a function named myOnEdit. In order to make it works your script should have a function named myOnEdit.

Install trigger for google app script in custom addon

I am still very new to addons and I am having trouble to install triggers and have the related functions to run.
Below is the function to add 1 "on open" trigger and 1 "on edit" trigger to the sheet.
function addTriggers() {
var sheet = SpreadsheetApp.getActiveSheet();
var triggers = ScriptApp.getUserTriggers(sheet);
if(triggers.length!=2)//
{
ScriptApp.newTrigger('sheetOpen')
.forSpreadsheet(sheet)
.onEdit()
.create();
ScriptApp.newTrigger('sheetEdited')
.forSpreadsheet(sheet)
.onOpen()
.create();
}
Then I tried to install this function through onInstall();
function onInstall(e){
addSpreadsheetEditTrigger();
sheetOpen();
}
function sheetOpen()
{
//do something after the sheet is open;
}
function sheetEdited()
{
//do something when the sheet is edited by user;
}
When I tested this addon, the triggers were not installed and thus none happened. Also please note that I need to use installable triggers because I need to access external files.
Could someone let me know where I did wrong?
1. How to build a trigger manually
If you want to build a trigger for a spreadsheet, you need to specify as parameter in forSpreadsheet() the spreadsheet, not the sheet!
So:
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
...
ScriptApp.newTrigger('sheetOpen')
.forSpreadsheet(spreadsheet)
.onOpen()
.create();
...
It seems that you got the assignment of the functions 'sheetOpen' and 'sheetEdited' the wrong way around
You should doublecheck either you really need to build the trigger manually. Instead you can call the already existing onOpen(e) trigger (unless you need an installable one).
Sample:
function onInstall(e){
sheetOpen();
}
function onOpen(e){
sheetOpen();
}
function sheetOpen()
{
//do something after the sheet is open;
}
UPDATE
Now, the limitations of Addons won't allow you to install triggers directly. Instead, you can create a custom menu giving the user the option to install the triggers when choosing the respective option.
Sample:
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
ui.createMenu('MyAddOn Menu')
.addItem('Please click here to get started', 'addTriggers')
.addToUi();
}
function addTriggers() {
...
}