Auto-direct emails to specific addresses on Google Form submit - google-apps-script

This is my first post so apologies in advance if I am posting to the wrong place or asking a question that has been answered elsewhere - go easy on me!
In a nutshell, I have a Google Form and a connected Google Sheet. I need to automate it so that, when a new form is submitted, an email is sent to a specific colleague (the student's supervisor). I have had a good go myself but am now totally stuck!
I have created the form, linked it to a sheet, written the code, added the trigger and tested by submitting a form. Nothing happened! No error messages, just... nothing!
Any advice hugely appreciated. I am very new to this and still taking baby steps.
The code I have cobbled together (which is probably full of errors!) is as follows:
function wa132657(e) {
//setup the spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//get the range from OnFormSubmit
var range = e.range;
Logger.log("DEBUG: the range is "+range.getA1Notation());//DEBUG
// get the data for the range
var response = row.getValues();
// get the supervisor name from the form submission
var supervisor = response[0][1];
Logger.log("DEBUG: Supervisor = "+supervisor);// DEBUG
// get the emails list
var emailSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SupEmails");
// get ALL the data from this sheet
var emaildata = emailSheet.getDataRange().getValues();
// check how many rows of data
var emailLastRow = emailSheet.getLastRow();
// start the loop through the emails data
for (var i=1; i<emailLastRow; i++){
// if the supervisor is equal to SupervisorEmail
if (supervisor == emaildata[i][0]){
// there is a match
//Next, get the email address
var emailSupervisor = emaildata[i][1];
Logger.log("DEBUG: supervisor = "+emaildata[i][0]+", email address: "+emailSupervisor);// DEBUG
// Finally, send the Email.
var theirName = e.values[2];
var theirProgramme = e.values[3];
var theAbsenceReason = e.values[8];
var theAbsenceStart = e.values[5];
var theAbsenceEnd = e.values[6];
var subject = "Student Absence Report";
var message = "New Absence Report: " + theirName + " \n Programme: " + theirProgramme; + " \n\n
Reason for Absence: \n" + theAbsenceReason + " \n Start of Absence" + theAbsenceStart + "\n End of Absence:" + theAbsenceEnd;
MailApp.sendEmail(emailSupervisor, subject, message);
}
}
}

Related

Is there a way to pass information to a Google Form from a link sent in an email (parameters in the URL maybe)?

I want to send an email to folks using a script that will ask them to confirm an appointment. I'd like to make it easy for them to confirm. I was thinking I could have a link go to a Google Form, but I would like that form to contain information about the appointment; I thought about putting parameters in the form URL (e.g. https://docs.google.com/forms/d/e/[formID]/viewform?location=Office1&subject=management) but I don't see a way to grab that URL in the script attached to the form (only the normal URL of the form). Any way I can get the URL with the parameters? Or is there some other way to pass information to the form? (Or, failing that, to a Google Doc or something?)
I tried using getPublishedURL but that gets the standard URL, no parameters...
Question: Is a way to pass parameter information to a Google Form from a link sent in an email.
Answer: No.
But there is a way that you can use a Google Forms link, sent in an email, that would enable a person to confirm an appointment.
In brief:
create a Google Form with three questions
Question 1 = Title: "User Details", Type: "Paragraph Text"
Question 2 = Title: "My appoitment time is", Type: "Short-answer Text"
Question 3 = Title: "Acknowledgement", Type: "List Item", one options = "yes"
create a Google spreadsheet with two sheets
sheet 1 = user details = name, email, appointment time plus two checkboxes ("ResponseCreated" and "Email sent")
sheet 2 = Form Responses - linked from the Google Form
add one additional column: "EditResponse URL"
write/run a script to create form responses using the data on sheet1
this will populate questions 1 and 2
Sheet 2(Form Responses) is automatically updated.
write/run a script to create the EditResponseUrl for the data on sheet="Form Responses"
write/run a script to send emails to the user details on Sheet1
use the EditResponseUrl from sheet 2 to create an HTML link in the email
-when each user clicks the link in their email, they are directed to a form that contains their details, and the time of their appointment.
They select "Yes" (to acknowledge the appointyment) and then Submit.
Sheet 2 is automatically updated from the form - this is your evidence of their acknowledgement.
Create Form Responses
function createResponse() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sourceSheetName = "User details"
var source = ss.getSheetByName(sourceSheetName)
// get the number of entries
var aVals = source.getRange("A2:A").getValues()
var aLast = aVals.filter(String).length
// get the data; 3 columns plus a checkbox// one row = header
var sourceRange = source.getRange(2,1,aLast,4)
//Logger.log("DEBUG: source range = "+sourceRange.getA1Notation())
var sourceValues = sourceRange.getValues()
var formUrl = ss.getFormUrl();
var form = FormApp.openByUrl(formUrl); // grabs the connected form
var questions = form.getItems();
// Getting the fields of the form questions
var userInfo = questions[0].asParagraphTextItem();
var appntInfo = questions[1].asTextItem();
var updateArray = new Array
for(i = 0; i < sourceValues.length; i++) {
if (sourceValues[i][3] == false){
var formResponse = form.createResponse();
var d1 = "Name: "+sourceValues[i][0]+"\nEmail address: "+sourceValues[i][1]
var r1 = userInfo.createResponse(d1)
var d2 = sourceValues[i][2]
var r2 = appntInfo.createResponse(d2)
formResponse.withItemResponse(r1)
formResponse.withItemResponse(r2)
formResponse.submit()
updateArray.push([true])
}
else {
updateArray.push([true])
}
}
// Logger.log("DEBUG: checkbox range = "+source.getRange(2,4,sourceValues.length).getA1Notation())
// Logger.log(updateArray) // DEBUG
source.getRange(2,4,sourceValues.length).setValues(updateArray)
}
Get EditResponseUrl
function responseURL() {
var form = FormApp.openById('10cG91VSwmIvCS8PQbJwtrQk47uWVmcH6i5pX83KsuVE')
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet = ss.getSheetByName('Form Responses 1')
var formResponses = form.getResponses()
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i]
sheet.getRange(i+2, 5).setValue(formResponse.getEditResponseUrl());
}
}
Send email
function sendEmails(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var userSheetName = "User details"
var usersheet = ss.getSheetByName(userSheetName)
var formSheetName = "Form Responses 1"
var formsheet = ss.getSheetByName(formSheetName)
// get the number of entries
var aVals = usersheet.getRange("A2:A").getValues()
var aLast = aVals.filter(String).length
// get the data; 3 columns// one row = header
var userRange = usersheet.getRange(2,1,aLast,5)
// Logger.log("DEBUG: source range = "+userRange.getA1Notation())
var userValues = userRange.getValues()
var formRange = formsheet.getRange(2,1,aLast,5)
// Logger.log("DEBUG: form range = "+formRange.getA1Notation())
var formValues = formRange.getValues()
//Logger.log(formValues)
// return
var sentArray = new Array
var emailSubject = "Request for Confirmation of Appointment"
for (var i=0;i<userValues.length;i++){
if (userValues[i][4] == false){ // test if email has already been sent
var name = userValues[i][0]
var email = userValues[i][1]
var apptTime = userValues[i][2]
var respURL = formValues[i][4]
var html_link = "<a href='"+respURL+"'> our Appointment confirmation form</a>"
//Logger.log(html_link)
var html_body = "Hello, "+ name +",<br><br>"
+ "Your appointment is at "+apptTime+". Would you please confirm your appointment by going to " + html_link + ".<br><br>"
+ "Thank you, <br>"
+ "Signature"
MailApp.sendEmail({
to: email,
subject: emailSubject,
body: "Can add a Plain Text version of the email body here for email apps that dont do html",
htmlBody: html_body
})
sentArray.push([true])
Logger.log("mail sent to "+name)
}
else{
sentArray.push([true])
}
}
usersheet.getRange(2,5,userValues.length).setValues(sentArray)
}
User Details (sheet1)
Form Responses (sheet2)
Email
Form - Confirm appointment

