Protecting Spreadsheet from renaming in Google Sheets - google-apps-script

I have Google Spreadsheet named "TeamWork" and I share it with about 50 other users, they can edit different ranges ad sheets. Problem is that when some of them want to change the name of file, they just can do it, so time to time I have funny names for this file, like "teamNotWork" etc.
Is there a way to prevent anyone except owner from rename Spreadheet? If possible not using "onEdit" script trigger, because its using quota.
Thanks for help!

onOpen wont happen often enough and onEdit will consume too much quota.
instead, use a time based trigger (every minute or every 5 minutes) to rename the file if its not what you want.
it also has the advantage that it will work regardless of how users open the sheet (mobile or desktop).

I would try using onOpen trigger:
function onOpen() {
var file = SpreadsheetApp.getActiveSpreadsheet();
file.rename('TeamWork');
}
You may add one more time Driven trigger and launch it once a day when nobody works with file.

Related

How to implement? Spreadsheet with link - Go To Link Grab Data - Update Spreadsheet Row

I am looking for technology suggestions. Or if this can be done in native google sheets (note the site I am looking to access is behind a username and password).
I have a google sheet that looks like this
birth date
link
data_element_from_website
12/31
https://something.com/3920230
1/31
https://something.com/1920238
lets say on https://something.com/3920230 there is a HTML element 123
Twice a day I want to be able to refresh the data, this could be done by going into the spreadsheet and clicking/doing something.
Can this be done?
What if https://something.com/3920230 is behind a login (authentication). Note: I could be logged in to the website in a different tab... I don't think that would make a difference though...
Assuming you have a script that you would like to run twice a day, you can use Apps Script Time-driven triggers:
A time-driven trigger (also called a clock trigger) is similar to a cron job in Unix. Time-driven triggers let scripts execute at a particular time or on a recurring interval, as frequently as every minute or as infrequently as once per month. (Note that an add-on can use a time-driven trigger once per hour at most.)
If it's just some formulae, you can change the recalculation settings to be either On change, On change and every minute or On change and every hour under the File > Spreadsheet settings menu item and clicking on the Calculation tab.
If you want to get data from public site(no login) you can use ImportXML. You can google a lot about it, for example
https://answerbun.com/personal-finance-money/get-revenue-details-in-google-sheets-using-google-finance/
If the page you want can only be accessed using login, this becomes a rather complicated task, especially using only apps script libraries (not much scraping lib support here)

Can App Script triggers stick when making copies of file?

I have a trigger on a Google Sheet set up to run a function weekly. I am hoping to scale this trigger out to my team without having to go into each teammate's individual sheet's script editor and enable it. Do you know if triggers can stick when making a copy of a master sheet that has a trigger set up? Can triggers be saved and used via shared libraries? I haven't had much success and would love some pointers if you have them.
Thanks!
Unfortunately, the answer is no. Only the owner of the google account can create triggers for himself/herself.
However, there is a great alternative. You can add this code to the master file (script editor):
function createTrigger() {
ScriptApp.newTrigger("Name_Of_The_Function_You_Want_To_Trigger")
.timeBased().onWeekDay(ScriptApp.WeekDay.MONDAY)
.atHour(7).create();
}
and when the person of your team executes this function (in his own copy of the master file), the script will create for him a particular trigger for:
Function: "Name_Of_The_Function_You_Want_To_Trigger"
type: timeBased()
Hour: 7am
When: weekly, every Monday
That saves you a lot of time, since the user (your colleague) has to run this particular function just once from his own file.

Time-Driven triggers not working properly

