I'm new to using the google doc script editor so please be kind. Here's what I have so far:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//Get Active cell
var mycell = ss.getActiveSelection();
var cellcol = mycell.getColumn();
var cellrow = mycell.getRow();
//Define variables from sheet by column
//Column count starts at 0, not 1.
var timestamp = e.values[cellrow,14];
var yourName = e.values[cellrow, 0];
var email = e.values[cellrow, 1];
var plot2013 = e.values[cellrow, 5];
var plotrequest = e.values[cellrow, 6];
var sharing = e.values[cellrow, 7];
var totalprice = e.values[cellrow, 8];
var paid = e.values[cellrow, 13];
var subject = "TSF Payment Confirmation"
//email body
var emailBody = "Thank you for your payment submitted on " + timestamp +
"\n\nThe details you entered were as follows: " +
"\nYour name: " + yourName +
"\nYour plot #: " + plot2013 +
"\nNumber plots requested: " + plotrequest +
"\nSharing plot with: " + sharing +
"\nTotal payment: " + totalprice;
//html version of email body
var htmlBody = "Thank you for your payment submitted on <i>" + timestamp +
"</i><br/> <br/>The details you entered were as follows: " +
"<br/><font color=\"red\">Your Name:</font> " + yourName +
"<br/>Your Email: " + plot2013;
"<br/>Plots requested: " + plotrequest;
"<br/>Sharing plot with: " + sharing +
"<br/>Total payment: " + totalprice;
//sends email if cell contents are 'yes'
if (e.values[13,cellrow] == "yes") {
//Sends email
MailApp.sendEmail(email, subject, emailBody);
}
}
And what I'm hoping is that once a user clicks in column 13 (assuming its counting from 0 on the left, and not variable numbers) and types 'yes' it will email the information from that users row as specified.
I'm getting an error message, saying:
var timestamp undefined
I got that from this example here: http://alamoxie.com/blog/tech-tips/sending-confirmation-emails-google-docs-form/
You're trying to reference the cells in a way that doesn't make sense (or work). Try this tested/working code instead:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
// Ensure the event was triggered by typing "yes" in the appropriate column
if(e.range.getColumn() == 14 && e.value.toUpperCase() == "YES"){
// Get the corresponding row
var row = sheet.getRange(e.range.getRow(), 1, 1, sheet.getLastColumn()).getValues()[0];
// Define variable from row by column
var timestamp = row[14];
var yourName = row[0];
var email = row[1];
var plot2013 = row[5];
var plotrequest = row[6];
var sharing = row[7];
var totalprice = row[8];
var paid = row[13];
var subject = "TSF Payment Confirmation"
// Construct the email body
var emailBody = "Thank you for your payment submitted on " + timestamp +
"\n\nThe details you entered were as follows: " +
"\nYour name: " + yourName +
"\nYour plot #: " + plot2013 +
"\nNumber plots requested: " + plotrequest +
"\nSharing plot with: " + sharing +
"\nTotal payment: " + totalprice;
// Construct an HTML version of the email body
var htmlBody = "Thank you for your payment submitted on <i>" + timestamp +
"</i><br/> <br/>The details you entered were as follows: " +
"<br/><font color=\"red\">Your Name:</font> " + yourName +
"<br/>Your Email: " + plot2013;
"<br/>Plots requested: " + plotrequest;
"<br/>Sharing plot with: " + sharing +
"<br/>Total payment: " + totalprice;
// Send email
MailApp.sendEmail(email, subject, emailBody);
}
}
Notice I put everything in a conditional statement; there's no sense in trying to parse all that data if a cell in column N wasn't changed to "yes". Immediately after, I retrieve all the values from the edited row and fill all your variables with the result. The rest is pretty much the same as you wrote it.
Good luck!
Related
For a new course project, I'm coming back to a google script for SendEmail from Google Sheets that worked perfectly a couple of years ago. (Original code from https://medium.com/#sebfung/custom-emails-from-a-spreadsheet-b11ff050bc5f ). Now I get three errors and can't figure out how to fix the third.
The full code is below. I've got limited code experience, but I figure I can work around the first two errors I get because they're cosmetic and my students can deal with it. (First, I can take out code to live without the "split" that used to let me drop off the second half of email addresses in the SendToName salutation. Second, I can take out the "replace" code that switches newline to paragraph breaks.)
But I can't figure out how to get around the third error. Something in the last command (MailApp.SendEmail) gives me a "Invalid email: undefined (line 66, file "Code")" error.
I don't see that any of these could be a spreadsheet-related error, since I went back to the earlier spreadsheets that worked a couple years ago and the debug now brings up the same three errors.
I'd be happy for suggestions on the first two, but I really most need and value help with that third error. I can't even run or test anything unless I fix it. Thanks!
function sendEmail(to, score, questions, answer1, answer2, answer3, answer4, answer5) {
var ss = SpreadsheetApp.getActiveSheet();
var range = ss.getActiveRange();
var numRows = range.getNumRows();
var values = range.getValues();
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
var to = row[1];
var score = row[2];
var questions = row[3]
var answer1 = row[4];
var answer2 = row[5];
var answer3 = row[6];
var answer4 = row[7];
var answer5 = row[8];
var sendToName = to.split('#')[0];
// email content
var emailSubject = "Quiz 1 Response";
// plain text body - just in case receiver can't parse html formatted email
var plainTxtBody = "Hello " + sendToName + ",\n" +
"You scored:\n" + score + "\n" +
"The questions were:\n" + questions + "\n" +
"Your answer:\n" + answer1 + "\n" +
"Your answer:\n" + answer2 + "\n" +
"Your answer:\n" + answer3 + "\n" +
"Your answer:\n" + answer4 + "\n" +
"Your answer:\n" + answer5;
// html formatting isn't necessary, but nice for reading :)
var htmlBody = '<html><body>';
var htmlFooter = '</body></html>';
// replacing newline characters with paragraph breaks to make it more readable
var scoreHTML = score.replace(/\n/g, "</p><p>");
var questionsHTML = questions.replace(/\n/g, "</p><p>");
var answer1HTML = answer1.replace(/\n/g, "</p><p>");
var answer2HTML = answer2.replace(/\n/g, "</p><p>");
var answer3HTML = answer3.replace(/\n/g, "</p><p>");
var answer4HTML = answer4.replace(/\n/g, "</p><p>");
var answer5HTML = answer5.replace(/\n/g, "</p><p>");
var emailMessage = "<p>Hello " + sendToName + ",</p>" +
"<p><strong>You scored:</strong><p>" +
"<p>" + scoreHTML + "</p>" +
"<hr>" +
"<p><strong>Here are the questions--see the answer key on the Quiz 1 page on the wiki:</strong></p>" +
"<p>" + questionsHTML + "</p>" +
"<hr>" +
"<p><strong>Here are your answers:</strong></p>" +
"<p>" + answer1HTML + "</p>" +
"<p>" + answer2HTML + "</p>" +
"<p>" + answer3HTML + "</p>" +
"<p>" + answer4HTML + "</p>" +
"<p>" + answer5HTML + "</p>";
htmlBody += emailMessage + htmlFooter;
// GmailApp must have default recipient, subject, body attributes followed by jsobject options {}
// Differs from MailApp syntax but has more options -- see documentation on GmailApp
MailApp.sendEmail(to, emailSubject, plainTxtBody, {
htmlBody: htmlBody,
});
}
}
The script does work. Var "to" probably doesn't contain a valid email adres. Make sure you have selected an active range in your spreadsheet. Please also note the first item in an array has index 0. Which reflects to the first column in your selection.
You can set a break point and use the debugger or use Logger.log(to); View -> Logs will show the outcome of var to.
Hi everyone I copied this from a previous post and matched it up to my needs. I'm having trouble preventing it from sending the entire list when the word Sent is in column 10. I've messed with the coding more than I would like to at this point and feel it's getting messy.
Can someone take a look at it and see what is missing?
It will send the email and do everything I need, but so far it just sends all the lines of data regardless if Sent is in the column or not.
function sendEmails2() {
//setup function
var ActiveSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var StartRow = 2;
var RowRange = ActiveSheet.getLastRow() - StartRow + 1;
var WholeRange = ActiveSheet.getRange(StartRow,1,RowRange,11);
var AllValues = WholeRange.getValues();
var message = "";
//iterate loop
for (i in AllValues) {
//set current row
var CurrentRow = AllValues[i];
//define column to check if sent
var EmailSent = CurrentRow[10];
//if row has been sent, then continue to next iteration
if (EmailSent == "sent")
continue;
//set HTML template for information
message +=
"<p><b>Sales Rep: </b>" + CurrentRow[0] + "</p>" +
"<p><b>Case ID: </b>" + CurrentRow[1] + "</p>" +
"<p><b>Name: </b>" + CurrentRow[2] + "</p>" +
"<p><b>Signing Date: </b>" + CurrentRow[3] + "</p>" +
"<p><b>Draft Date: </b>" + CurrentRow[4] + "</p>" +
"<p><b>Sign to Draft: </b>" + CurrentRow[5] + "</p>" +
"<p><b>Enrolled Debt: </b>" + CurrentRow[6] + "</p><br><br>";
//set the row to look at
var setRow = parseInt(i) + StartRow;
//mark row as "sent"
ActiveSheet.getRange(setRow, 10).setValue("sent");
}
//define who to send email to
var SendTo = "my email address" + "," + "";
//set subject line
var Subject = "NEW DEAL CLOSED";
//send the actual email
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
}
mistake is there in var EmailSent = CurrentRow[10] where the column being considered actually in 11. When taking the whole data range from sheet, the column index starts from 0 and so the actual index to be taken should be 9 for 10th column
//define column to check if sent
var EmailSent = CurrentRow[9];
I'm making an online registration with google forms. Once a person submits, an email will be sent to the email they entered. The data is the things they entered in the form. So this email serves as a data confirmation email. The problem now is, the test i did was successful but, the emails contained aaalll of the data. My question would be, how to email the data from a specific row for a specific email
here's what i did (copied from someone)
function sendEmail() {
//setup function
var ActiveSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var StartRow = 3;
var RowRange = ActiveSheet.getLastRow() - StartRow + 1;
var WholeRange = ActiveSheet.getRange(StartRow,1,RowRange,11);
var AllValues = WholeRange.getValues();
var message = "";
//iterate loop
for (i in AllValues) {
//set current row
var CurrentRow = AllValues[i];
//define column to check if sent
var EmailSent = CurrentRow[11];
//if row has been sent, then continue to next iteration
if (EmailSent == "sent")
continue;
//set HTML template for information
message +=
"<p><b>Found by: </b>" + CurrentRow[1] + "</p>" +
"<p><b>Title: </b>" + CurrentRow[2] + "</p>" +
"<p><b>Agency: </b>" + CurrentRow[3] + "</p>" +
"<p><b>Summary: </b>" + CurrentRow[4] + "</p>" +
"<p><b>Due: </b>" + CurrentRow[5] + "</p>" +
"<p><b>Posted: </b>" + CurrentRow[6] + "</p>" +
"<p><b>Total Funding: </b>" + CurrentRow[7] + "</p>" +
"<p><b>Announcement Number: </b>" + CurrentRow[8] + "</p>" +
"<p><b>Useful Links: </b>" + CurrentRow[9] + "</p><br><br>";
//set the row to look at
var setRow = parseInt(i) + StartRow;
//mark row as "sent"
ActiveSheet.getRange(setRow, 11).setValue("sent");
}
//define who to send grants to
var SendTo = "emailaddress1#gmail.com" + "," + "emailaddress2#gmail.com";
//set subject line
var Subject = "Grants";
//send the actual email
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
}
I answered a similar question about this recently. It's always easier for me to break down the problem into the parts we need. In this case, we need: All the responses, then we need to match a response
The best way is to first read the form responses as an array:
function formResponsesToArray() {
var app = FormApp.openById(...),
responses = app.getResponses(), stringResponses = []
responses.forEach(function(r) {
var response = []
r.getItemResponses().forEach(function(i) {
response.push(i.getResponse())
})
stringResponses.push(response)
})
Logger.log(stringResponses)
}
If you know the persons email, then we can get their response like this, assuming the email is the first thing they enter in to the form:
var theirEmail = "hello#hello.com"
var theirResponse = stringResponses.filter(function(response) {
return response[0] === theirEmail
})
Then you can use theirResponse to get the information they entered in to the form!
The code you shared basically gathers all the rows data where a email status field has no "sent" value and composes a single message at the end and sends it.
According to your condition, you need to send a different mail for every row where email status field has no "sent" value.
I have added the mailApp syntax inside the loop only to send different mails and done some changes with message variables.
function sendEmail() {
//setup function
var ActiveSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var StartRow = 3;
var RowRange = ActiveSheet.getLastRow() - StartRow + 1;
var WholeRange = ActiveSheet.getRange(StartRow,1,RowRange,11);
var AllValues = WholeRange.getValues();
//iterate loop
for (i in AllValues) {
//set current row
var CurrentRow = AllValues[i];
//define column to check if sent
var EmailSent = CurrentRow[11];
//if row has been sent, then continue to next iteration
if (EmailSent == "sent")
continue;
//set HTML template for information
//here i have removed the "+" sign to create a new message for its respective row
var message=
"<p><b>Found by: </b>" + CurrentRow[1] + "</p>" +
"<p><b>Title: </b>" + CurrentRow[2] + "</p>" +
"<p><b>Agency: </b>" + CurrentRow[3] + "</p>" +
"<p><b>Summary: </b>" + CurrentRow[4] + "</p>" +
"<p><b>Due: </b>" + CurrentRow[5] + "</p>" +
"<p><b>Posted: </b>" + CurrentRow[6] + "</p>" +
"<p><b>Total Funding: </b>" + CurrentRow[7] + "</p>" +
"<p><b>Announcement Number: </b>" + CurrentRow[8] + "</p>" +
"<p><b>Useful Links: </b>" + CurrentRow[9] + "</p><br><br>";
//here you can add the email address field to whom you want to send emails.
//e.g. var SendTo=CurrentRow[1];
//define who to send grants to
var SendTo = "emailaddress1#gmail.com" + "," + "emailaddress2#gmail.com";
//set subject line
var Subject = "Grants";
//send the actual email
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
//set the row to look at
var setRow = parseInt(i) + StartRow;
//mark row as "sent"
ActiveSheet.getRange(setRow, 11).setValue("sent");
}
}
Hope this helps, Thanks
I'm having a problem sending an html body message from a Google sheet from another email address that is an alias.
I can send it using the mailApp, but when I switch to the GmailApp I can't seem to get it to work.
The script I am using is below:
function sendNotification(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var emailAdd = "email#yourdomain.com";
if(event.range.getA1Notation().indexOf("G") > -1 && sheet.getRange("G" + row).getDisplayValue() > 999 && emailAdd.length > 1)
{
var rowVals = getActiveRowValues(sheet);
var aliases = GmailApp.getAliases();
Logger.log(aliases);
GmailApp.sendEmail(
"email#yourdomain.com",
"Allocation Request - " + rowVals.quantity + " cases on " + rowVals.date,
{htmlBody: "There has been a new allocation request from " + rowVals.name + " in the " + rowVals.team + " team.<br \> <br \> "
+ "<table border = \"1\" cellpadding=\"10\" cellspacing=\"0\"><tr><th>Issuing Depot</th><th>Delivery Date</th><th>Case Quantity</th></tr><tr><td>"+rowVals.depot+"</td><td>"+rowVals.date+"</td><td>"+rowVals.quantity+"</td></tr></table>"
+ "<br \>To view the full details of the request, use the link below.<br \> <br \>" +
"Allocation Requests"
+"<br \> <br \><i>This is an automated email. Please do not reply to it.<\i>"},
{from: aliases[0]}
);
}
}
function getActiveRowValues(sheet){
var cellRow = sheet.getActiveRange().getRow();
// get depot value
var depotCell = sheet.getRange("E" + cellRow);
var depot = depotCell.getDisplayValue();
// get date value
var dateCell = sheet.getRange("F" + cellRow);
var date = dateCell.getDisplayValue();
// get quantity value
var quantCell = sheet.getRange("G" + cellRow);
var quant = quantCell.getDisplayValue();
// return an object with your values
var nameCell = sheet.getRange("B" + cellRow);
var name = nameCell.getDisplayValue();
var teamCell = sheet.getRange("C" + cellRow);
var team = teamCell.getDisplayValue();
return {
depot: depot,
date: date,
quantity: quant,
name: name,
team: team
} }
I've managed to get the email to send from my alias, but it just sends and message containing [object], whereas not sending it from an alias works fine.
Could someone take a look and see what I'm doing wrong? I've not been able to find an answer on here yet. Thanks.
Create an object then add elements to the object:
var bodyHTML,o,sendTO,subject;//Declare variables without assigning a value
o = {};//Create an empty object
bodyHTML = "There has been a new allocation request from " + rowVals.name;
o.htmlBody = bodyHTML;//Add the HTML to the object with a property name of htmlBody
o.from = aliases[0]; //Add the from option to the object
sendTO = "email#yourdomain.com";
subject = "Allocation Request - " + rowVals.quantity + " cases on " + rowVals.date;
GmailApp.sendEmail(sendTO,subject,"",o);//Leave the third parameter as an empty string because the htmlBody advanced parameter is set in the object.
I have created a script that automatically sends out emails that pulls information from several cells and populates the body of the email with the information alongside a standard body of the text.
However I can't work out a way to script in a paragraph space between the lines. I have done a workaround of creating a variable with the value of a cell that is just a paragraph space but, as other people will be using this spreadsheet, I am worried that the cell will get deleted and the formatting will change.
Is there another way to format paragraphs into the body of the email?
See my code below if that helps! The variable I need to format is "Var Message"
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = 99;
var dataRange = sheet.getRange(startRow, 1, numRows, 16)
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var EMAIL_SENT = "Contacted";
var currentdate = Utilities.formatDate(sheet.getRange("n2").getValue(), "GMT" , "dd/MM/yyyy" );
var staffmember = sheet.getRange("o2").getValue();
var paragraph = sheet.getRange("f2").getValue();
var row = data[i];
var emailAddress = row[0];
var name = row[1];
var company = row[2];
var website = row[3];
var role = row[4];
var show = row[9];
var date = Utilities.formatDate(row[15], "GMT" , "dd/MM/yyyy" );
var date2 = Utilities.formatDate(row[15], "GMT" , "dd/MM" );
var time = Utilities.formatDate(row[11], "GMT" , "HH:mm" );
var message = "Hello," + paragraph + "Could you please authorise or decline the following Arts Industry comp request from the Fringe Office? If you could reply within 72 hours, that would be great:" + paragraph + name + " " + company + " " + website + " " + role + paragraph + show + " " + date + " " + time + paragraph + "Many thanks," + paragraph + staffmember ;
var subject = "ARTS INDUSTRY REQUEST";
var emailSent = row[12];
if (emailSent != EMAIL_SENT) {
if (date > currentdate) {
var subject = "ARTS INDUSTRY REQUEST";
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 13).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
else if (emailSent != EMAIL_SENT) {
if (date < currentdate) {
var subject2 = "URGENT: ARTS INDUSTRY REQUEST" + " " + date2;
MailApp.sendEmail(emailAddress, subject2, message);
sheet.getRange(startRow + i, 13).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
}
}
}
}
For plaintext emails, you can use the "newline" escape sequence \n.
If you have K&R "C - The Programming Language", you'll find a full list of escape sequences in chapter 2. An online reference is available here.
var message = "Hello,\n"
+ "Could you please authorise or decline the following Arts Industry comp request from the Fringe Office? If you could reply within 72 hours, that would be great:\n\n"
+ name + " " + company + " " + website + " " + role
+ '\n' + show + " " + date + " " + time
+ '\n\n'
+ "Many thanks,"
+ '\n\n'
+ staffmember ;
You can use the advanced options of MailApp.sendEmail() function to achieve paragraph and line breaks more efficiently. Here is an example
var content = "Here is some text <br> " +
"that is split over two lines" ;
MailApp.sendEmail(recipient, subject, '',{'htmlBody' : content } );