Script to name form response spreadsheet based on form title in Google Drive - forms

I need a script to be able to create the form response spreadsheet of a Google Form and name that Spreadsheet the same as the Form + (Responses) at the end of the name. I have no idea how to do this. I am guessing it has to do with the script below, but the script does not understand that "Title" is the same as a "Name". (I do not know how to append the "(Responses)" part at the end either.) Any help would be appreciated.
function myFunction() {
var form = FormApp.openById('FORM ID HERE').getTitle();
var ss = SpreadsheetApp.create(form);
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
}

I found the answer and also how to apply it to many forms in a folder. The answer is below.
function myFunction() {
var files = DriveApp.getFolderById("0B6Eeub3cEBoobnpxWXdjSWxJRm8").getFiles()
while (files.hasNext()) {
var file = files.next();
var form = FormApp.openById(file.getId());
var formName = DriveApp.getFileById(file.getId()).getName();
var ss = SpreadsheetApp.create(formName + ' (Responses)');
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
}
}

Related

Google Apps Script_populate multiple templates depending on google form data and then email pdf copies

Help greatly needed.
Using Google Form to gather data, in order to populate one of 2 Google doc templates, dependent on whether option 1 or 2 is chosen in the Google form. Populated template to be saved in "final" folder as a PDF, and then emailed to the email address submitted in the Google form.
Currently, I'm able to generate the correct PDF files in the correct folder and send the email to the correct address, but there is no attachment and just the words [Object object].
Before I included the if/else function, I was able to correctly send the email with attachment, which means that I've caused a problem with the if/else and naming of the generated pdfs. I just can't figure it out.
function autoFillGoogleDocFromForm(e) {
//form values
var timestamp = e.values[0];
var firstName = e.values[1];
var lastName = e.values[2];
var email = e.values[3];
var multiplechoice = e.values[4];
if (multiplechoice == "Template 1") {
//This section will complete template 1
var file = DriveApp.getFileById("Template 1 ID");
//Create copy of Template 1
var folder = DriveApp.getFolderById("Templates folder ID")
var copy = file.makeCopy(lastName + ',' + firstName, folder);
//Open copy of Template 1 and replace key fields per form data
var doc = DocumentApp.openById(copy.getId());
var body = doc.getBody();
body.replaceText('{{First Name}}', firstName);
body.replaceText('{{Last Name}}', lastName);
doc.saveAndClose();
Utilities.sleep(1500);
} else {
//This section will complete Template 2 by default
var file = DriveApp.getFileById("Template 2 ID");
//Create copy of Template 2
var folder = DriveApp.getFolderById("Templates folder ID")
var copy = file.makeCopy(lastName + ',' + firstName, folder);
//Open copy of Template 2 and replace key fields per form data
var doc = DocumentApp.openById(copy.getId());
var body = doc.getBody();
body.replaceText('{{First Name}}', firstName);
body.replaceText('{{Last Name}}', lastName);
doc.saveAndClose();
Utilities.sleep(1500);
}
//create pdf copy of completed template either 1 or 2 depending on IF
var pdffolder = DriveApp.getFolderById("Templates folder ID");
var pdfFILE = DriveApp.getFileById(copy.getId()).getAs('application/pdf');
pdfFILE.setName(copy.getName() + ".pdf");
var theFolder = pdffolder;
var theFile = DriveApp.createFile(pdfFILE);
theFolder.addFile(theFile);
Utilities.sleep(1500);
var subject = "File attached";
var attach = theFile;
var pdfattach = attach.getAs(MimeType.PDF);
MailApp.sendEmail(email, subject, {attachments: [pdfattach]});
}
There are two signatures of MailApp that support attachments:
sendEmail(message)
and
sendEmail(recipient, subject, body, options)
There isn't a sendEmail(recipient, subject, options) method signature.
Include a body argument:
MailApp.sendEmail(email, subject, "☢☣☢",{attachments: [pdfattach]});

How to run script if a google sheets cell contains email?