Sending HTML newsletter emails via google spreadsheet

I have a spreadsheet that updates daily. values in Italic are being updated daily, Bold values are static labels.
Date: 9/20/2019
Number of cars in parking lot: 105
Last entry: 09:21 AM
Last Check out: Mr.X
I have setup a script to send an email with the updates to the users via googlespreadsheet. But the email that users receive is a plain text like this:
Date:,9/20/2019,Number of cars in parking lot:,105,Last entry:,09:21 AM,Last Check out:,Mr.X,,,,,
How can I make this code to send more userfriendly email with a table or colorful fonts, etc similar to a daily newsletter?
So, given the requirement, this script would transform your sheet data into an HTML table and then send it as the message body over an email (you're free to further modify the CSS as required)
Assuming that your sheet looks something like this -
And that your desired output is something like this -
You could use the following code and make necessary changes as required -
var SheetID = "YourSheetIDGoesHere"; //replace with your Spreadsheet SheetID
var sheetName = "YourSheetNameGoesHere"; //replace with your Sheet Name
var sheet = SpreadsheetApp.openById(SheetID).getSheetByName(sheetName);
function sendUpdate() {
var range = sheet.getDataRange();
var values = range.getDisplayValues();
var weights = range.getFontWeights();
var rowDisplay = range.getLastRow();
var columnDisplay = range.getLastColumn();
var message = '';
message = message + "<table rules='all' border='3' style='border-color: #666;' cellpadding='5'>\n";
for (var i = 0; i < rowDisplay; i++ ) {
message = message + "<tr>\n";
for (var j = 0; j < columnDisplay; j++ ) {
message = message + "<td style='text-align: 'left'; font-weight: " + weights[i][j] + ";'>" + values[i][j] + "</td>\n";
} // ends the for loop for each column
message = message + "</tr>\n";
}
message = message + "</table>\n";
MailApp.sendEmail(
{
to: Session.getActiveUser().getEmail(), //this will send the email to whoever is running the script; replace it with the desired email IDs
subject: "Subject Goes Here",
htmlBody: message
}
);
}
Inspired by this article here.

GScript: Track number of emails sent using mass email Gscript code

I am trying to modify this GScript to count the number of emails sent. I would like to track the total number of emails sent using this function. Would it be easier to do it within this code or to use a code to search the sent box of the user? I believe I know how to make a count value get stored temporarily, but I am unsure how to store it for a greater period of time.
function WhiteTicket() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Email Outline');
var lastRow = sheet.getRange("J1").getValue();
var range = sheet.getRange("A3:"+ lastRow);
var UserData = range.getValues();
for (i in UserData) {
var row = UserData[i];
var firstname = row[1];
var lastname = row[2];
var email = row[3];
var whiteticket = row[6];
if (whiteticket != '0') {
var esubject = "New Tickets";
MailApp.sendEmail({
to: row[3],
subject: esubject,
htmlBody:"Hello " + firstname + "," + '<br />'+'<br />' +
"Please note that you have " + whiteticket + " ticket(s)."});
}
}
if (ok) {
EmailComplete();;
}
}
Requirement:
Record amount of emails sent by this script.
Solution:
Use GmailApp.search() and pass to length to count the amount of emails sent.
Example:
var total = GmailApp.search('in:sent subject:"'+esubject+'"').length;
Logger.log(total);
This is pretty self explanatory, it'll search all of the emails in your sent folder with subject matching the subject string you're assigning with var esubject. The script above just writes it to the log using Logger.log().

