google spreadsheet script - permissions to protect sheet - google-apps-script

I have the following spreadsheet:
-Template (protected)
-Current working sheet
-older sheet (protected)
-even older sheet (protected)
This spreadsheet is shared with a few users, and they have write permission in the "current working sheet". Once it is considered completed, I created a button in the "current working sheet" to which I assigned a script. When ran as owner, the script:
renames the "current working sheet" to "something older"
protects the "something older" sheet
duplicates the "template" sheet as a new "current working sheet"
It all works fine wen ran by owner, however when the button that triggers the script is pressed by one of the users whom I shared the document with, then step (2) fails, meaning the sheet can't be protected. I suspect this is a permissions issue but I am a complete newbie in google scripting, so I am asking for some help here. Is there any way to make sure that no matter who presses the button, the assigned script is ran as owner?
thank you

You cannot have a button which the user at the keyboard clicks invoke a script which runs as the owner. See the doc about authorization here. That said, what you can do is have the button set a value or update a record which a script on a time based trigger checks. A flow like this would work well:
User updates the working sheet
User clicks the I am done! button
Script adds a row to a hidden sheet called Things for scripts to do which indicates that as of now, the working sheet should be archived
Every hour, a script checks Things for scripts to do and updates sheets and permissions as described above

Related

onChange Function not triggering when sheet is changed by another script

I have a app script Web App with a calendar, the calendar gets it's data from a master spreadsheet. A user can click on the item (on the calendar) to change the data: such as date, time, what they did, what happened, etc. These changes gets submitted to a "dump" spreadsheet, and then those changes are supposed to get copied over to the master spreadsheet.
The issue is, when the web app form is submitted, the dump sheet is being changed by a script. This causes the onChange trigger on the dumpSheet to NOT run, and in turn the submitted data is not being copied over to the master sheet.
How can I work around this issue? I could do a Time driven trigger to submit the changes, but then the issue is that the user would have to wait to see his changes in the web app calendar. And I would be running the function unnecessarily, wasting my app script quota.

How to run a Google Apps Script in a read-only spreadsheet?