I'm looking for help to send an email whenever a new row is added by a google form entry if said entry contains an email in the Email column. I'm new to Javascript, but I've pieced together some code which I plan to run off an onEdit trigger in GSheets.
My problem is that if there is no email address, the code will fail. I need to know how to wrap this in an "if/else" or maybe just a simple error handling bit would be fine, not sure.
If I go with an "if/else", I'll need to check if the email column contains a value. I don't need to check if it is a valid email; the google form already does this on submission.
Here is the code I have right now:
function MessageNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Message Board"));
//
//extracts the values in last row and stores them into a two-dimensional
array called data
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var dataRange = sheet.getRange(lastRow,3,1,8);
var data = dataRange.getValues();
//
//pull column elements into a one-dimensional array called rowData
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[2];
var poster = rowData[7];
var subject = rowData[3];
var recipName = rowData[6];
var comment = rowData[4];
var replyLink = rowData[5];
//
//
var message = 'Dear ' + recipName + ',\n\n'+poster+' has posted the
following comment directed to you: '+'\n'+comment+'\n\n'+'To reply to this
comment click: '+replyLink;
var subject = subject;
MailApp.sendEmail(emailAddress, subject, message);
}
}
thanks in advance for any help you can give me.
Thank you tehhowch for the help. I'm new at this so I'll have to continue researching the link you referred to regarding iteration best practice. However I was able to get this working with a simple 'if' wrapper, which turned out to be simpler than I thought.
I did find out that form submission does not recognize an active sheet, so manually testing my code worked, while form submission did not trigger it.
After some looking, I replaced:
var ss = SpreadsheetApp.getActiveSpreadsheet();
with this:
var ssID = '//insert spreadsheet id here';
var ss = SpreadsheetApp.openById(ssID);
This still did not work, so I had to kickstart it by deleting the trigger and putting it back in (found this info: On form submit trigger not working)
This may not be the most efficient code, but here is what I have now, and it does work:
function MessageNotification() {
var ssID = '//insert spreadsheet id here';
var ss = SpreadsheetApp.openById(ssID);
ss.setActiveSheet(ss.getSheetByName("Message Board"));
//extracts the values in last row and stores them into a two-dimensional
array called data
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var dataRange = sheet.getRange(lastRow,3,1,8);
var data = dataRange.getValues();
//
//pull column elements into a one-dimensional array called rowData
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[2];
var poster = rowData[7];
var subject = rowData[3];
var recipName = rowData[6];
var comment = rowData[4];
var replyLink = rowData[5];
//
//
var message = 'Dear ' + recipName + ',\n\n'+poster+' has posted the
following comment directed to you: '+'\n'+comment+'\n\n'+'To reply to this
comment click: '+replyLink;
var subject = subject;
if(emailAddress)
{
MailApp.sendEmail(emailAddress, subject, message);}
}
}
As mentioned in the question comments, you want to use the event object available to the on form submit trigger. This can be accessed from a container-bound script on either the form or its responses spreadsheet, simply by adding a parameter to the function that receives the trigger.
This object is of the form:
e: {
authMode: <enum>,
namedValues: {
'q1title': [ <q1string> ],
'q2title': [ <q2string> ],
...
},
range: <Range>,
triggerUid: <string>,
values: [<q1string>, <q2string>, ...]
}
Using this object means that accessing of the Spreadsheet, for the purposes of emailing someone based on contents of the form, is unnecessary.
function MessageNotification(e) {
if(!e) return; // No form event object was provided.
var responses = e.namedValues;
var emailQTitle = /* the title of the question that asks for the email */;
// Check that 1) this question exists in the response object, and also
// 2) it has an answer with a value that 3) is "truthy".
// https://developer.mozilla.org/en-US/docs/Glossary/Truthy
if(responses[emailQTitle] // 1
&& responses[emailQTitle].length // 2
&& responses[emailQTitle][0]) // 3
{
var emailAddress = responses[emailQTitle][0];
/* access the responses variable in a similar manner
for the other variables needed to construct the email */
MailApp.sendEmail(emailAddress, ... );
} else {
/* There was no response to the email question. */
// You can use View->Stackdriver Logging to inspect the form response, for
// example, to make sure that it had the format or values you expected.
console.log({form_object: e, responses: responses, emailTitle: emailQTitle});
}
}

How to read the data from Excel sheet and print the result on console while working on protractor

I am working on AngularJs application testing framework where I am using Protractor. I want to read the data (urls, usernames, passwords) from an excel sheet. I am using the following code but it's showing me errors.
Please find the below code:
var Excel = require('exceljs');
var wrkbook = new Excel.Workbook();
wrkbook.xlsx.readFile('E:\\Login_Data.xlsx').then(function()
{
var worksheet = wrkbook.getWorksheet('Sheet1');
worksheet.eachRow(function (Row, Test_URL)
{
console.log("Row " + Test_URL + " = " + JSON.stringify(Row.User_Name));
});
});
The data from excel sheet is :
Test_URL User_Name Password
http://...com abc#1111 xyz#333
Please let me know your positive inputs so that I can run my code and proceed forward.
Thanks in advance
eachRow isn't getting the Test_URL variable that you set as function parameter; that is instead the row index.
For getting every value of the row, you can use Row.values, and also you could the value of each Cell (corresponding to that row) with .getCell.
So it should be something like this:
var Excel = require('exceljs');
var wrkbook = new Excel.Workbook();
wrkbook.xlsx.readFile('E:\\Login_Data.xlsx').then(function()
{
var worksheet = wrkbook.getWorksheet('Sheet1');
worksheet.eachRow(function (Row, rowIndex)
{
var test_url = Row.getCell(1).value;
var user_name = Row.getCell(2).value;
var password = Row.getCell(3).value;
// do whatever you want with those variables.
});
});

change output file encoding in a google-script with DriveApp.createFile?

