Google Apps Script - communication between script - google-apps-script

HiMy problem is following: I would like to create small web page, on which it will be possible to create event in Google Calendar, but with some restrictions. In my case this calendar could be edited by my flatmates to reserve washing machine. This reservation cannot overlap and also all of us has limited number of days when we can use it. I have created private calendar, and I have created script which validate requests, and if everything is ok add event to calendar. This script is executed as me (because only I have permission to edit this calendar).
But I have problem with fetching information which user execute this script (me or one of my flatmate). Class Session contains 2 methods getActiveUser() and getEffectiveUser() but active user does not work (I guess because privacy protection policy). But if I create another script which is executed as user accessing the web I can get active user.
Does anybody know if is it possible to communicate somehow between this 2 scripts embedeed on the same site? I want to pass email of active user from one script to another. Or maybe do you know better solution how to solve this problem?
Regards
Adam

As you noticed, you need to set the script to run as the user accessing it to get his email. Then, instead of accessing the calendar directly (which you obviously can't) you can call another script published, but running as yourself allowing anonymous access that will receive this request from the "viewing" script and create the calendar events for it.
After you publish this "background" script, get its url and use it on a UrlfetchApp.fetch call to it. Then pass the parameters as url paremeters (or on payload if you prefer to use post instead of get).
The background script may even use ContentService to give nice return values to the calling script.

Sure, you can do so, but it's not as simple as you'd like. Make your admin level script run a web service that responds to the other script. It can probably be hacked as you can't authenticate the users, but comon, this is a washing macine!

Related

Limit Spreadsheet Access to Scripts

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.

the getActiveUser method within a company domain

I am attempting to call Session.getActiveUser in order to auto-fill certain fields in a Google Sheets document when other fields are edited. All users are in the same domain; however, I receive an error message, "You do not have permission to call getActiveUser." I was under the impression from existing documentation that users within the same domain can access one another's information through custom scripts - is this incorrect? If so, I know that there are several workarounds, but if not, is there something else I could be doing wrong?
Thanks in advance!
"user3889423" is correct, you need Authorization of the user, in order to call the getActiveUser().
You can find this information in this link below:
https://developers.google.com/apps-script/guides/sheets/functions#advanced
The link in KRR's answer contains the information you need. Here's the excerpt answering you question:
You definitely cannot call Session.getActiveUser() without user authorization, even for users within the same domain:
If your custom function throws the error message You do not have permission to call X service., the service requires user authorization and thus cannot be used in a custom function.
However, even with user authorization, you still cannot use Session.getActiveUser() in custom functions (directly in cells). You need to create a custom menu instead:
To use a service other than those listed above, create a custom menu that runs an Apps Script function instead of writing a custom function. A function that is triggered from a menu will ask the user for authorization if necessary and can consequently use all Apps Script services.
If that script runs without the explicit authorization of the user, you won't be able to get the ActiveUser (I think). It should work though when a user authorizes the script first.

Google Apps Script - Always allow app to run

I wrote a script in GSheets we use at my work that uses custom menus. Because everyone is set to "Can view" on the template, they are forced to make a copy as to not affect the template.
The downside of that is each spreadsheet will require authorization to run every single time the form is sent in and the menus need to be used which makes the process more cumbersome. Is there a way I can provide authorization to run the code, whether it be through an onOpen trigger or some other means?
The code includes moving sheets into folders, extracting data to a central spreadsheet, and sending emails. The email does not need to come from the user, it can be sent as a no-reply/anonymous user if that helps.

Make spreadsheet only editable through script

I have a script which adds new rows and changes the sheet in some ways.
I'd like to lock this sheet so it cannot be edited manually, but allow the script to be run.
Is there a way to do this?
Yes, it's not the most easier thing to do, but it's possible.
But before we start it's important to understand how Google spreadsheet/sheet protection works.
There's no way to protect a sheet or range from the file owner. So, if you also want to protect a file from yourself (assuming you're the owner). Then the only solution available now (I do hope they change this in the future) is to change the ownership of the file to another account. What most people do is use another Google account that they don't use actively (you can create a bogus easily if you don't already have one).
Then, after you have transferred the file to another account, you can easily lock changes to ranges, sheets or the whole spreadsheet using the regular GUI.
Ok, now to the script. When a script runs, it's always using the authorization of a specific account, and it can do everything that this account can. For example, when someone runs a script directly from the script editor, or clicking on a custom menu or image: it runs under the account of who's clicking. But if you set a installable trigger, then the script always runs under the account of who setup the trigger in the first place (not who's performing the action that actually triggers it). Simple event triggers run as who's triggering the action (you can think anonymously), but they can't do much, it's a security feature (read the link for a better understanding).
Lastly, when one is publishing a script as a web-app, then there's a selection box to choose if the script runs as the developer or the user. Very simple.
Back to the problem. Since we have locked out everybody from the desired sheet/range. For a script to make changes to this locked area, it must run as the file owner!
If the changes you do are automatic, e.g. via a installable trigger, then you're good. Just setup the trigger using the file owner account and that's it. Also, if your users are accessing the script "externally", that is, via a web-app. Then that's easy to, just setup the web-app to run as the developer (the file owner).
The most complicated scenario is if you need to run the script from a custom menu, which will then run under the privileges of who's clicking on it, which themselves can not make changes to the protected area. The solution to this is to deploy the script as web-app running as the developer, and have the function running from the button click to call the deployed url using UrlFetch, possibly passing some parameters to designate what needs to be done. Then, since the webapp runs as the developer (which is the file owner), it can make any changes required, and return (if there's something to return) any value (usually a JSON) to the calling function (which is running as the user and is associated with his session), so you can show him a message on a popup or toaster, etc.
It's kind of tricky but works great, and you can do all that on the same script contained in the spreadsheet. But if you're concerned that your users may access the script editor and change the code (which is possible), than you should separate the web-app part on a different file, that you don't need to share with them.
Yes but only for others not for the script owner. Just use 2 accounts one as the owner and the other one as the reader.

