Sending Google Forms responses to specified e-mail address on Submit - google-apps-script

I am trying to setup Google Form in a way that once Form Submiter hits "Submit" button the responses are not only populated in dedicated spreadsheet but also sent via e-mail to particular mailing group
Probably the best way would be to use Google Scripts and Triggers, including "onsubmit", "Mailapp.sendmail" functions but my struggles here are:
a) to get the responses directly from just submitted form
b) to change "send from" e-mail address (that would send an e-mail to mailing group) to submiter's e-mail
c) connect the form responses with mailapp.sendmail function
I have tried something like this but it holds the issues mentioned above:
function OnSubmit(e) { var formResponses =
FormApp.getActiveForm().getResponses();
Logger.log(formResponses.length);
var formResponse = formResponses[formResponses.length-1];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
Logger.log('Last response to the question "%s" was "%s"',
itemResponse.getItem().getTitle(),
itemResponse.getResponse());
MailApp.sendEmail ("email#mydoiman.com", "Form Submited " + Date.now(),
FormApp.getActiveForm().getResponses());
}}
I really appreciate all your help! Because I am total amateur in this one.

a) to get answer in an email you can do that :
function sendAnswers(e) {
var items = e.response.getItemResponses();
var emailRespondent = e.response.getRespondentEmail();
var html = "";
for(var i = 0; i< items.length; i++) {
var item = items[i];
html += "<b>"+item.getItem().getTitle()+"</b> : "+ item.getResponse() + "<br>";
}
MailApp.sendEmail("EMAIL_RECIPIENT", "Form answers", "", {htmlBody:html})
}
b) it is not possible to change the 'To' of email.
c) Yes we use the MailApp function.
=> do not forget to create a trigger to have the function run on onFormSubmit.
=> in emailRespondent you have email of person that submit the form if you click to collect email of respondent. if you don't do that comment the line i.e.
// var emailRespondent = e.response.getRespondentEmail();
Stéphane

Related

How can I send a completed Google Form to a user when I submit the form?

I have created a Google Form for my Elem. School Principal for Teacher Observations. She would like to be able to send the completed form to the teacher when she submits the form.
my idea is to somehow add a textbox for the Email address at the end of the form, and when email address is filled, click Submit which will process the form, and send a copy to the recipient email address. I am tryingo to do this via Google's Script editor, but I am not versed in JavaScript. Any help would be appreciated.
If you want to send the filled form to the address of whoever filled it, you can use the "Collect email addresses" and "response receipts" functions.
However, if you want to send the email to other users based on a form input field you can use something like this:
function onFormSubmit(e) {
var form = e.source;
var response = e.response.getItemResponses();
var targetEmail = response[response.length].getResponse(); //Gets response for last question
var htmlResponse = HtmlOutput.createHtmlOutput("<h1>Form Submission:</h1>");
var questions = form.getItems();
for (var i=0; i<questions.length; i++) {
var answerOfQuestion = response[i].getResponse();
if (typeof(answerOfQuestion)=="object") {
var tempAnswer = "<ul>";
for (var j = 0; j<answerOfQuestion.length; j++) {
tempAnswer += "<li>"+answerOfQuestion[j].toString()+"</li>";
}
tempAnswer += "</ul>";
answerOfQuestion = tempAnswer;
}
htmlResponse.append("<p><b>"+questions[i].getTitle()+":</b> "+answerOfQuestion+"</p>");
}
GmailApp.createDraft(targetEmail, 'Form Submission', 'Here is the form results:' + htmlResponse.getContent() , {
htmlBody: htmlResponse.getContent(),
}).send();
}
Go to Settings (the gear icon) > General Tab
Select both "collect email addresses" and "response receipts"
No additional coding necessary.

Getting Contents of Google form on Email after a user submits a google form