Google app script - how to count number of google form response

It is my first time writing google app script and I am desperately need help.
The purpose is to set up a workshop sign up form. Based on how many people already signed up, an email is sent out to inform if sign up was successful, or was put in the wait list.
I copied code from a tutorial. But need help to get the count of form responses. Here is how it looks like now:
function onFormSubmit(e) {
var timestamp = e.values[0];
var yourName = e.values[1];
var toAddress = e.values[2];
var subject = "Workshop Confirmation";
var emailBody = "Thank you for your submitted on " + timestamp
var num_response = COUNT_NUMBER_OF_RESPONSE // <-- need help here
var LIMIT = 15
if (num_response <= LIMIT) {
emailBody = emailBody + "\n\nYou are enrolled in the workshop";
}
else {
var wait = num_response - LIMIT
emailBody = emailBody + "\n\nThe workshop is full. You are #" + wait + " in the waiting list"
}
emailBody = emailBody + "\n\nThe details you entered were as follows: " +
"\nYour Name: " + yourName +
"\nYour Email: " + toAddress ;
MailApp.sendEmail(toAddress, subject,
emailBody, optAdvancedArgs);
}
I have no clue how to find right answer in the google app document. Any help would be greatly appreciated!
How about the composite function
FormApp.getActiveForm().getResponses().length
no need to go around looking for the spreadsheet (since in my experience, the spreadsheet is not always up to date, whereas the form is)
From what I see in the tutorial, this script is embedded in a spreadsheet so the easiest would be to count the number of rows and substract 1 because of the headers...
There is a method for that : getLastRow(), the doc refered in this link should give you enough information to write the few lines of code you need...
test :
function xx(){
var lr = SpreadsheetApp.getActiveSheet().getLastRow()-1;
Logger.log(lr);
}
Script on form (not spreadsheet)
function onFormSubmit(e) {
var num_response = FormApp.getActiveForm().getResponses().length
var LIMIT = 20 //or whatever
if (num_response < LIMIT) {
}
else {
var form = FormApp.getActiveForm();
form.setAcceptingResponses(false);
}
}

