Google Forms + Cloud Function Integration - google-apps-script

Image with Error:
Hi,
I am trying to build an OnSubmit Function with google forms. I have attached the picture of the error. As far as I understand, the gs script isn't able to read the property "response" from "event". I have clearly followed the Google Apps Script documentation. Can you tell me where I'm going wrong?

I would need a little more information in order to more accurately help. If you could specify why you are setting a trigger/ what it is that you want to do then I can hopefully help a little more.
However I can try to help from the little bit that I can see from your picture...
step 1 to solving your problem: Have you implemented a trigger? All I see is that you created a function called "onSubmit". Unfortunately with google script, that doesn't do anything to actually tell the servers when to run the function. For that you would need to set a trigger. I would highly recommend that you create the code through the responses google sheet and not through the form itself. That is because if you wish to use the information from the form response, then using the google spreadsheet makes it significantly easier to retrieve the information, especially if you are familiar with arrays. This is a short video of me doing the process of setting a trigger and showing you the results. The only thing I have redacted is my email.
Regardless of whether you decide to implement the code on the spreadsheet or the form, the steps for adding a trigger are the same.
What you want to do is go to your code. Click "edit" -> Click "Current Project's Triggers" -> click "Add trigger" -> and for "Select event type you want to select "On Form Submit"
The reason I specifically put "on form submit" is because that was my understanding of your problem. By selecting that it runs your selected function whenever the form is submitted.
Hope this helps. If you need further clarification, please let me know.

Related

How to avoid saving a google sheet and have multiple people editing at the same time?

I’ve created a Google Sheet – kind of like an app – using script. It’s a number of blank cells where once added some information, it creates a string with that information in the right order. I created this to help some colleagues. We are using free accounts.
I face 2 problems:
The app is supposed to be used by only one person at a time, but I’m sure at some point two or more people will want to use it at the same time. Is there a way to allow this without they interfering with each other? I’ve read you can share a link that creates copies of your doc, but that wouldn’t work in this case because I intend to keep updating it regularly.
The changes people make to the sheet will stay there. Right now I have a onOpen function that just rewrites everything, but if someone accesses the document while someone is using it they’ll rewrite everything and ruin their work.
Any ideas on how to solve these two problems? Thank you so much in advance!
I think that you have to find another way to implement your "app" because Google Sheets not a good tool for limiting that only one user edit a spreadsheet a time, but if for any reason you decide to keep with it,...
... you need to implement a workflow like the following
Save the active user email on PropertiesService.getUserProperties().
This should be done by each user by running a script themselves. The most user-friendly will be by using a macro, custom menu or button (a drawing with an assigned Google Apps Script function). You might use an open installable trigger to validate that the active user have already done this.
You might have to make the function that clears the data a "smart" function.
You might have to consider additional cases, like if the owner of the spreadsheet opens it when there is an editor working on the spreadsheet.
Use installable triggers to manage the sharing settings.
Use an open trigger to remove all the editors except the active user
Use a time-driven trigger to add again the editors. To make this work effectively should define how the time-driven trigger will know that the last editor have finished their session, i.e. you might use DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).getLastUpdated()
The above should help you with both problems, as long you as the owner do not open the spreadsheet as is used by someone else.
Other alternatives that might work better is to create an add-on or a web application.
Related
Determine current user in Apps Script
Last modified date in Google App Script GAS sheets

"Authorisation is required to perform that action" for alert/popup, Google Apps Script add-on for Spreadsheets

I am building an Google Apps Script add-on for Google Spreadsheets.
In the manifest I have explicitly requested the following scopes:
"https://www.googleapis.com/auth/script.container.ui",
"https://www.googleapis.com/auth/spreadsheets"
Also the "OAuth consent screen" within my Google Cloud project has the same scopes and these are already verified by Google.
Nevertheless it is not possible for me to give feedback to my users in case of a wrong input. I have tried the following:
SpreadsheetApp.getActiveSpreadsheet().show(htmlApp);
SpreadsheetApp.getActiveSpreadsheet().toast(message);
SpreadsheetApp.getUi().alert('Wrong input.');
SpreadsheetApp.getUi().showSidebar(html);
Browser.msgBox('Wrong input.');
Nothings seems to work, I always see the error "Authorisation is required to perform that action" within the stackdriver logs.
What would work is to create an "error sheet" and log all input errors into it, or to make one cell within the main sheet to an "error cell" and log all input errors into it. I think this is not a good solution in terms of user experience.
It seems that this problem has something to do with the authMode: https://developers.google.com/gsuite/add-ons/concepts/editor-auth-lifecycle#authorization_modes
Because "Access to user interface" is only possible within "FULL" authMode, which is not the case during onEdit().
The strange thing is, that other add-ons are able to show an alert/popup. Is this a hack? Or do I need more scopes? Or do I have to change anything else?
EDIT 08.10.2019:
#Jacques-Guzel Heron:
For instance: the user inputs a date in cell A1 and another in cell B1. Within the onEdit(e) trigger I want to check if the date in B1 is after the date in A1, if not I want to alert the user. All the above listed methods lead to the error "Authorisation is required to perform that action", when the app is published. When the app is not published .toast(), .alert() and .msgBox() work within my test environment. The strange thing is, that these methods then create a DIV-element, whereas the other add-ons create an IFRAME-element for their alert/dialog-box. Therefore I think they use another method and it has nothing to do with scopes. In addiation I had a look during the OAuth verification process of these add-ons and the scopes are listed within the dev-tools. They do not use any special "ui-scope", so I doubt the cause for this error is scope related.
EDIT 09.10.2019:
Now I know how an alert/dialog-box containing of an IFRAME-element can be made. To do this, these methods can be used:
var htmlString, msg, htmlOutput;
htmlString = '<p>my html string</p>';
msg = 'my message';
htmlOutput = HtmlService
.createHtmlOutput(htmlString)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setHeight(140);
SpreadsheetApp
.getUi()
.showModalDialog(htmlOutput, msg);
But it is also not possible to call this method during onEdit(e).
All the above listed methods can be called, through clicking on the menu items and also through clicking on buttons within the sidebar, but not during onEdit(e).
In addition I have added all the scopes which other add-ons are using, but in vain. So again my assumption got confirmed that the problem is not scope related.
I have the impression that some smart people have managed to find an inofficial workaroung, please let me know :)
You are right on all your approach. And yes, this is intended behavior as documented on authorization modes.
Those add-ons use custom menus to use a formula that checks the cell after being called pressing a button.
On that documentation you can find information to develop your alert. Please describe what you are trying to accomplish so I can help you better, otherwise ask me for more clarification without hesitating.
The solution are installable triggers: https://developers.google.com/apps-script/guides/triggers/installable
They are running in FULL authMode and therefore are allowed to access the user interface: https://developers.google.com/gsuite/add-ons/concepts/editor-auth-lifecycle#authorization_modes