I'm new to the world of Google Apps Script, and I found myself faced with a problem. I've created a script that runs as an onOpen() trigger, but if the spreadsheet file is read-only, this script does not run. I read that, being read-only, it is not able to run it. Is there a way to remedy this problem?
I gave the permissions in edit, blocking all the cells from scripts. I wish people can not see the script, as this allows them to re-run the script and take "power" on the sheet. If I create an API can I keep the sheet read-only?
Any suggestions?
All scripts must run under someone's authority. Under whose authority, a script is run determines whose data is accessible to the script and whether such authority can run the script.
Authorization Concepts:
Scripts which are run from the script editor run under the authorization of user at the keyboard¹. Custom functions runs anonymously. Installable triggers runs under the user created the trigger. WebApps run as per the options selected during deployment.
Simple triggers fire automatically and anonymously under these restrictions²:
The script must be bound to a Google Sheets, Slides, Docs, or Forms file, or else be an add-on that extends one of those applications.They do not run if a file is opened in read-only (view or comment) mode.They cannot access services that require authorization.
Installable triggers must be set up and run under the user who set up the trigger³.
They do not run if a file is opened in read-only (view or comment) mode.Installable triggers always run under the account of the person who created them.A given account cannot see triggers installed from a second account, even though the first account can still activate those triggers.
You can restrict access to spreadsheet, sheets or ranges⁴,⁵.
Deductions:
Mr.A(Owner) has a spreadsheet. The spreadsheet has two sheets 1.Main Sheet and 2. Secret Sheet(Sheet is protected and hidden to be edited only by Mr.A). It also has the following scripts: 1. A simple trigger script(onEdit) to set timestamp as a note in every cell that is edited. 2. A installed trigger (AonEdit()) to send email from MrA's email on every edit. 3. A function(summary()) to create a summary of Main Sheet and send email from user's account to himself(to run manually from script editor). 4. A function to protect the secret sheet(protect()) 5. A simple onOpen() trigger logging Someone opened your sheet. And He gives edit access to Mr.B(a editor). What can Mr.B do?
Mr.B edits cell A1 in Main Sheet:
Simple trigger onEdit is fired anonymously and a timestamp is set on A1 as a note.
Installable trigger AonEdit is fired under Mr.A's authority and a email is sent from Mr.A's gmail.This is not known to Mr.B,though he can see the script itself.
Mr.B,being a cunning person as he is, unhides the secret sheet successfully and attempts to modify it:
Mr.B could not modify the secret sheet,even though he can fully unhide/view it
Mr.B finds the script editor and tries to run the function summary(). This function needs gmail permission. Mr.B is greeted with authorization[¹] for Mr.B's gmail account,so that the function may run. Mr.B grants authorization and the summary is sent from Mr.B's gmail account.
Mr.B cunningly modifies the protect() function to grant himself edit access to the secret sheet. The user at the keyboard is Mr.B. Mr.B's authority is not enough. He's greeted with the following error:
You are trying to edit/remove a protected cell or object. Please contact the spreadsheet owner to remove protection if you need to edit.
Mr.A (Owner) knows about this unauthorized access attempt by Mr.B, He restricts edit access to All sheets. Now, Mr.B even though has permission to edit the spreadsheet, He cannot edit any sheet in the spreadsheet. Whenever he opens the sheet, the simple onOpen() is triggered logging Someone opened your sheet. Mr.B however can run the function summary() even now(If he has the script editor link) to get the summary of the sheet.
Solutions:
as this allows them to re-run the script and take "power" on the sheet.
A user with write permission can enter the script and modify the permissions.
As explained above, That wont be possible. The sheet/range edit permission is maintained even at the script level. However, A potential loop-hole is the AonEdit() function. If Mr.B were to know that Mr.A had set up a installable trigger for AonEdit() function, He can modify the AonEdit() function to say protection.remove(),which will run under Mr.A's authority(Installable triggers run under the person who created it) and thus the protection is removed.
I wish people can not see the script.
You can use a standalone script⁶. You can also use installable triggers[³] with standalone scripts subject to the restrictions of those triggers(such as It'll only run under your authority). Since the script is not bound to the spreadsheet, Editors on the spreadsheet do not have edit/view permission on the script. Alternatively, You can publish a addon⁷/webapp⁸.

How to make new sheet in google spreadsheet selected?

My script adds new sheet on a spreadsheet after some form submission. This sheet is used as a leaderboard. But to look on it I have to click on the new created tab. Is it any way to do it from script?
This picture is a screenshot after new sheet creation (Week 1 Lesson 2).
P.S.
I found that I have to reformulate the question. The problem is that I want to do it from another spreadsheet (this spreadsheet has onSubmit trigger and create and place info on other open spreadsheet (leaderboard). I check the setActiveSheet(sheet). It works only with the spreadsheet that runs the script. So I have to send some signal to leaderboard to activate sheet. But I can't understand how to do that
Straight from the developers guide
setActiveSheet(sheet)
As far as I know, there is no way to use Apps Script to change the active sheet on another open spreadsheet not running the script.
You could install a time-based trigger that ran every minute in the leaderboard sheet that checked for a new entry and then changed the active sheet as needed. This isn't instant but would take at most 60 seconds to update.

Spreadsheet event trigger on Google Apps script doesn't fire when the sheet is edited by another script

I wrote a small script bound to a Google spreadsheet that reads an email-address from a cell in the last row and sends an email to it.
The values are collected by a WebApp (not by Google form).
I tried all kind of triggers. The time driven triggers work, but the spreadsheet triggers don't work. I tried all of them. If I change manually some cell in the spreadsheet the onEdit trigger is working, but it doesn't fire up when the sheet was changed by another script.
Google's dev says : The onEdit() trigger runs automatically when a user changes the value of any cell in a spreadsheet. but it doesn't precise the change could be from script or not.
You'll find here a comment from HDCerberus :
I'm not at my PC to write a full response, but at a glance it could be the OnEdit trigger, which ONLY works when the sheet is edited manually, and NOT by a script. Are you expecting it to run when the sheet is edited manually or by a script?
Not every change triggers onEdit(). Please take a look on answer from topic Detect user inserting row or column in a google spreadsheet and reacting in a script - you will find registered bugs and one of them says that values written by scripts do not trigger onEdit().

Script triggered onEdit runs into permissions error when trying to edit protected sheet

I have a problem with a Google script for a spreadsheet. I have a script installed onEdit through the Resources menu. The script copies some cells from an unprotected sheet to a protected sheet. The script works fine when I'm logged in to my account (I'm the owner of the spreadsheet), but runs into permission errors when run from a collaborator's account who has no access to the protected sheet. Shouldn't the script run as me (the account owner) and not run into permission issues?
Another script in the same spreadsheet that runs onFormSubmit is able to edit a protected sheet when a collaborator submits a form, even though he has no access to the protected sheet. This suggests the problem is not with permissions per se, but that the problem is specific to the onEdit trigger, right?
This is expected behavior. The onEdit trigger is one of three 'simple triggers'.
From the docs:
"These simple triggers run in response to actions in Google Spreadsheets, and they run as the active user. For example, if Bob opens the Spreadsheet, then the onOpen function runs as Bob, irrespective of who added the script to the Spreadsheet. For this reason, the simple triggers are restricted in what they are permitted to do:
They cannot execute when the Spreadsheet is opened in read-only mode.
They cannot determine the current user.
They cannot access any services that require authentication as that
user. For example, the Google Translate service is anonymous and can
be accessed by the simple triggers. Google Calendar, Gmail, and Sites
are not anonymous and the simple triggers cannot access those
services.
They can only modify the current Spreadsheet. Access to other
Spreadsheets is forbidden.
Have to use installed trigger for it to work