I want to get the contents of the google form sent to my email rather than just a notification that a new user has submitted the form. I put in the following code. But I get a response saying that namedValues is undefined. I tried actually submitting a dummy google form, but it still doesn't send me the contents of the google form on email.
function sendFormByEmail (e) {
var email = "example#gmail.com";
var Name = e.values[3];
var EmailAddress = e.values[4];
var txt = "";
for(var field in e.namedValues) {
txt += field + ' :: ' + e.namedValues[field].toString() + "\n\n";
}
MailApp.sendEmail(email, "New Client", txt);
}
If the script is attached to the form and triggered when that form is submitted, use the response object with that event. AFAIK the namedValues object you are trying to access is only available if your script is attached to the spreadsheet that recieves the form input.
I use this script when I want to quickly send a simple form submission to an email address (and not use the addons that can do this and more):
function onFormSubmit_sendEmail(e) {
var msgBody = "";
var itemResponses = e.response.getItemResponses();
for (var i = 0; i < itemResponses.length; i++) {
var itemResponse = itemResponses[i];
msgBody = msgBody + itemResponse.getItem().getTitle() + ": " + itemResponse.getResponse() + "\n\n";
}
MailApp.sendEmail("someemail#somedomain", "Form Submission", msgBody);
}
}
You can use some tests on the item title (getTitle() method) to do different things depending on the question - e.g. if one question is where you want the email sent to, do something like:
if (itemResponse.getItem().getTitle() == "Recipient Address") {
var email = itemResponse.getResponse();
You could then use that MailApp.sendMail() function. Hope this helps.

Generate unique Form URL for each respondent

I have a Google Form With a Google spreadsheet to store responses. In my spread sheet I have 4 columns: name, email, revenue, and a fourth column, Id, which is used to identify the particular recipient.
What I am trying to accomplish is to generate a unique URL for each respondent so that they can respond to the form and use the same URL to edit the form at a later time.
I've looked at the getEditUrl() (Google Apps Script) method which creates a unique URL for the respondent after submitting the response-- code below:
function myFunction() {
assignEditUrls();
}
function assignEditUrls() {
var form = FormApp.openById('1vsqvwomoqSXwF6TlNkmmktAAk2av2r-2LRrBYJdv3VQ');
//enter form ID here
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses');
//Change the sheet name as appropriate
var data = sheet.getDataRange().getValues();
var urlCol = 5; // column number where URL's should be populated; A = 1, B = 2 etc
var responses = form.getResponses();
var timestamps = [], urls = [], resultUrls = [];
for (var i = 0; i < responses.length; i++) {
var resp = responses[i];
timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
urls.push(shortenUrl(responses[i].getEditResponseUrl()));
withItemResponse(responses[i])
}
for (var j = 1; j < data.length; j++) {
var dop = data[j][0]
resultUrls.push([data[j][0]?urls[timestamps.indexOf(data[j][0].setMilliseconds(0))]: '']);
}
sheet.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);
}
function shortenUrl(longUrl) {
// google url shortener api key
var key = "AIzaSyBVG4Q5i1mNI0YAO0XVGZ3suZU8etTvK34";
var serviceUrl="https://www.googleapis.com/urlshortener/v1/url?key="+key;
var options={
muteHttpExceptions:true,
method:"post",
contentType: "application/json",
payload : JSON.stringify({'longUrl': longUrl })
};
var response=UrlFetchApp.fetch(serviceUrl, options);
if(response.getResponseCode() == 200) {
var content = JSON.parse(response.getContentText());
if ( (content != null) && (content["id"] != null) )
return content["id"];
}
return longUrl;
}
However I want to do it the other way which is to first generate the unique URL to be then sent to respondents so they can submit and edit their responses without the need of sending them another URL (e.g. the editurlresponse).
Is this possible to do?
Originally posted to https://webapps.stackexchange.com/a/86399/88163
Yes, it's possible, but with slight different approach:
Submit one answer for each respondent in order to get one edit URL by each of them, then send the corresponding URL to each respondent.
Below is a code snippet that programmatically submits a response and log some response attributes including the edit response url by through two code lines, the first one has an issue, the second one is a workaround. Please note that these lines use getEditResponseUrl() not the toPrefilledUrl().
It will work as a stand alone or as a bounded script.
/*
This code shows how to get the edit response url of a
programmatically submitted response to a Google Form
*/
// Replace the form ID by your own form
var formID = '1234567890abcdefghijklmnopqrstuvwxyz';
function myFunction() {
var form = FormApp.openById(formID);
var response = form.createResponse();
var items = form.getItems();
var item = items[0];
if (item.getType() == 'TEXT') {
var textItem = item.asTextItem();
var itemResponse = textItem.createResponse('my text');
response.withItemResponse(itemResponse);
}
// Submit response
var submittedResponse = response.submit();
// Get submitted response attributes
var values = {
ID : submittedResponse.getId(),
TS : submittedResponse.getTimestamp(),
/*
Issue 4476: FormApp: getEditResponseUrl() produces invalid URL
https://code.google.com/p/google-apps-script-issues/issues/detail?id=4476
*/
ER1 : submittedResponse.getEditResponseUrl(),
/* Workaround from
https://code.google.com/p/google-apps-script-issues/issues/detail?id=4476#c2
*/
ER2 : submittedResponse.getEditResponseUrl().replace(
/\?edit2=.*/,"?edit2=" + submittedResponse.getId()
)
};
Logger.log(values);
}
References
Class FormResponse - Google Apps Script Reference
Issue 4476: FormApp: getEditResponseUrl() produces invalid URL