Email Google Form Results not working

I am using a script to have form results e-mailed to me every time the form is submitted. Entire code is posted in Google Groups here:
http://groups.google.com/a/googleproductforums.com/d/topic/apps-script/1rObNfuez6k/discussion
Here's the current code:
function contactUsMailer2(e) {
// var ss = SpreadsheetApp.getActive();
// SpreadsheetApp.setActiveSpreadsheet(ss);
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data'); //default sheets - change if you
var setup = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Setup'); //rename the sheets
var width = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data').getLastColumn(); //get "width" of sheet, used to enumrate fields
var myEmailAddress = setup.getRange('B3').getValue(); //get email recipient(s) from "Setup" (default)
var myEmailSubject = setup.getRange('B4').getValue(); //get a subject line from "Setup" (default)
//from row 1 of "Data"
var sheetURL = SpreadsheetApp.getActiveSpreadsheet().getUrl(); //get sheet url to include in email
var formURL = SpreadsheetApp.getActiveSpreadsheet().getFormUrl(); //get form url to include in email
var column = 'A';
var message = '';
var htmlBody = '<html><body><table>'; //generated email will have both an HTML table and a plain-text part
//to be RFC compliant. beginning of html and table.
for (var c=1; c<=width; ++c) {
var data = sheet.getRange(1, c, 1, 1).getValue(); //this gets the "filed" names from the 1st row of "Sheet1"
try {
//retrieve field data and build the HTML and plain-text emails
var message = message + data + ': ' + e.namedValues[data].toString() + '\r\n'; //plain-text
var htmlBody = htmlBody + '<tr><td><b>' + data + ': </b></td><td>' + e.namedValues[data].toString() + '</td></tr>'; //HTML
}
catch (a) {
var message = message + data + ': n/a\r\n';
var htmlBody = htmlBody + '<tr><td><b>' + data + ': </b></td><td>n/a</td></tr>';
}
var column = String.fromCharCode(column.charCodeAt() + 1); //increment column letter
}
var htmlBody = htmlBody + '</table>'; //close table
var message = message + '\r\n\r\nData from form located at ' + formURL + '\r\n'; //put form url in text email
var message = message + 'Data posted to spreadsheet at ' + sheetURL; //put sheet url in text email
var htmlBody = htmlBody + '<br><br>Data from form located here<br>'; //put form url in HTML email
var htmlBody = htmlBody + 'Data posted to spreadsheet here<br>'; //put sheet url in HTML email
var htmlBody = htmlBody + '</body></html>'; //close html
MailApp.sendEmail(myEmailAddress, myEmailSubject, message, {htmlBody: htmlBody}) ; //send the email
}
function showid() {
Browser.msgBox("The sheet ID is:\r\n\r\n" + SpreadsheetApp.getActiveSpreadsheet().getId());
}
Script now works fine with the original spreadsheet, but when I try to use it with a new form and spreadsheet it fails to send the e-mail. The form fill in the spreadsheet just fine and we get the usual e-mail stating that the spreadsheet has been updated, but the script e-mail doesn't come through.
Funny thing is when I debug the script it does send the e-mail, just null entries in all fields (which is what I would expect). Debug doesn't report any errors in the script itself. What am I missing?
Have you authorized the script in your new form ? Since your script is required to send out an email it requires explicit authorization.
Try removing the quote around
for (var c=1; c<=width; ++c) {
var data = sheet.getRange(column + '1').getValue(); //this gets the "filed" names from the 1st row of "Sheet1"
I do something similar in a script and the following works for me.
var rangeval = "B"+(i+1);
var nameFld = filesheet.getRange(i+1,1).getValue();
Joe
Make sure trigger is set to "On Submit". Mine was set to "On Open".