Let's explain the context of my request : I'm trying to output the content of a google spreadsheet in a .txt tabulated file, encoded in UTF-16, because I need this charset in a later task with this .txt file.
Actually, I've got the right output in the right folder and with the name I want ect ... but the charset is UTF-8 (i've check with an basic text editor).
The problem is I can't find any documentation about charset manipulation with google script. My only solution for now, is a basic manual charset manipulation in sublim text ...
Here's my code (translated from french).
Thank's for your replies !
Maxime
function export() {
//sheet manipulation part
//Get the sheet and set data range i need
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getDataRange();
var values = sheet.getRange(2, 1, sheet.getLastRow()-1, sheet.getLastColumn()).getValues();
var text = values.map(function (a) {return a.join('\t');}).join('\n');
//Path setting and export part
// Get sheet info, define path and create file
var id = SpreadsheetApp.getActiveSpreadsheet().getId();
var idString = id.toString();
var thisFile = DriveApp.getFileById(idString);
var parentFold = thisFile.getParents();
var folder = parentFold.next();
var theId = folder.getId();
var targetFolder = DriveApp.getFolderById(theId);
targetFolder.createFile('liste du ' + new Date() + '.txt', text, MimeType.PLAIN_TEXT);
}
This helped me:
var string = 'your text here';
var blob = Utilities.newBlob('').setDataFromString(string, "UTF-16");
blob.setName('your_file_name.txt');
var file = DriveApp.createFile(blob);
As a result createFile method will use UTF-16.
This has already been answered in this SO post:
Utilities.newBlob("").setDataFromString("foo", "UTF-8").getDataAsString("UTF-16")

Google Script - Move new submissions to another sheet based on the responses

I'm trying to create a script that will take a new form response and move it to another sheet based on the information submitted. For example, let's say the form has two answer choices A, B. The spreadsheet has three sheets; Form Responses, Sheet A, Sheet B. If someone submits the form and selects A, I need that new row to be moved from "Form Responses" to "Sheet A." I found someone else's script that does exactly this but using the OnEdit function. I cannot figure out how to modify this script to work when a new form response is submitted.
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Form Responses" && r.getColumn() == 2 && r.getValue() == "A") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Sheet A");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I used the installable triggers and replaced the OnEdit function with onFormSubmit but that doesn't work. I'd really appreciate it if anyone could help me with this.
Thanks,
To achieve what you want, you will need to:
Create a function write_to_new_sheet that we'll use in a trigger function whenever a new response hits the form. This function will take the form response as an event object e:
function write_to_new_sheet(e){
let responses = e.response.getItemResponses()
let new_row = get_new_response_data_as_row(responses)
let sheet_to_write = SpreadsheetApp.openById('your spreadsheet id').getSheetByName('sheet A') // or 'sheet B', you can set this dynamically by checking the new_row, corresponding to the response as a gsheet row
write_values_in_first_row(sheet_to_write, new_row)
}
this are the auxiliary functions to write_to_new_sheet:
function get_new_response_data_as_row(responses){
let new_row = []
responses.forEach(response => {
new_row.push(response.getResponse())
})
return new_row
}
function write_values_in_first_row(sheet, new_row_values){
let row_to_write_from = 2 // assuming you have a header
let sheet_with_new_row = sheet.insertRowBefore(row_to_write_from)
let number_of_rows = 1
let number_of_columns = new_row_values.length
let range = sheet_with_new_row.getRange(row_to_write_from, 1, number_of_rows, number_of_columns)
let results =range.setValues([new_row_values])
return new_row_values
}
Set up an installable trigger that works whenever you submit a new response to the form:
function setup_write_to_new_sheet_on_form_submit(){
ScriptApp.newTrigger('write_to_new_sheet')
.forForm('your form id goes here')
.onFormSubmit()
.create();
}
Run the above function once, to set up the trigger.
try submitting a new response on the form, and check the changes in the sheets you want it to be written.
Try something a little less broad in your comparing of variables,, For instance the sheet that submissions are sent to is a constant and already address.
function formSubmission() {
var s = SpreadsheetApp.getActiveSheet();
var data = range.getValues(); // range is a constant that always contains the submitted answers
var numCol = range.getLastColumn();
var row = s.getActiveRow;
var targetinfo = s.getRange(row,(Yourcolumn#here).getValue);
if(targetinfo() == "Desired Sheet Name") {
var targetSheet = ss.getSheetByName("Sheet A");
var targetrow = targetSheet.getLastrow()+1);
var Targetcol = numCol();
targetSheet.getRange(targetrow,1,1,Targetcol).setValues(data);
}
}
I didn't test that but hopefully it helps look up Event Objects in the developer guide i just recently found it and it clarifies a lot
the triggers can be set by going to:
then set it:
I have a spreadsheet that collects the form submissions and then has extra sheets that have filtered out these submission based on the answers. All this is just with formulas. Could that do the trick also?