Using a script to edit data from a form submission

It appears the data submitted to a Google Form is saved not just in the associated spreadsheet, but also in the Form itself I have an HTML interface that displays the data to internal staff in a Non-Profits account. Some of this data may change or may not be known at the time of submission. Other information is saved in additional fields in the associated spreadsheet. I can add and edit that data, but is it possible to edit the data in the form file as well?
It is possible to get the data saved as a response in the form itself, and you can submit new responses programmatically. I don't think you can alter existing responses with Google Apps Script. See https://developers.google.com/apps-script/reference/forms
// Open a form by ID and log the responses to each question.
var form = FormApp.openById('1234567890abcdefghijklmnopqrstuvwxyz');
var formResponses = form.getResponses();
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
Logger.log('Response #%s to the question "%s" was "%s"',
(i + 1).toString(),
itemResponse.getItem().getTitle(),
itemResponse.getResponse());
}
}

Get the current response onSubmit

Is there any way to find out the current response of the Google Form (programmatically)?
In the onSubmit function.
Looked over their documentation but I have to provide the respondId.
How do I find the respondId?
A snipped code from them about this is:
// Open a form by ID and log the responses to each question.
var form = FormApp.openById('1234567890abcdefghijklmnopqrstuvwxyz');
var formResponses = form.getResponses();
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
Logger.log('Response #%s to the question "%s" was "%s"',
(i + 1).toString(),
itemResponse.getItem().getTitle(),
itemResponse.getResponse());
}
}
UPDATE:
function onSubmit(e) {
/* Get values entered by filling the form */
var itemResponses = e.response.getItemResponses();
var myWantedValue = itemResponses[COLUMN_NUMBER].getResponse();
}
Note: By passing the e(vent) as parameter the values can be accessed by submitting the live form, NOT by the script editor!
This code gives you the values for the last form response, is that what you're looking for ?
function myFunction() {
var formResponses = FormApp.getActiveForm().getResponses();
Logger.log(formResponses.length);
var formResponse = formResponses[formResponses.length-1];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
Logger.log('Last response to the question "%s" was "%s"',
itemResponse.getItem().getTitle(),
itemResponse.getResponse());
}
}
You are trying to read the exact response that triggered the execution of onSubmit(), to run another process on particular data, such as sending a confirmation email.
If the above is correct:
Instead of using the form as a data source for your later processing, try to read the Google Sheet storing the responses. It may seem the problem is the same: reading either data source (the form itself, or the sheet storing the data), doesn't point you to the exact entry that has triggered the onSubmit() event.
The difference is that in a sheet you can create a "reply_sent" column, to timestamp the instant each form response has been postprocessed, for example, having sent an automated reply based on its contents.
Then, when onSubmit() is run, it goes through all responses and processes not only the last one received, or the one having triggered the onSubmit() funtion, but also any other response that may have been left unreplied for whatever reason ("reply_sent" field blank). A last benefit from this approach is that your script is logging how it is behaving, since a date is recorded along with each response as it triggers obSubmit().
You cannot set up a custom confirmation message for each user.