Long time learner/lurker, first time poster:
Howdy folks-
I've deployed a web-app that runs as the user (not me). It creates a form and a linked-spreadsheet in the
users drive with "anyone" access and "edit" permissions.
Bound to this spreadsheet is an installable "onOpen" trigger that creates a UI menu item to the right of the
spreadsheet's "help" menu, and on that menu item is a function that manipulates the data in the spreadsheet.
That all works properly -for the user who created the form+spreadsheet.
Here's my problem:
The use-case for my web-app is to allow someone to create the form and spreadsheet then hand it off to
someone to use the form and view responses and tally votes via the spreadsheet.
Because the spreadsheet's access is "anyone", the person to whom the spreadsheet is handed-off can EDIT
the spreadsheet, but the "onOpen" trigger never fires unless and until the opening-user signs in.
Then, the next problem:
Assuming the handed-off person signs in and sees the new UI menu item, they cannot successfully RUN the
function on the menu. It appears only the user that originally created the form+spreadsheet is the one
who can run the funtion from the UI (addMenu) menu.
Questions:
what's the best/recommended way to detect a user is not signed-in ..so I can present a modal alert
when the spreadsheet is first opened? The goal is to alert the user that if they signed-in, they would
see the menu item by activating the installable trigger.
Can a modal alert be presented when a user is not signed-in? I'm not sure how that code would be triggered
too, as it's likely the same problem as not triggering the onOpen UI-addMenu code
what's the best/recommended way to set the permissions for the spreadsheet's (embedded) menu-function -so
the user opening the spreadsheet can run it vs. only the original creator of the spreadsheet.
web-app example: https://forms.fattm.org/contest-form-creator
(several forms can be created, but the problem described above relates only to the form
named: CONTEST BALLOT (Item 1179) ..so you can un-check the others before hitting submit)
Thanks for your time/thoughts/help!
Welcome to SO!. The script you have that creates a custom menu using onOpen is a container-bound one, bound to the spreadsheet you are sharing. However the onOpen function is a trigger function which must be installed first (for each user that wants to use it) There is no way to get around this, unless you publish an add on, in which case the users would still have to install the add on the sheet you are providing.
Related
Is there a way to check OAuth permissions from the onOpen() simple trigger in apps script?
My app creates and shares spreadsheets with my users, and when they open the spreadsheet, I need to be able to check if they've authorized the required scopes yet. Simple triggers can't natively run functions that require authorized scopes. But installable triggers can. I've created a function that will prompt the user for permissions and then install the needed triggers with those scopes. I have a custom menu item that runs this function just fine, but the simple onOpen() trigger can't run that function because it requests OAuth scopes permissions. Many of our users wont realize they need to run that function from the menu for the spreadsheet to work.
My initial idea was to have a hidden cell somewhere in the spreadsheet with a true/false value that starts as "false". When the user opens the spreadsheet, the onOpen() simple trigger:
checks that cell's value
if it's false then pops up a ui alert for the user.
The alert tells them to use a custom menu that onOpen() added which will run a function that will:
prompt the user for permissions
add onOpen and onEdit installable triggers for that user so the rest
of my app works for that user when they interact with the
spreadsheet.
change the hidden cell's value to "true" so that the simple onOpen()
trigger doesn't keep prompting the user.
This works great! But only for the first user who accesses the spreadsheet. Once they authorize the permissions, that hidden cell turns to "true" and subsequent users wont be prompted to run the menu function.
My second idea was instead of having that hidden cell as a true/false value, make it a list of the user's gmail accounts that have given permissions (accessed via Session.getActiveUser().getEmail()). But in order to get the current user's email, I need a OAuth scope! So the simple onOpen() trigger cannot even check if the current user is a new user or not...
Is there another way to check if the active user has authorized the OAuth scopes needed from the simple onOpen() trigger?
I don't want to just rely on my users to know that they have to run that special menu function in order for things to work.
You can use ScriptApp.getAuthorizationInfo()
if (ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL).getAuthorizationStatus() == ScriptApp.AuthorizationStatus.NOT_REQUIRED) {
// user has authorized the OAuth scopes
}
I created a sheet in my personal drive with scripts that used a modal dialog popup. Everything worked great. Granted permissions. I move the sheet into a new G suite shared drive. Regranted permissions to myself. Now, everyone that logs in with the G Suite account can do everything and it works. Using my outside account (the sheet is shared outside the G Suite), I can do almost everything, but I get
Execution failed: You do not have permission to call showModalDialog
With my outside account from the G Suite, am I now no longer allowed or able or can even grant that permission? Is there something else somewhere I need to do?
Unless someone else has a better answer, I believe that the permissions for the UI to come from an onEdit (or even a triggered onSpecialEdit) will not allow a modalshowdialog....except for the person to created the onSpecialEdit trigger based on onEdit.
Since onEdit are less intentional for the user, the types of functions that send emails or popUp on the screen with information is not allowed, except the one single person who created the script trigger.
To get around this, I needed to create and insert a graphic image to be a button. Assigned a script to the button. The script pulled a value off a hidden cell to determine which cell the action should be taken on (a column of data validation check boxes that I originally wanted to trigger), and then pass that value to the script with the UI.
That works, but just not as clean and simple as checking a box and seeing the results.
I have a Google spreadsheet with a function: appendComment that is attached to the onEdit installable trigger for the sheet.
Permissions for the sheet are set to both link sharing (anyone with link has edit permission) and specific users with edit access.
setting up:
I have a menu item added in the onOpen trigger which starts the script permission process, giving permission for the scripts to run for that user. It is a simple MsgBox call inside a function called getAuthorization. To initiate authorization for the scripts in the sheet, the user selects the only item from the "SCG" menu, which initiates the process.
the problem:
After authorizing the script, I make the trigger fire by clicking on a checkbox in a cell on the sheet (the appendComment function only operates when I click in that column), I get a permissions error that looks like this:
You do not have permission to call prompt (line 30, file "")
This is infuriating... can't find this problem and its resolution anywhere.
Both Browser.inputBox and ui.prompt cause the same error.
Here is a simple reproduction of the problem in a google-sheet for anyone who wants to take a look:
https://docs.google.com/spreadsheets/d/1WxVTulbqT8dtUlHEf_TW_Jaus5a1GSfXnjgdoWYhrls/edit?usp=sharing
Any help is appreciated!
To achieve the result I was going for... controlled comments history with easy comment entry by users on a sheet... I did away with the prompt boxes and just used the adjacent cell instead.
Ended up putting my function in the onEdit trigger.
No box neededed, no permission issues, works even better than with the checkbox.
I made some script with my spreadsheet, which uses some Trigger and SendEmail functionalities. I have menu items in spreadsheet to control these triggers and sendemails.
Now when I share this spreadsheet with someone other, when he tried to access the trigger or sendemail functions from menu, the script asks for authorization as that user. IF authorized it will function as that user. e.g. send email as that user or make a new trigger as that user. This makes things double and useless
I want that any user accessing the script can use those functionalities, but won't require authorization to run as that user. The script should run as the creator of the sheet, so that no double triggering occurs. How should I do it?
You could create a web-app. Web-apps have the ability to run either as the user himself, or as the developer/publisher.
Under Execute the app as, select whose authorization the app should
run with: your account (the developer's) or the account of the user
who visits the app (see permissions).
https://developers.google.com/apps-script/guides/web
This web-app wouldn't have a sheet linked to it, but if you only use 1 sheet you can have the web-app access the sheet through the ID of the sheet. You could use your existing menu-items to trigger the webapp
Would this be a possible solution for your problem?
How do I create a script that runs as soon as the user opens a spreadsheet?
Specifically I need a script that when the spreadsheet is opened asks the name and sex of the user, and depending on the gender it adds the name to a different sheet of the spreadsheet.
This is simple but I've gone through the tutorials on their webpage and couldn't do it. I know how to program but I am new to Google Apps Scripts.
Also is this something done better in Google Forms or in Google Sheets?
How do I create a script that runs as soon as the user opens a spreadsheet?
An onOpen() trigger function.
Specifically I need a script that when the spreadsheet is opened asks the name and sex of the user, and depending on the gender it adds the name to a different sheet of the spreadsheet.
The onOpen() should call a function that uses Browser.inputBox() to get the user's input, then writes it to the sheet via Range.setValues().
Note that the user will need to have edit privileges for this to work.
Also is this something done better in google forms or in google spreadsheets?
If you want the UI to show up in a spreadsheet, then the script must be contained in a spreadsheet.
Alternatively, if you don't want the user to see the spreadsheet, you could use the Forms service to collect their input, with no need for any programming.
Nothing too hard to get that :
read this doc on how to build an alert in a spreadsheet and make it show up using an installable trigger onOpen
all you have to do is put these together.
For script lauched at opening you need write function:
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
...
};
Google Spreadsheet don't have a dialog window or something similar.
But there are several ways:
You can use show method to show your html or UiApp input dialogbox: https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#show(Object)
you can use one sheet for input "sex" and hide others sheets. After click button you can show all sheets. Here is SpreadSheet API: https://developers.google.com/apps-script/reference/spreadsheet/
you can use information from profile logged person and read his/her sex :)
you can use Form for input "sex" and switch context (by script) to spreadsheet but this is more complex solution. Here is Form API: https://developers.google.com/apps-script/reference/forms/
Yea, I forget about inputBox() :)
To create a script that runs as soon as the user open the spreadsheet, you should create a bounded to a spreadsheet script and use a trigger:
Create a new or open an existing spreadsheet.
Click on Tools > Script editor...
Click the close button on the welcome dialog.
Start writing your script
To make the script run on open, you could use a simple trigger by using onOpen as the function name or you could use an installable trigger.
For further details see https://developers.google.com/apps-script/guides/sheets