We have a Google Apps domain. The domain has a sheet with a Google Apps Script add-on. We have to share this sheet with people outside our organisation. The add-on is used to refresh the data displayed in the spreadsheet.
When someone who isn't logged in opens the shared link, the add-on is not available for them. Is there a way to get around this?
You will not be able to get around the restriction that requires the user to be logged in.
Your add-on modifies spreadsheet contents on behalf of the user.
That operation requires authorization from the user.
Only logged-in users can grant authorization.
Reference: Develop Add-ons for Google Sheets, Docs, and Forms - Authorization
A separate web service that ran as you, say, and was accessible to "Everyone, including anonymous", could modify a spreadsheet without requiring a user to be logged in. You could not make this part of the Sheets UI, though.
Related
Context:
I have a service account that updates a Google Sheet on a daily basis and I want to add functionalities to the Sheet by extending it with Apps Script. I developed the script with my own personal account (same I used to create the service account) and it seems I can't access the service-account information when it's making changes to the Spreadsheet. What I mean is that I set up a trigger for changes on the spreadsheet but when I try to verify who made the changes I get a blank string.
Quoting the docs:
The circumstances in which the email address is available vary: for example, the user's email address is not available in any context that allows a script to run without that user's authorization, like a simple onOpen(e) or onEdit(e) trigger, a custom function in Google Sheets
How do I fix this? Is there a different design I should use?
Service accounts are not real users, this can be noted in this documentation. Please note the following:
Service accounts do not belong to your Google Workspace domain, unlike user accounts. If you share Google Workspace assets, like docs or events, with your entire Google Workspace domain, they are not shared with service accounts. Similarly, Google Workspace assets created by a service account are not created in your Google Workspace domain. As a result, your Google Workspace and Cloud Identity admins can't own or manage these assets.
Service accounts do not have passwords, and cannot log in via browsers or cookies.
The triggers that are setup on your script would require them to be logged in to the browser in order to capture the email address, a service account can't do that so that would be the reason why you are unable to gather this information.
In a GAS published as webapp bound to a spreadsheet in a public (free) Gmail account, I'm compiling information from many unrelated users into that spreadsheet, where any Gmail user account can access the webapp.
But when script is run as the user, the user can access the app (after user grants permissions to the app), but it stops at point where script accesses the spreadsheet. The user is told to request access. I have to "share" the spreadsheet to the user for the app to function when run as that user, but that is problematic--too many potential users.
If another version of the script is run instead under my account, then user has access to the webapp, but the script cannot access the user's Gmail address. Big problem because the webapp must have the user's Gmail address for security/application access controls.
(The webapp is in development and Google "approval" has not yet been sought.)
How do I have a webapp (a) that modifies content in a central spreadsheet, (b) that any Gmail user can access, (c) where the script has access to Session.getActiveUser().getEmail(), and (d) the user does not need to have edit permissions for that central spreadsheet? The only user-account information that the script needs is the user Gmail address--again for application access control and security. (Since Google provides me a link that gives anyone full access to the spreadsheet (if they also have its URL), can't I give the bound script access to the spreadsheet when run under any Gmail account, where the integrity of the spreadsheet content is managed through the app's functions and internal access controls?)
If there is no solution except to run the webapp under the user's Gmail account and give that user edit rights to the spreadsheet, would that create significant risk (where I don't intentionally/overtly disclose the spreadsheet's URL) that a user could access and alter the spreadsheet beyond the insert/edit functions performed by the webapp? If that risk is low, is there a function I could use in the webapp to automatically grant spreadsheet edit rights to a Gmail account when its Gmail address is pre-registered in the user list for the webapp?
Thank you!
Let me start with c): there is no way to make that Session.getActiveUser().getEmail() works for free Google accounts (i.e. gmail.com accounts) other than for the container / script owner.
Regarding a) b) and d) you might use the Google Sheets API making the calls to it by using UrlFetch Service and a service account instead of the Spreadsheet Service or the Advanced Sheets Service.
Regarding allowing anyone to edit a central spreadsheet, once they open it either by using the Google Sheets apps or by means a web app, they will be able to find the spreadsheet in Google Drive > Shared with me among other places... IMHO the risk in terms of how likely is to have issues is big but in terms of the the impact depends on several factors, i.e. some changes might be reverted by using the version history but spreadsheet might become corrupted. If you have not used Google Sheets version history intensively the best is to get deeply familiar with it before relying on it as a backup / disaster recovery main tool .
From https://developers.google.com/apps-script/reference/base/session#getactiveuser
getActiveUser()
Gets information about the current user. If security policies do not allow access to the user's identity, User.getEmail() returns a blank string. The circumstances in which the email address is available vary: for example, the user's email address is not available in any context that allows a script to run without that user's authorization, like a simple onOpen(e) or onEdit(e) trigger, a custom function in Google Sheets, or a web app deployed to "execute as me" (that is, authorized by the developer instead of the user). However, these restrictions generally do not apply if the developer runs the script themselves or belongs to the same Google Workspace domain as the user.
Related
Use Apps Script URLFetchApp to access Google Datastore Data
Google Service Accounts / API - I keep getting the Error: Access not granted or expired. (line 454, file "Service")
I have a script associated with a spreadsheet which requests Authorization. When granted and I look at the Permissions associated with my account the script has the following:
Has some account access, including Google Docs
Google Docs
View and manage your documents in Google Drive
View and manage your spreadsheets in Google Drive
Additional access
View and manage your forms in Google Drive
I am surprised it is going to this level as all the function calls I am seeing are either getting an active item or getting the sheet by name (not the file, a tab inside the file). Outside of an HTML service form, there is nothing I see which should call a Google Form item. Nor do I see anything about a Doc. Just Spreadsheet items.
Is there any way to determine where the various authorized access items are IN the code without trial and error?
I've built an add-on for Google spreadsheets. Its a simple chat that runs in Sidebar, it uses CacheService (public cache) for storing messages. It works great for collaborators, but it doesnt show up for not logged-in users. Actually, even a custom Menu item doesnt show up. It is still in development and is not published, it is bound to the Spreadsheet. So is it possible to run it without user signing in?
Not an official answer, but i highly doubt this will be available.
I assume you have the spreadsheet shared as 'public with anonymous write'.
Apps scripts have quotas and they are deducted from the active user. If there is no active user i doubt google will allow that.
There are other ways to let anonymous usera runs scripts, like a gas service published to run as the owner (not active user) but those are for web apps and not for addons or code that runs inside the spreadsheet (menus triggers etc)
You might be able to find what you're looking for here
https://developers.google.com/apps-script/add-ons/lifecycle
We have a number of Google Apps users, each of them has a non-public spreadsheet named 'XData' in their GDrive account. The Google Apps admin needs to be able to do the following:
Click one button that would collect specified data from users' spreadsheets and put it into a master spreadsheet on admin's account.
Click another button that would display the data from master spreadsheet to admin in a nice visual way.
What's the best way to implement such setup using Google tools (Fusion Tables and/or Admin SDK and/or Apps Script and/or Drive SDK and/or Spreadsheets API and/or etc)? The first step is optional if the second one can be accomplished without it.
1 and #2 can be done easily with apps script only if all the spreadsheets are shared with the script owner.
If they are not shared you can only do it with drive api and user delegation of permissions (see the drive api docs)