Clarification on Active User Scope and Script Authorization

I have a spreadsheet with a UI app script. The app reads/updates from the spreadsheet.
My current settings are: Execute the app as "me".
Who has access to the app: "anyone".
I'm essentially sending out workflows that have assignments by email. Those emails can be outside of the domain but would all be gmail addresses.
I had hoped I'd be able to access the Session.getActiveUser() as I need to allow certain functionality on the app based on user accessing the UiApp. That function does not seem to provide any info unless I'm logged in as the script owner. Session.getActiveUser() is blank when accessing from a different address.
Is there a way to get the active user without having to Execute the app as "User accessing the app". I'd rather not have to share the spreadsheet with all the end users.
Thanks for any suggestions.
Rewrite from comments for readability :
Sharing the spreadsheet in this context doesn't mean anybody could open the spreadsheet directly as a document as long as the url of the spreadsheet remains unknown. The app will indeed need to have access to it if you deploy your app as 'User accessing the webapp' but no one can find the url of the sheet unless you publish it. I use this configuration very often but of course I don't know your exact use case... ;-) In my case the app itself determines what a specific user can do or not (by enabling /disabling certain functions / panels depending on the logged user.
Here is an example of an app like this, can you find the source spreadsheet ?
My spreadsheet has "anyone with the link" so the app can read and write to it but the name of the spreadsheet and its url is unknown (except for me) so it never appears in the document list of the user even if the user "writes" something in the document through the webapp (since he never actually "opens" it). I checked that on different accounts and never found any exception.
The active user and the property's like email etc.. Are not accessible with a public google account. It is accessible and useable with a google apps account within your own domain. See http://www.google.com/intl/en/enterprise/apps/business/pricing.html
Otherwise it's just a point of privacy on the web.
A litle disappointing i can imagine but logical if you think about it.
I do have another tip for you. Have al look at this link http://shop.oreilly.com/product/0636920023210.do
O'reilly also implemented a workflowsystem. It uses the url parameters to pass email (identity) information. Not really secure, but in combination with the Utilities.DigestAlgorithm SHA encoding you could take steps to encode your url email-parameters.
Hope this is helpfull.