We're working with Spreadsheets and Apps-Script to do some automation, therefore we've set up some time based triggers, some hourly, some daily based, all set up in the apps-script dashboard. It happens more and more often, that the triggers simply don't run. They're just not executed, so I don't see any failure in the dashboard (because the code is valid, though).
I thought, it was about the .getActiveSpreadSheet() method which might not work, when the sheet is not open or visible (which it would be in the most cases), but I recently have a sheet where I open it by id (openById), and the trigger still works just as he pleases.
Simple example code is:
function testTrigger(){
var sheet = SpreadsheetApp.openById($sheetid).getSheetByName("ha")
sheet.getRange("A1").setValue(new Date());
Logger.log("test");
}
And before I used
function testTrigger(){
var sheet = SpreadsheetApp.getActiveSpreadsheet.getSheetByName("ha")
sheet.getRange("A1").setValue(new Date());
Logger.log("test");
}
The trigger for this function is set to fire every minute. As I can see in the sheet, the last time it ran was 12:35:48, but it's now 12:40. So why isn't it working?
By the time I'm writing this, it suddenly fired at 12:40:48. But now it's 12:44 again, so there are already 3 runs missing! Why does this keep happening?
And: Would SpreadsheetApp.getActiveSpreadsheet.getSheetByName("ha") even work with a closed sheet? Has the sheet to be open AND active in the browser? We were using Spreadsheets and Apps-Script for months now, I used getActiveSpreadsheet.getSheetByName("ha") every time and it worked. It seems, the time driven triggers are buggy atm, I have no other conclusion (since the code and everything else is valid).
Is there any way to find out, why a trigger didn't fire (beside a code error, which I would of course see in the dashboard).
And would these problems also occur, if I would use programmatical triggers?
Thanks in advance!
Here's an image of the problem (nothing changed in the code or in the trigger during these runs):
To answer some your questions
As specified by the documentation for time-driven triggers "The time may be slightly randomized — for example, if you create a recurring 9 a.m. trigger, Apps Script chooses a time between 9 a.m. and 10 a.m"
If instead you create manually a ClockTriggerBuilder with the parameter nearMinute(minute), this "Specifies the minute at which the trigger runs (plus or minus 15 minutes)". In other words: You cannot expect from the Apps Script triggers to run precisely at the time you would like them to.
SpreadsheetApp.getActiveSpreadsheet() works if you have a bound script, rather than an alone-standing script. In any case, to avoid error sources, it is wise to use SpreadsheetApp.openById(id) instead of SpreadsheetApp.getActiveSpreadsheet()
You can supervise your triggers und executions and My triggers, however from your description it seems like the trigger is fired correctly, just not exactly at the time you would desire.

Google script: unprotect a sheet through function when user has no right to do so

I have a spreadsheet with different sheets in Google sheet, 3 users can edit each one a sheet (protections are set, each user can edit only one sheet). They all can execute a google script function that writes what they edited in a summary sheet. I don't want anyone to be abble to edit the summary sheet, so I set myself as the only available editor.
So my problem is to authorize the 3 users, only through the google script function, to write in the summary sheet. I tried to use the following function :
var unprotected = summarySheet.getRange('G3:G10');
protection.setUnprotectedRanges([unprotected]);
but since the users are not allowed to edit the summary sheet, and since the function is run with the active user, so they can't give themselves the right to unprotect a range in the summary sheet... Do you know how to workaround this problem?
Thanks a lot!
I see two script-based choices, one easy and one quite hard, and one sheet-based choice, that is easiest:
Easy:
You run the "summarize" script instead of them or, you set the summarize script run on a trigger out of your account. Then you actually leave protections alone. You could set the summarize script to run on open with error catching if the user doesn't have the necessary authority to unprotect the summary sheet and/or write to the summary sheet.
Hard:
When they run the "summarize" script it calls a published standalone script that has been given the authorization to make the necessary protection changes. I'll be honest, I wouldn't be able to code this but have seen/heard of similar implementations.
Easiest:
Finally, I want to make sure you've considered having the summary sheet itself contain the necessary formulas, parsing, etc. to summarize data from the other sheets without any need of scripts for this aspect of the sheet. The sheet could call custom functions as needed if the parsing or other summarization functionality is beyond built-in functions' capabilities. The sheet could stay fully protected and update itself in real time as users enter data (no need for users to trigger the summary creation, unless spreadsheet settings have auto-recalculate turned off).
Edited to add: put in A1 of Summary sheet something like:
=summarize()
And have that custom function return a 2-dimensional array of the summarized data.

Google spreadsheet: Intercept calls before trigger (event) open

I have a code into a spreadsheet (A) that does a copy of a sheet from another spreadsheet (B) the is activate from a trigger onOpen.
But trigger onOpen starts after 5 or 6 seconds, so a user can do some changes into the sheet.
I would like to keep my sheet for those 10 seconds too.
Have you an idea? I'm looking how to intercept calls before trigger open but I don't find documentation.
Thanks
You can install a onEditSs edit trigger on B (dont use the simple onEdit, instead install one).
From there copy to A whenever the range changes (keep the last one copied on cache to minimize writes).
This way A is always up to date even without opening it.