Limit Spreadsheet Access to Scripts - google-apps-script

I'm attempting to create a poor-man's ticketing system through the use of Google Sheets and bound scripts, but I don't know of any way that I can limit interaction with the spreadsheets to the scripts attached to buttons. I want to be able to share this sheet and have other users interact via a guided process triggered by my buttons/scripts, so as to avoid corrupting/losing information on the sheet due to carelessness.
At first I thought that I could just protect the sheet ranges that I didn't want damaged and be able to give access via the scripts, but that sadly is not the case.
Ultimately the question is, how can I use scripts to access a protected range with permissions as a viewer only.

you dont want to do it that way.
easiests is to deploy as webapp running as you. they use the webapp instead of pressing buttons or menu items.
to still use buttons/menus/sidebars it is possible but with more steps. you would need to publish a contentService as webapp (anonymous) and use urlFetch into the service to make thoae changes. not secure because curious users could find that service url in code and use it for bad purposes without traceability.

Related

Turn OFF “Authorization is required” for Google Sheets Script for own team

We are a small company which just switched from paper to tablets (Surface GO Win10 Home) and we have one particular sheet which is used for every order (about 100 orders per month). This Google Sheet acts as a template for every single order and includes some easy code which is written in a bound Apps Script project, to handle things like switching the status from started to finished, copying some cells etc.
My problem is, when someone of the team wants to use the created "buttons" in the sheet to activate the script, it asks for authorization for the script the change the sheet. If you enable it, everything works fine but then for every new order you have to enable it again, and again, and it gets really annoying for every team member.
I tried somehow to
turn it off in the security options as administrator
tried it in the GOOGLE CLOUD PLATFORM under API's and services
tried to make the code somehow public in the script editor options
...but nothing seems not to work. I used VBA programs a lot in Excel VBA but it was more a hobby and I'm not a computer scientist, otherwise it would maybe be easier to solve this problem.
Is there an easy way so every one of my team can work with the sheets created out of a template without any request from Google for authorization every time.
Kind regards.
The reason for the popups is that Google Apps Script is not part of Google Sheets itself, it's a separate application that uses OAuth 2.0 to get the permissions to make the requests by calling the APIs. The popup shows the scopes you are authorizing for. This means that you can't disable that.
Note that apps script could do more things that just edit the spreadsheet itself; it could get other files, get your personal information, call external servers, etc. Also, the authentication process will only happen once per file.

Can an apps script macro in a Google sheet be used by other users?

I have a fairly simple requirement for a Google sheets apps macro script - it basically pulls the values from a couple of cells in another sheet and displays them in an alert box.
I've done the macro for this and it works fine. What I now want is for anyone I've shared the sheet with to be able to run the same macro. This is where things have suddenly got a bit more involved! My questions are:
Is this possible? And if so, what's the best way of achieveing it? At the moment, the macro is not available for the test user I've shared the sheet with. I've had a bit of a look around and it seems like publishing the script as a web app may be the way to go - can anyone confirm if that is correct? Or would there be a better option? I don't know anything about web apps so just want to confirm if this is the best option before trying to wrap my head around it all.
If the sheet in question has been shared with a user, but the second sheet which the script pulls data from has not, is it still possible for the user to run the script and retrieve the data? Or would the second sheet need to be shared with that same user as well? (If it would then it kinda defeats the object of what I'm trying to achieve).
Finally, would the user with whom the sheet is shared have to have a Google account in order to do this? I'm assuming so...which is a bit of a pain, but I guess understandable.
Thanks very much
Wokaround
Following the requirements you have described I get that you want your users to trigger an Apps Script function that will alter or get data from your Spreadsheet while only granting your users viewer-only acccess.
As described here only users with editor level access can run functions on your bounded script or activate it when clicking a button in your Spreadsheet.
To overcome this you can create a simple web app with a button that will trigger your function. Users will have to access this web app to trigger the function. The good point is that they will not have editor level access to the Spreadsheet nor to the actual script of the web app (as they will just interact with its user interface).
The web app would be a different script that can interface any of your Spreadsheets editing them or getting any information from them.

Bypass verification for GAS bound to a Sheet?

Is it possible to bypass the verification process or at least the VERY SCARY "Go to (unsafe)" in tiny letters next to "BACK TO SAFETY"?
I sometimes have a shared Google Sheet that is meant to be used by a volunteer organization (think neighborhood HOA or PTA, etc) and I add Apps Script to add menus to assist with adding or editing information on that Sheet only. I don't request any user information and I'm not using the script to access the users Drive or Gmail or other sheets.
I haven't been able to find good documentation on this, but I can't tell if the Verification requirement stems from:
The fact that there is a script running at all
Some call I'm making to an API that is sensitive (and maybe I really am getting access that I don't realize?)
Use of HTML forms
If it's the 2nd that could mean some changes could render my scripts harmless - Fyi a possible culprit is the use of SpreadsheetApp. I use that to access .getActiveSheet(), .getActiveSpreadsheet(), .getUi().showModalDialog(), .Dimension.ROWS, .getActive().getSpreadsheetTimeZone(), .getUi()
.createMenu()

