Essentially i'm also pulling email addresses from a separate sheet via a formula so that when new form entry is made, column B populates the proper email (name is included in the form). The problem I'm facing is that for the tool to be efficient I need to run the formula all the way down indefinitely so that when new entry comes it simply looks up the name and column B pulls the correct email address. However, the below code returns an error because it cannot handle #N/A where no email exists yet or even "" with IFERROR in the formula.
Ideally the code will stop if #N/A is encountered and only continues when there is an email in CurrentRow[1] has an email. The code works perfectly fine if empty rows are totally blank.
The current version here comes from what I've read and researched, including the post: Email only new rows in Google sheets. I've researched and lots of similar examples exist but having tried 40 or so variations i could not get mine to work.
function sendEmail() {
//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 KamEmail = CurrentRow[1];
//if row has been sent, then continue to next iteration
if (CurrentRow[1] == "#N/A") {break;}
else;
//set HTML template for information
message +=
"<p>Hi " + CurrentRow[1] + "</p>" +
"<p>Your constituent has submitted an Agenda blog pitch" + "</p>" +
"<p><b>Name of constituent: </b>" + CurrentRow[2] + "</p>" +
"<p><b>Submission Snapshot: </b>" + CurrentRow[3] + "</p>" +
"<p><b>Link to Submission: </b>" + CurrentRow[4] + "</p>" +
"<p><b>Date of Submission: </b>" + CurrentRow[7] + "</p><br><br>";
//set the row to look at
var setRow = parseInt(i) + StartRow;
//mark row as "sent"
ActiveSheet.getRange(setRow, 9).setValue("Sent to KAM");
}
//define who to send grants to
var SendTo = CurrentRow[1];
//set subject line
var Subject = "RE: Registrations";
//send the actual email
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
}
Related
I am trying to create a sheet for project management to collaborate easily among many interlocutor (I know there are free tools outhere working with a public organization is hellish to insert new procedures into the project).
Here is the sample file created : Google Sheet for Test
The ideais everytime a new question is input, the author can select the menu "Question" > "Send Question".
And it should sent automatic email to the Recipient email address (column C)... under the condition that the Question cell is filled (condition checked in "I2").
But currently, the script does not work as expected.
Note: I am currently learning JS.
Here is the code :
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Question')
.addItem('Send Question', 'sendQuestion')
.addSeparator()
.addItem('Send Answer', 'sendAnswer')
.addToUi();
}
function sendQuestion() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Questions");
var range = sheet.getRange("A22:L2");
var emailvalid = range.getCell(1,7).getValue();
var question = range.getCell(1,5).getValue();
var answer = range.getCell(1,6).getValue();
var qvalid = range.getCell(1,8).getValue();
var ansvalid = range.getCell(1,10).getValue();
if(qvalid == "Nope"){
Browser.msgBox("Please, write a question !");
}
else {
return false};
if(emailvalid == "Nope"){
Browser.msgBox("Please, input a valid email address !");
}
else {
return false};
var from = range.getCell(1,1).getValue();
var recipient = range.getCell(1,2).getValue();
var emailTo = range.getCell(1,3).getValue();
var subject = "Project Management | Your received a new question" + question;
var link = "https://docs.google.com/spreadsheets/d/1QUbw0WNju55h5pk3l8QqVCYa_jSCzrIzMjf0N4v-z8c/edit?usp=sharing"
var options = {}
options.htmlBody = "Hi" + recipient +"," + "<br />"+ "<br />" + "You received a new question from " + from + "<br />" + "<br />" + "You can answer directly into the table here: "<"br />"+"<br />" + link + "<br />" + "<br />"+ "Thank you";
GmailApp.sendEmail(emailTo, subject, " ", options);
}
function emailSent(){
var ui = SpreadsheetApp.getUi();
var sent = sendQuestion("Send Email ?",ui.ButtonSet.YES_NO);
if(sent == ui.Button.YES) {
ui.alert("Your Message has been sent.");
} else {
ui.alert("Email canceled");
}
}
You're main error there is this else return false statement you have, which is basically terminating the function if your validation passes, where it should be the other way around, exiting the function if the validation fails, after you popup informing the problem.
if(qValid == 'Nope') {
Browser.msgBox('etc...');
return; //return here, not in the else clause
}
//same for email valid
There are quite a few other "improvements" I'd do on such function. But I guess it's beyond the point here, you're learning as you go and the most important is that it works now.
I have made a google form that saves data in a spreadsheet, I am writing the code for such spreadsheet so it sends me an email with some data from it, however I am struggling to get one of the values. Column 4 (D) gets the email address from the sender, so I wanna recover that value to put it as a "replyTo" variable and be able to directly reply to whoever is enquiring.
This is my code so far:
function Initialize() {
try {
var triggers = ScriptApp.getProjectTriggers();
for (var i in triggers)
ScriptApp.deleteTrigger(triggers[i]);
ScriptApp.newTrigger("EmailGoogleFormData")
.forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet())
.onFormSubmit().create();
} catch (error) {
throw new Error("Please add this code in the Google Spreadsheet");
}
}
function EmailGoogleFormData(e) {
try {
if (MailApp.getRemainingDailyQuota() > 0) {
// You may replace this with another email address
var email = "nico.pinera#filmmusiclive.com";
/*********** Sender email address || I HAVE PROBLEMS HERE ***********/
var replyTo, senderMail,ss,r_max;
ss = SpreadsheetApp.getActiveSheet();
//r_max = ss.getmaxRows();
// Returns the active cell
var range = ss.getActiveRange();
senderMail = range.getValues()[3];
// Enter your subject for Google Form email notifications
var subject = "Parte de NNTT recibido"
var key, entry,
message = "<b>Hola pepito</b><br/>aa</br><br><br><br><br>",
ss = SpreadsheetApp.getActiveSheet(),
cols = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues()[0];
// Iterate through the Form Fields
for (var keys in cols) {
key = cols[keys];
entry = e.namedValues[key] ? e.namedValues[key].toString() : "";
// Only include form fields that are not blank
if ((entry !== "Sí") && (entry !== "") && (entry !== ",") && (entry.replace(/,/g, "") !== "Sí"))
message += '<img src="" /><br/><br/>' + ' <b><u> ' + key + '</u></b>' + ' => ' + entry ;
}
MailApp.sendEmail(email, replyTo, subject, message);
}
} catch (error) {
Logger.log(error.toString());
}
}
Does anyone have any idea of how can I get the active value from that cell? which would be whatever row in column D.
Also, I did do it by finding the int of maxRows() and then finding the value of the cell of maxRows() and column D, however If I manually edit the spreadsheet (say I manually add a value in the last row), new form requests would be stored above that one and shifting it down. (If I edit row 12 and a new request comes in, my row moves down to 13 and the new one is stored in 12 and so on and so forth).
Short answer
If the required data for the email is included in the form response, instead of using a spreadsheet bounded script, use a form bounded script.
Explanation
Google Forms also could have bounded scripts. Those scripts could be triggered on form submission and the form submission responses are included in the event object as a Form Response object. See Google Form Events and Form Response.
Benefits
To have the responses data in one place, the form file, instead of two, the form file and a spreadsheet.
the responses are in a response object. There is no need to call the value from a cell and this could save a several lines of code and calls to the Google Apps Script services
the response object include the edit response URL that is not added to the spreadsheet by default.
Brief code example
Simplified version of the code posted at Sending Confirmation Emails from Google Apps Forms by Les Bell and adapted to add the email address submitted as response to the reply-to parameter
function sendConfirmationEmail(e) {
// e is a Form Event object
// Edit this to set the subject line for the sent email
var subject = "Registration Successful";
// This will show up as the sender's name
var sendername = "Your Name Goes Here";
// This is the body of the registration confirmation message
var message = "Thank you for registering.<br>We will be in
touch.<br><br>";
// response is a FormResponse
var response = e.response;
var textbody, sendTo, bcc, replyTo;
// Get the script owner's email address, in order to bcc: them
bcc = Session.getActiveUser().getEmail();
// Now loop around, getting the item responses and writing them
// into the email message
var itemResponses = response.getItemResponses();
for (var i = 0; i < itemResponses.length; i++) {
var itemResponse = itemResponses[i];
// If this field is the email address, then use it to fill in
// the sendTo variable
// Check that your form item is named "Email Address" or edit to match
if (itemResponse.getItem().getTitle() == "Email Address") {
sendTo = itemResponse.getResponse();
replyTo = sendTo;
}
}
GmailApp.sendEmail(sendTo, subject, message, {
bcc: bcc,
name: sendername,
htmlBody: message,
replyTo: replyTo
});
}
Complete Code
The below code was taken from Sending Confirmation Emails from Google Apps Forms by Les Bell. The URLs included as comments were removed and some breaklines were added to avoid the appearance of the horizontal scroll bar.
Its purpose is to send the submitted responses and the edit response URL to the email address captured in the form submission.
function setup() {
/* First, delete all previous triggers */
var triggers = ScriptApp.getProjectTriggers();
for (var i in triggers) {
ScriptApp.deleteTrigger(triggers[i]);
}
/* Then add a trigger to send an email on form submit */
ScriptApp.newTrigger("sendConfirmationEmail")
.forForm(FormApp.getActiveForm())
.onFormSubmit()
.create();
}
function sendConfirmationEmail(e) {
// e is a Form Event object
// Edit this to set the subject line for the sent email
var subject = "Registration Successful";
// This will show up as the sender's name
var sendername = "Your Name Goes Here";
// This is the body of the registration confirmation message
var message = "Thank you for registering.<br>We will be in touch.
<br><br>";
message += "Your form responses were:<br><br>";
// response is a FormResponse
var response = e.response;
var textbody, sendTo, bcc;
// Get the script owner's email address, in order to bcc: them
bcc = Session.getActiveUser().getEmail();
// Now loop around, getting the item responses and writing them
// into the email message
var itemResponses = response.getItemResponses();
for (var i = 0; i < itemResponses.length; i++) {
var itemResponse = itemResponses[i];
message += itemResponse.getItem().getTitle() +": "
+ itemResponse.getResponse() + "<br>";
// If this field is the email address, then use it to fill in
// the sendTo variable
// Check that your form item is named "Email Address" or edit
// to match
if (itemResponse.getItem().getTitle() == "Email Address") {
sendTo = itemResponse.getResponse();
}
}
message += "<br>If you wish to edit your response, please click on
<a href=\""
+ response.getEditResponseUrl()
+ "\">this link</a>.";
message += "<br><br>";
textbody = message.replace("<br>", "\n");
GmailApp.sendEmail(sendTo, subject, textbody,
{bcc: bcc, name: sendername, htmlBody: message});
}
Project key: MyvPlY2KvwGODjsi4szfo389owhmw9jII
I am trying to run a script that sends the contents of my form by email each time the form is submitted. I was following the instructions from this link below exactly until I started getting errors and I received advice to change my script to open spreadsheets by id:
http://www.snipe.net/2013/04/email-contents-google-form/
When I complete the form, it is supposed to email the contents to my email.
The problem I am now having is that the function which goes through the form values doesn't work. It's returning the error
TypeError: Cannot read property "namedValues" from undefined. (line 15, file "Code")"
in regards to the piece of code below:
for(var i in headers)
message += headers[i] + ': '+ e.namedValues[headers[i]].toString() + "\n\n";
I am not too familiar with Google Apps Scripts so I'm not sure how to work around this issue either. Is there anything you recommend? I have included the entire script below.
function sendFormByEmail(e)
{
// Remember to replace this email address with your own email address
var email = "sample#email.com";
var s = SpreadsheetApp.openById("1hOqnK0IVa2WT6-c-MY0jyGGSpIJIV2yzTXdQYX4UQQA").getSheets()[0];
var headers = s.getRange(1,1,1,s.getLastColumn()).getValues()[0];
var message = "";
var subject = "New User Form";
// The variable e holds all the form values in an array.
// Loop through the array and append values to the body.
for(var i in headers)
message += headers[i] + ': '+ e.namedValues[headers[i]].toString() + "\n\n";
// Insert variables from the spreadsheet into the subject.
// In this case, I wanted the new hire's name and start date as part of the
// email subject. These are the 3rd and 16th columns in my form.
// This creates an email subject like "New Hire: Jane Doe - starts 4/23/2013"
subject += e.namedValues[headers[2]].toString() + " - starts " + e.namedValues[headers[15]].toString();
// Send the email
MailApp.sendEmail(email, subject, message);
}
The function appears to be undefined as 'e' is not received as part of the function context. You'll need to set a trigger for the submission of the form, and send the information to the function. You can use the following code:
/* Send Confirmation Email with Google Forms */
function Initialize() {
var triggers = ScriptApp.getProjectTriggers();
for (var i in triggers) {
ScriptApp.deleteTrigger(triggers[i]);
}
ScriptApp.newTrigger("SendConfirmationMail")
.forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet())
.onFormSubmit()
.create();
}
function SendConfirmationMail(e) {
try {
var ss, cc, sendername, subject, columns;
var header, message, value, textbody, sender, itemID, url;
// This is your email address and you will be in the CC
cc = "name#email.com";
// This will show up as the sender's name
sendername = "name to be displayed as sender";
// Optional but change the following variable
// to have a custom subject for Google Docs emails
subject = "Choose an approppiate subject";
// This is the body of the auto-reply
message = "";
ss = SpreadsheetApp.getActiveSheet();
columns = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues()[0];
// This is the submitter's email address
sender = e.namedValues["Username"].toString();
// Only include form values that are not blank
for ( var keys in columns ) {
var key = columns[keys];
//Use this to look for a particular named key
if ( e.namedValues[key] ) {
if ( key == "Username" ) {
header = "The user " + e.namedValues[key] + " has submitted the form, please review the following information.<br />";
} else {
message += key + ' ::<br /> '+ e.namedValues[key] + "<br />";
}
}
}
}
textbody = header + message;
textbody = textbody.replace("<br>", "\n");
Logger.log("Sending email");
GmailApp.sendEmail(cc, subject, textbody,
{cc: cc, name: sendername, htmlBody: textbody});
} catch (e) {
Logger.log(e.toString());
}
}
I have the same error and it took me some time to figure out how to solve it.
The problem is that you are writing your code in the form, and you should do it in your spreadsheet.
When I created the function inside the form and registered the event, it was called but the parameter didn't have the same structure (and didn't have the field namedValues, so the error "Cannot read property "namedValues" from undefined"). A better way to check this is to log the object as a JSON string:
Logger.log("e: " + JSON.stringify(e));
So, the steps I have made to correct this issue:
Create a spreadsheet
Create the form through the spreadsheet (inside the spreadsheet select Tools->Create a form), and create your form
Go back to your spreadsheet, and create the script (Tools->Script Editor)
Write your function
Register the function (Edit->Current Project's Triggers): function sendFormByEmail, Event: From Spreadsheet -> On form submit
Hope this helps
There is an error in this line of code:
message += headers[i] + ': '+ e.namedValues[headers[i]].toString() + "\n\n";
it's this part:
e.namedValues[headers[i]].toString()
I'm just guessing that you want:
e.namedValues + [headers[i]].toString()
You're missing a plus sign if you want to concatenate the values.
My company has a google form that we use to submit requests for data pulls. I created a script that auto emails form responses to myself, as well as a copy to the submitter. The script is:
function Initialize() {
var triggers = ScriptApp.getScriptTriggers();
for(var i in triggers) {
ScriptApp.deleteTrigger(triggers[i]);
}
ScriptApp.newTrigger("SendGoogleForm")
.forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet())
.onFormSubmit()
.create();
}
function SendGoogleForm(e)
{
try
{
// You may replace this with another email address
var email = "My Email Goes here"
var Owner = e.namedValues["Owner:"].toString();
cc = email + "," + Owner
Adv = e.namedValues["Advertiser Name:"].toString();
IO = e.namedValues["IO Name:"].toString();
Tog = "Pixel Request " + Adv + " " + IO;
// Optional but change the following variable
// to have a custom subject for Google Form email notifications
var subject = Tog;
var s = SpreadsheetApp.getActiveSheet();
var columns = s.getRange(1,1,1,s.getLastColumn()).getValues()[0];
var message = "";
// Only include form fields that are not blank
for ( var keys in columns ) {
var key = columns[keys];
if ( e.namedValues[key] && (e.namedValues[key] != "") ) {
message += key + ' :: '+ e.namedValues[key] + "\n\n";
}
}
// This is the MailApp service of Google Apps Script
// that sends the email. You can also use GmailApp for HTML Mail.
MailApp.sendEmail(cc, subject, message);
} catch (e) {
Logger.log(e.toString());
}
}
The script sends the emails without a problem. However, while the email sent to myself shows up in my sent mail, no copy is delivered to my inbox and it is marked as read; this is a problem because then I do not know that requests have been submitted which was the point of this creation. This seems anomalous as normally emails to yourself will typically show up in the inbox as unread. Does anyone know a way I might be able to fix this?
This is not an issue with the Google Script. This is probably how Gmail handles email where the sender and recipient is you.
i need help with adding space or a new row in a script. It looks like this:
function myFunction() {
var firstThread = GmailApp.getInboxThreads(0,1)[0];
var message = firstThread.getMessages()[0];
var sender = message.getFrom();
var body = "This email is sent from:" + " " + sender + message.getPlainBody();
var subject = message.getSubject();
var attachment = message.getAttachments();
GmailApp.sendEmail("user.name#aruba.com", subject, body, {attachments: attachment});
}
I need to add the "message.getPlainBody();" on a new line under the "This email is sent from:" + " " + sender "
Right now all gets on the same row in the Email. Is there any similar thing like the html tag <br> ?
You can insert linebreak/newline characters in strings to start a new line.
Note the \n which actually counts as 1 character (the \ starts an escape sequence)
var body = "This email is sent from:\n" + sender + "\n\n" + message.getPlainBody();
Just try with adding \n:
var body = "This email is sent from: " + sender + "\n" + message.getPlainBody();