I'm looking to call UrlFetchApp.fetch() based on user input on a sheet but nothing happens. No errors, just silently ignores the call. Same goes for MailApp.sendEmail() and GmailApp.sendEmail()
This is on a Google Apps domain, and only domain users are using the Google Sheet.
Simple triggers like onOpen or onEdit are not able to do anything that requires authorization like sending mails because they run silently and anonymously.
This is all explained in the documentation .
You should simply rename your onEdit function to something else - SpecialOnEdit for example ? - and create an installable trigger (documentation) from the script editor menu (ressources/triggers/create a new trigger...)
You can see an execution flow in view -> execution transcript in the script editor. Just change a cell value in spreadsheet then come back the script editor and check "execution transcript". It will show you an error if it happens.
Related
I have a Google Sheets spreadsheet that's been working for months, and has no scripts associated with it. Recently I decided I'd like to log the date of change to a row, and that the onEdit() function could do that for me.
From the spreadsheet display, I selected Tools / Script Editor, which popped up an empty script with a myFunction() function.
I modified myFunction() to:
function onEdit(e) {
Logger.log("Something was edited.");
}
Then pressed Save and accepted the default progject name (Untitled project). I also tested this (Run) and it created a log entry.
Now when I edit any value in the sheet or add a new row, I would expect a log entry. But none appears.
Have I missed a step? What must one do in order to get a valid onEdit() to run?
Your logs will be available at View>Stackdriver logging. View>Logs will only show logs executed in the current session (by clicking "Run"). Using console class is preferred.
Disclaimer: I don't often work with the Script Editor in Google Sheets, nor Google Sheets itself, too often. There may be a better way to accomplish this.
In my experience, I've found you also have to explicitly add a trigger to your Script Editor project to get the events to fire correctly.
From your sheet, open your Apps Script project by selecting the Tools > Script Editor menu option.
From the resulting Apps Script project screen, select the Edit > Current Project's Triggers menu option.
From the resulting Triggers view, click the + Add Trigger button (appeared in the lower-right of the interface presented to me; your mileage may vary).
In the resulting modal, select the following options:
"Choose which function to run" - select the onEdit method to execute the method you've written.
"Choose which deployment should run" - I've selected the "Head" option, but I'd imagine your mileage will vary wildly if you've elected to use the more advanced deployment features here.
"Select event source" - set this to "From spreadsheet".
"Select event type" - set this to "On edit".
"Failure notification settings" - set this to whatever setting you'd like.
Finally, click the "Save" button.
Once your trigger is set up, the spreadsheet should now be running your method whenever an edit to the spreadsheet is made.
Answer:
Make sure you run the onEdit(e) function from the Apps Script UI using the play button (►) and authorise the script to run as you.
By Google documentation, an onChange trigger for a Spreadsheet addon has to be created programmatically via ScriptApp.newTrigger(...)....
newtrigger requires the scope :
https://www.googleapis.com/auth/script.scriptapp
When the user is asked for granting permissions, the text presented is:
Allow this application to run when you are not present
I understand this function can create time based trigger, but for a simple onChange in a Spreadsheet, I would understand if the user declines it due to that text.
Is there a way to have an onChange trigger without this scope for changes (not onEdit) in spreadsheets?
Answer:
The only way to create a trigger on behalf of a user programmatically is using ScriptApp.newTrigger(), and this method requires the https://www.googleapis.com/auth/script.scriptapp scope. No other scope will allow this to run.
You can however set up an onChange() trigger for the Spreadsheet, which will run regardless of who makes the change to the sheet.
More Information:
When you set up a trigger, you are allowing an app/script/function to run, on behalf of you, without you manually running the function. Asking a user to create a trigger will require them to authorise that they consent to the script doing something on their behalf.
You can however, set up the trigger yourself. As long as the function that will run on the trigger doesn't violate any of the installable trigger restrictions then this will run on the Sheet as long as it has been authorised to run by you.
Remember though, that if you set up the trigger yourself, the script will always execute as you, not as the user. So if the function, for example, sends an email, then the email will be sent on behalf of you - as you were the one that authorised the script.
Setting up an Installable Trigger manually:
If setting up the trigger to run as you is an acceptable solution, you can do so by following these steps:
Save the script with the save icon, press the run button (►), and confirm the authentication of running the script.
From here, following the Edit > Current project's triggers menu item, you will have a new page open in the G Suite Developer Hub. Click the + Add Trigger button in the bottom right and set up the trigger settings as follows:
Choose which function to run: <your-function-name>
Choose which deployment should run: Head
Select event source: From Spreadsheet
Select event type: On change
And press save.
This will now run on all changes made to the sheet - regardless of who made the change. Just remember that as far as execution goes, you're the script runner.
References:
Class ScriptApp | Apps Script - .newTrigger(functionName) method
Installable Triggers | Apps Script - Restrictions
Event Objects | Apps Script - Google Sheets events: Change
my onEdit() function calling to other function when there is a change in the sheet.
if the user makes the change all works fine.
but if the change was made by google-form (the form fill some cells with the answers it gets) onEdit() does not trigger.
do I miss something?
Yes, you forgot to read the documentation for the simple triggers:
onOpen(e) runs when a user opens a spreadsheet, document, or form that he or she has permission to edit.
onEdit(e) runs when a user changes a value in a spreadsheet.
onInstall(e) runs when a user installs an add-on.
doGet(e) runs when a user visits a web app or a program sends an HTTP GET request to a web app.
doPost(e) runs when a program sends an HTTP POST request to a web app.
and installed triggers:
Even though installable triggers offer more flexibility than simple triggers, they are still subject to several restrictions:
They do not run if a file is opened in read-only (view or comment) mode.
Script executions and API requests do not cause triggers to run. For example, calling FormResponse.submit() to submit a new form response does not cause the form's submit trigger to run.
Installable triggers always run under the account of the person who created them. For example, if you create an installable open trigger, it will run when your colleague opens the document (if your colleague has edit access), but it will run as your account. This means that if you create a trigger to send an email when a document is opened, the email will always be sent from your account, not necessarily the account that opened the document. However, you could create an installable trigger for each account, which would result in one email sent from each account.
A given account cannot see triggers installed from a second account, even though the first account can still activate those triggers.
Consider what would happen if your onEdit(e) was activated by programmatic changes, such as if your onEdit function alters the spreadsheet values...
In your situation, where you want form submission to activate your on edit function, You will need to install a form submission trigger (there is no simple trigger for form submissions).
An example function to receive your form submission trigger:
function giveMeAnInstalledFormSubmitTrigger(formSubmitEventObject) {
if(!formSubmitEventObject) throw new Error("You called this from the Script Editor");
var newEventObject = /* do something with the formSubmitEventObject */;
// Call the on edit function explicitly
onEdit(newEventObject);
}
You can read more about the event objects that triggered functions receive in the Apps Script documentation: https://developers.google.com/apps-script/guides/triggers/events
onEdit() will not be triggered by another script editing a sheet or by a form submission.
You can use onFormSubmit(e) instead depending on what your function does it would be a good idea to use the e parameter of the trigger.
https://developers.google.com/apps-script/guides/triggers/events#form-submit
What i have done is that i created an extra sheet with a cell that is the same where the primarecell is(the cell that changes). Leave it for now. I open the scriptapp and write down the code(the code that should happen if the cell changes). Then i wrte down "if" and take the two value i both cells and make an trigger that goes on every minute. With that said, if The cells are the same the "if" is looping on "true". But if something change on the primary cell, it will be "false" and you use "else". Under"else" you should have what ever function you want when soemthing change in that cell. + You must have a funtion where you insert the new value form the primarycell to the "check cell" if u want this too function as loop. Otherwise the "if" code will loop "false" every minute becuse the both cells are not the same.
My english and explaining is not that good:(
I am trying to apply conditional formatting rules on a google sheet using a google apps script. I found that this could be done with the API, so I enabled it and have it all working when ran from my script ... but when I trigger the script to run from my sheet, the API batchUpdate doesn't run. I am sure I'm missing something simple ...
The code is in the Themes.gs project of this spreadsheet: https://docs.google.com/spreadsheets/d/1Fs6B-OmlqfoAoon5PcoAYbHq4CO8w0qPqfSRy_OQhe0/copy
specifically this bit doesn't seem to run when the script is triggered from the sheet itself:
Sheets.Spreadsheets.batchUpdate(JSON.stringify(functionname), SpreadsheetApp.getActiveSpreadsheet().getId())
A simple solution is Installable Triggers.
Rename your onEdit() function to something else, like whenWeEdit().
Click the link that says: No triggers set up click here to add one now.
Under Run, select whenWeEdit (or whatever you renamed your function as).
Under Events, select From spreadsheet.
Next, instead of On open, select On edit.
Click save.
Edit the sheet. Your function now seems to work for me. What about you?
I'm having an issue with doing an HTTP Post in the onOpen event in google apps script.
What I'm trying to do is send a notification to another deployed script that someone has opened one of our spreadsheets. I'd like this functionality to persist even when someone copies the spreadsheet so that we can track where those are as well.
My problem is that if I call UrlFetchApp.fetch(url, options) from the onOpen event, I get the error - "Execution failed: You do not have permission to call fetch" however the fetch does work if I create a trigger using the ui that fires when the spreadsheet is opened. The problem with this approach is those triggers are not copied when the spreadsheet is copied.
Any suggestions for a possible solution or a simple workaround would be greatly appreciated.
Thanks,
Mark.
There are two types of triggers - simple and installable. The onOpen is a simple trigger and there are limitations on what you can do within a simple trigger and doing an UrlFetch is one of them. You can read more about simple & installable triggers at https://developers.google.com/apps-script/understanding_triggers