Google Forms is a great tool--easy to create, easy to use, etc. I was recently at a meetup talking to users about Google Cloud Platform and someone said they wished they could hook a Google Form up to a Google Cloud Function.
After thinking for a second, I thought "this must be possible". Although there's not usually a lot of direct interoperability between G Suite and Google Cloud, I knew that you could write an Apps Script trigger for most Google Docs, which would let you make HTTP requests, and that Cloud Functions can accept arbitrary HTTP requests as events, so there's no reason this shouldn't work.
And in fact, it totally works!
Writing your Cloud Function
There's really nothing special about the Cloud Function you'll create for this: it's just like any other Cloud Function that accepts a HTTP request. Let's assume we're going to be passing JSON back and forth as the payload:
The function would look something like this:
def form_trigger(request):
payload = request.get_json(silent=True)
print(f"Payload was: {payload}")
return "OK"
This will get the JSON from the POST
request, print it to our logs, and just return an "OK". Obviously you can do then whatever you want with the payload at this point: store it in your database, kick off a job, etc.
Deploy that function with gcloud functions deploy form_trigger --trigger-http --runtime python37
and move on to the next step.
Creating your Google Form
The Google Form you create will just be like any other form: you can have multi-part questions, multiple-choice questions, free-form questions, etc.
Creating a script for your form
Here's where we can start connecting the dots. First, literally select the three dots in the menu when you're editing your form:
From this menu, choose "Script editor" to get taken to the Apps Script editor for this form. This should give you a file named Code.gs
with an empty function like so:
function myFunction() {
}
We're going to update it to be something like the following:
// Replace with the URL to your deployed Cloud Function
var url = "<YOUR CLOUD FUNCTION URL>"
// This function will be called when the form is submitted
function onSubmit(event) {
// The event is a FormResponse object:
// https://developers.google.com/apps-script/reference/forms/form-response
var formResponse = event.response;
// Gets all ItemResponses contained in the form response
// https://developers.google.com/apps-script/reference/forms/form-response#getItemResponses()
var itemResponses = formResponse.getItemResponses();
// Gets the actual response strings from the array of ItemResponses
var responses = itemResponses.map(function getResponse(e) { return e.getResponse(); });
// Post the payload as JSON to our Cloud Function
UrlFetchApp.fetch(
url,
{
"method": "post",
"payload": JSON.stringify({
"responses": responses
})
};
);
}
Make sure to update the url
variable with the full URL to your deployed Cloud Function.
Adding a trigger
Now, from the script editor, click on "Edit" > "Current project's triggers" . This will prompt you to give your project a name, and then take you to the G Suite Developer Hub, and show you all the triggers for your project (there should be none).
In the bottom right corner, select "+ Add Trigger" to add a new trigger:
The dialog should default to the onSubmit
function you declared for your form, otherwise select it.
You should also be sure to change the "Select event type" field from "On open" to "On form submit".
This will create a popup window to allow Apps Script to view and modify your form.
Finally, save your trigger and it should appear in the list of triggers.
Conclusion
At this point, your form is fully connected to Cloud Functions! You can submit some test responses and you should see the responses appearing in the logs for your function.
From here, you can hook the function up to other services, or do things conditionally based on the responses, and you shouldn't need to write additional Apps Script to make it happen.
Top comments (16)
I am a complete newby trying to connect my google forms to Google Cloud for use in Firebase for a corona-response team in the Netherlands. I get an error running the first Cloud Function.
The trigger seems ok , but cannot be tested
Having the same issue
Hi Jouwert, happy to help. What's the error?
I am trying to upload screenshot but I fail ...
This is what Google Cloud gives me back:
Implementatiefout:
Function failed on loading user code. Error message: Code in file index.js can't be loaded.
Is there a syntax error in your code?
Detailed stack trace: /srv/index.js:1
(function (exports, require, module, __filename, __dirname) { def form_trigger(request):
^^^^^^^^^^^^
SyntaxError: Unexpected identifier
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:617:28)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at getUserFunction (/worker/worker.js:439:24)
The trigger script in my google form is
// Replace with the URL to your deployed Cloud Function
var url = "us-central1-inspired-rush-271907.c..."
// This function will be called when the form is submitted
function onSubmit(event) {
// The event is a FormResponse object:
// developers.google.com/apps-script/...
var formResponse = event.response;
// Gets all ItemResponses contained in the form response
// developers.google.com/apps-script/...
var itemResponses = formResponse.getItemResponses();
// Gets the actual response strings from the array of ItemResponses
var responses = itemResponses.map(function getResponse(e) { return e.getResponse(); });
// Post the payload as JSON to our Cloud Function
UrlFetchApp.fetch(
url,
{
"method": "post",
"payload": JSON.stringify({
"responses": responses
})
});
};
But maybe the Cloud Function is wrong. I was not so sure as to how to implement this script from your instruction:
def form_trigger(request):
payload = request.get_json(silent=True)
print(f"Payload was: {payload}")
return "OK"
Hi Im also having a problem after setting it up my google form and cloud function. I tested them both separately, like the trigger works completely without fail and cloud function work if executed directly cloud function dashboard i can see right away the logs however when doing an actual test to the form like submitting the form i don't get any cloud function logs.
Hi there, can you share some more details? What does your Cloud Functions and Apps Script trigger look like?
Hi Dustin, I'm just following the whole instruction you shared. But I cant catch it from the logs it seems that its not being executed when i'm submitting a form.
Perhaps a silly question, but did you make sure to update
var url = "<YOUR CLOUD FUNCTION URL>"
?ow yes and it works and it prints ok when accessing that url - us-central1-xxxxxx-csapps.cloudfun...
From the logs i can only see the image attached when I'm manually triggering it from the dashboard. See dev-to-uploads.s3.amazonaws.com/i/...
It seems that this doesn't work anymore. Confirmed that trigger doesn't execute the URL anymore.
I couldn't get it to work, for some reason the data I was receiving in Firebase Cloud Functions was malformed, I had to add the following to the fetch parameters:
contentType: "application/json"
Then, the payload could be accessed from the function directly from the body object
PS found this solution from stackoverflow.com/questions/629020...
Thanks for the post. I tried to add this functionality to a form on my own google site, and I mostly got it working; however I'm stuck on the part where you use JSON to pass things between google scripts. The google script throws an error when I include one of the semicolons that are in your script, but leaving it off results in nothing being passed to the google cloud function. I attached something that shows what I am trying to do and how I'm trying to do it. Any help debugging the JSON statement would be appreciated. Thanks!
Where you able to run it? We may have a similar issue. Do you see json data from gcp logs?
Is there a way to integrate Google Cloud functions in forms created via API?