Can Google Apps Scripts be flexible enough to handle multiple sheets?

Is it possible with one Google Apps Script published as a Web Application to be flexible enough to connect to different spreadsheets depending on the person or webmaster using the Application?
I saw when working with one of my scripts there are ‘script properties’ and then ‘user properties’ tabs under ‘Project properties’.
I tried to add a property but couldn't get it to Stick
So then I found Google Apps Script ‘Class Properties’ area.
When I think of how these two properties might work, I think of Google Gadgets. A user can add a gadget to her Google Site but can then change or configure the Gadget in the properties area of that gadget
Is this type of functionality possible?
You can configure settings that will allow one script to access the files of the user of the Apps Script. The user needs to log in with their Google account.
You can publish the Apps Script script to run as ANYONE, and Execute the app as: User Accessing the Web App. Which requires the user to log in with their Google Account, and will allow the script to access the users files.
The Properties Service is for storage. It doesn't set or grant permissions. A break down comparison of the different types of Properties is shown at:
Comparison of Property Stores
For the question, 'Can Google Script me modified to run differently depending on who's running it', yes.
For example, you could use the function 'getActiveUser()', and dependent on who the user was, you could set a variable such as 'thisUsersSheet == usersSpreadsheet key', among many other ways to do this.
Whether or not it would be possible to have it replaced site gadgets, that's much more dependent on what you're trying to achieve specifically.
Note: You mention 'Script properties' and 'User Properties' in your question. Stay away from these, they are deprecated.

Is it possible to have one script for multiple spreadsheets?

I have one master spreadsheet and a number of copies. This master spreadsheet uses some scripting.
Is it possible to link all the copies of this master spreadsheet to the same script as in the master spreadsheet?
Objective:
changes in the scripting in the master spreadsheet are automatically used by the copies
aka: low maintenance
amleczko is right: you should use the new library feature in Google Apps script.
However, as of today, you won't be able to do exactly what you want (using the same script for several spreadsheets). What you can do instead is save a version of your script (Files > Manage Versions...), in order to create a library. Then, import this library in the other spreadsheets (Resources > Manage Libraries...). Switch on the "development mode" so every change made do the library will immediately take affect in the spreadsheets using this library. Otherwise, you will have to save a new version of the library for every change, and manually update the version number of the library in every spreadsheets using it.
The problem is, you need to write a script in every spreadsheets using your library, with skeleton functions like this:
function doSomething(){
myLibrary.doSomething();
}
best way is to publish as add-on, then install the add-on, it will appears in every spreadsheet you open. and you can publish as private, which only seen by yourself.
I think this has changed. According to Issue 40 starting from 22 May 2012 there is such a possibility. Please check:
https://developers.google.com/apps-script/guide_libraries
https://developers.google.com/apps-script/guide_versions
http://googleappsdeveloper.blogspot.it/2012/05/introducing-versions-and-libraries-in.html
It's not possible in this way that you're thinking. At least, not yet (see issue 40).
But, depending on your script usage, you may connect them "the hard way" or even better, use only one script. The script on the master spreadsheet can open the other spreadsheet files and do its job "remotely". It's not required that script to be hosted on a spreadsheet to interact with it (read/write on it). You only need a script hosted on the spreadsheet if you're going to use spreadsheet events triggers i.e. on-open, on-edit and on-form-submit.
Maybe you can develop a nice UI for the script on the master sheet and publish it as service. Then only have a link on the copies to access the same UI on a different browser tab. Adding parameters to the link the script UI can even adapt to the particular spreadsheet that is "triggering" it.
Well, that's all I can imagine now. But, unfortunately, there's some use cases that just don't fit this nice "workarounds". For those, one can only star issue 40 (to kind of vote and keep track of updates) and hope it's developed soon.
The solution I put in place in this context was to have a Google Site, where the Master Script is embedded, and where the Spreadsheet is embedded too
Then, the script, refering to a dedicated spreadsheet, looks for the Google Site Page's name, looks in the Master spreadsheet and get the ID of the spreadsheet which is embedded in the Page.
I have solved this problem when using a script which auto generates spreadsheets.
Typically, I will add a sheet to any spreadsheet with a script called "Info." I'll use that to store information that it important to the script. In my script which auto generates more spreadsheets, I keep track of the ID of the created sheet. This way, I can then quickly call up all of the "linked" sheets, and interact with them with using the same script. It might even be worth writing the script in one sheet, and keeping it totally separate from your Master sheet or it's children.
Take a look at this function, it might give you some ideas.
SpreadsheetApp.openById(id)