Google Apps Script, calling function once when document is copied

I have been playing around with Google Script Editor and I've gotten heaps of use out of it.
The next task that I am looking at is automatic formatting and text insertion/replacement when copying a Template.
An example use case is as follows: Within my organisation I have submitted a Doc to the template gallery. When creating a copy of the template I want it to automatically insert today's date and the current time (rounded to the nearest hour).
This is a question about the Triggers. The text replacement bit is easy and done. Not to mention this is just one of the basic use cases, I'll be attempting many more similar behaviours with things like timesheets and the like.
The problem that I am running into is that I can't seem to get the triggers to work as I'd like them to.
2 of the Triggers that I thought I could try and use: onOpen(e) and onInstall(e).
onOpen(e), though it works, it works "too well". That is, it also replaces the text on the original template as well, proving a nuisance when updating info in these templates.
onInstall(e), I thought this would work as creating a copy of the Doc also "installs" the script as well. However this function doesn't seem to run at all.
Any ideas about getting a trigger to happen once and only once when a Doc is created from a template?
Cheers,
Bricktron
First of all, Trigger onInstall(e) works only for Add-ons.
Now coming to onOpen(e), in my opinion you can use Google Apps Script Property's Services to store one flag which helps your code identifying whether this file has been opened or not.
So for very first time onOpen(e) runs, assign property eg: propertyService.setProperty("opened","TRUE") and next time you can check by accessing the property whether it has been already "opened" or not.
Example:
var openedFlag=propertyService.getProperty("opened");
if(openedFlag=="TRUE"){
//Document has been modified
//Do not run the modifiable code again
}else {
//First time
//Edit the file
//Set the propertyService to "TRUE"
}

Google script - Submit form response without having authorization to edit form

I have created a script for collaborators, to be used in google sheets.
When they trigger the script, it submits a form response, that then gets used to modify a "central" spread sheet.
But I am faced with a permission problem, and I haven't managed to find a convenient answer to it on the net.
The script uses FormApp.openById([...]).createResponse().[....].submit().
The problem comes from the fact both openById() and openByUrl() need the person who runs the script to be able to edit the form.
(As said on the Class FormApp help page : Returns the Form with the specified URL. Throws an exception if the URL is invalid or the user does not have permission to open the form.)
I have so far found 2 workarounds :
Give edit access for the form to my collaborators : it then shares them a form they shouldn't edit.
Change the link-sharing of the form to "on" : although no one but me actually knows the form Id, I don't really like the possibility of anyone discovering the link to be able to edit the form.
Neither of these workarounds completely satisfies me, and I'm sure there must be a way to submit a response via a script without being able to edit the form - just as people who send answers to google forms can't generally edit the questions ! Just I can't figure out how.
Any help on this problem will be very much appreciated !
Thank you,
Mike
Create a Web App using an account with owner or editor access to the form and set it to be run as the script owner. For a general guide see https://developers.google.com/apps-script/guides/web

Does an on form submit trigger from a script attached to the form (not the spreadsheet) trigger when a form response is edited?

I have a spreadsheet that writes a calendar event when the form is submitted. As you know, when the form response is edited using the response url, on form submit triggers are not triggered.
https://code.google.com/p/google-apps-script-issues/issues/detail?id=2969#c12
indicates that if the script is attached to the form, then it will trigger.
I took the script that was working in the spreadsheet, and transplanted it to the form, and it works with new forms, but still not with edited responses.
So the main question is whether it triggers when the response is edited or not?
If the answer to the above is 'yes' then the related questions are:
Am I correct to assume I need to change the coding of the script to work with FormResponse objects (e.response) rather than the spreadsheet returns?
Can I still set the trigger manually using the Resource menu or do I have to set it programmatically now?
(If the answer is no, then I will be drawing upon Send email when Google Form submission is updated to accomplish the same thing within the spreadsheet...but would prefer to avoid the added complexity of a script that I don't fully understand)
Thanks
You can figure out whether some code ran by using a Logger.log() statement:
Logger.log("It ran!");
And then checking to see if anything printed to the log. Choose the VIEW menu, and then the LOG item from within the code editor.
You've already tried triggering the code from both the spreadsheet and the form, so just add a Logger.log() statement to determine if the code is running or not.
If you try using that code from the other answer, and run into a problem, just determine which line of code is giving the error, and post a question. If there is an error executing the code, there will be an error msg in the EXECUTION TRANSCRIPT. That's under the VIEW menu. Post what the error msg is, and what line of code the error is from.
If there is no error, but the results aren't what you want, then post the results compared to what you want.