In google sheets, I have it set it to when an user selects an option from a dropdown, it sends an email (from their email address) to the user who submitted that response on a form. This part works fine. The issue is that when an email is sent from the sheet, it sends an email from every user who authorized the script, not just the user that selected the option from the dropdown. I'm very green at this and not really sure how to fix it to where it only sends an email from the user who selected the option from the dropdown.
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [ {name: "Authorize", functionName: "createSpreadsheetEditTrigger"} ]
ss.addMenu("First Time Setup", menuEntries);
}
//** Creates onEdit trigger using current user as owner.
** If other onEdit triggers exist tied to this document & owner, delete them to avoid
duplicates.**//
function createSpreadsheetEditTrigger() {
var ss = SpreadsheetApp.getActive();
var session = Session.getActiveUser().getEmail();
var triggers = ScriptApp.getUserTriggers(ss);
triggers.forEach(function(trigger){
if(trigger.getEventType() == ScriptApp.EventType.ON_EDIT){
scriptApp.deleteTrigger(trigger);
}
});
ScriptApp.newTrigger('SendEmail')
.forSpreadsheet(ss)
.onEdit()
.create();
ScriptApp.newTrigger('Denied')
.forSpreadsheet(ss)
.onEdit()
.create();
ScriptApp.newTrigger('Pending')
.forSpreadsheet(ss)
.onEdit()
.create();
}
Utilities.sleep(2000);
function SendEmail(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
Logger.log(Session.getActiveUser().getEmail());
try{
var triggers = ScriptApp.getUserTriggers(ss);
}catch(e){
return;
}
if(e.range.getColumn() == 22 && e.value == "Approved"){
{
var EMAIL_SENT = 'EMAIL_SENT';
var dt = e.range.offset(0,-21).getValue();
var ldc = e.range.offset(0,-19).getValue();
var status = e.range.offset(0,0).getValue();
var notes = e.range.offset(0,-1).getValue();
var cost = e.range.offset(0,-5).getValue();
var start = e.range.offset(0,-4).getValue();
var end = e.range.offset(0,-3).getValue();
var Iemail = e.range.offset(0,-20).getValue();
var Aemail = e.range.offset(0,4).getValue();
var name = e.range.offset(0,-18).getValue();
var issue = e.range.offset(0,-16).getValue();
var emailSent = e.range.offset(0,5).getValue();
var userName = Session.getActiveUser().getUsername();
if (emailSent !== EMAIL_SENT){
var subject = "Exception Bill Pre-Approval Status - Approved";
var body = "Hello," + "\n\r" + "The following request has been Approved:" + "\n\n" + "Submitted on: " + dt
+ "\n" + "Submitted by: " + name + "\n" + "LDC: " + ldc + "\n" + "Service Needed: " + issue + "\n" + "Estimated Cost:" + cost + "\n" + "Start Date: " + start + "\n" + "End Date: " + end + "\n" + "Notes: " + notes + "\n\n" + "Status: " + status + "\n\r" + "\n\r" + "Thanks," + "\n" + userName;
Utilities.sleep(2000);
GmailApp.sendEmail(Iemail, subject, body);
e.range.offset(0,5).setValue(EMAIL_SENT)
SpreadsheetApp.flush();
}
}
}
}
The email is being sent from every user because there is a trigger calling sendEmail created by each of them.
One solution is to add at the beginning of the function an if statement as follows:
if(e.user.getEmail() !== Session.getActiveUser().getEmail()) return;
Related
May I don't know how to call another function when reached last row of register code column on google sheet, users click the submit on google form will auto email out another sendMail function
to said that eg 'registration had been closed, thank you.'
my code :
function sendmail() {
var ss = SpreadsheetApp.getActive();
var sh1 = ss.getSheetByName("Sheet1");
var EMAIL_SENT = "EMAIL_SENT";
var lastRow = sh1.getLastRow();
var email = sh1.getRange(lastRow, 2).getValue();
var name = sh1.getRange(lastRow, 1).getValue();
var registercode = sh1.getRange(lastRow, 3).getValue();
subjecttxt = "Thank you for registered with us"
email_Body = "Dear " + name + "," + "<br>" +
"your registeration is successfully, your registered code is " + registercode +
"Thank you for your registeration"
MailApp.sendEmail({
to:email,
subject: subjecttxt,
htmlBody: email_Body,
}) ;
sh1.getRange(lastRow, 4).setValue(EMAIL_SENT);
}
I believe your goal is as follows.
In your situation, the values are put to the columns "A" and "B". At that time, your function sendmail is run. At this time, when the values are put to the columns "A" and "B", when the row is over the last row of the column "C", you want to send an email body of registration had been closed, thank you..
If my understanding is correct, how about the following modification?
Modified script:
function sendmail() {
// This is from https://stackoverflow.com/a/44563639
Object.prototype.get1stEmptyRowFromTop = function (columnNumber, offsetRow = 1) {
const range = this.getRange(offsetRow, columnNumber, 2);
const values = range.getDisplayValues();
if (values[0][0] && values[1][0]) {
return range.getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow() + 1;
} else if (values[0][0] && !values[1][0]) {
return offsetRow + 1;
}
return offsetRow;
};
var ss = SpreadsheetApp.getActive();
var sh1 = ss.getSheetByName("Sheet1");
var EMAIL_SENT = "EMAIL_SENT";
var lastRow = sh1.get1stEmptyRowFromTop(1) - 1;
var email = sh1.getRange(lastRow, 2).getValue();
var name = sh1.getRange(lastRow, 1).getValue();
var registercode = sh1.getRange(lastRow, 3).getValue();
var subjecttxt = "Thank you for registered with us";
var email_Body;
if (lastRow < sh1.get1stEmptyRowFromTop(3)) {
email_Body = "Dear " + name + "," + "<br>" + "your registeration is successfully, your registered code is " + registercode + "Thank you for your registeration";
} else {
email_Body = "registration had been closed, thank you.";
}
MailApp.sendEmail({
to: email,
subject: subjecttxt,
htmlBody: email_Body,
});
sh1.getRange(lastRow, 4).setValue(EMAIL_SENT);
}
About if (lastRow < sh1.get1stEmptyRowFromTop(3)) {,,,}, in this script, when the values of columns "A" and "B" are put to the next row of the last row of the column "C", email_Body = "registration had been closed, thank you." is used. When you want to use this email_Body at the last row of the column "C", please modify (lastRow < sh1.get1stEmptyRowFromTop(3)) to (lastRow < sh1.get1stEmptyRowFromTop(3) - 1).
When you want to add "registration had been closed, thank you." to email_Body, when the values are put to the same row of the last row of the column "C", please modify the above if statement as follows.
if (lastRow < sh1.get1stEmptyRowFromTop(3) - 1) {
email_Body = "Dear " + name + "," + "<br>" + "your registeration is successfully, your registered code is " + registercode + "Thank you for your registeration";
} else {
email_Body += "registration had been closed, thank you.";
}
I have this code to send Google Form responses to email.
function sendFormByEmail(e) {
Logger.log("e: " + e);
var email = "email#gmail.com";
var s = SpreadsheetApp.getActiveSheet();
var headers = s.getRange(1,1,1,s.getLastColumn()).getValues()[0];
var message = "";
var subject = "New Hire Form Submission: ";
for(var i in headers)
message += headers[i] + ': '+ e.namedValues[headers[i]].toString() + "\n\n";
// Insert variables from the spreadsheet into the subject.
// 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);
}
This is tied to the spreadsheet not the form and e is returning undefined. I saw someone else have this issue and disabling the new Chrome V8 worked for them but is not working for me.
trigger settings
By the time the function is called, the data is already in the spreadsheet, so you could just read the last now
var row = SpreadsheetApp.getActiveSheet().getLastRow();
var columns = s.getLastColumn()
var range = s.getRange(row, 1, 1, columns).getValues();
When I inserted query function into the sheet from which it pulls the data, I began to get blank emails when the trigger ran. When I go into the script editor and debug or run, I get the email the way it is programmed to run
Email I receive on scheduled send:
Email I receive when sent from Script Editor
Here is the code I am running:
function sendEmail() {
//setup function
var ActiveSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var StartRow = 2;
var aVals = ActiveSheet.getRange("A1:A").getValues();
var aLast = aVals.filter(String).length;
var RowRange = aLast - StartRow + 2;
var WholeRange = ActiveSheet.getRange(StartRow, 1, RowRange, 10);
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 (starts from "0" not "1")
var hasTracking = CurrentRow[8];
//if row has been sent, then continue to next iteration
if (hasTracking !== "")
continue;
//set HTML template for information
message +=
"<p><b>Order: </b>" + CurrentRow[0] + "</p>" +
"<p><b>Name: </b>" + CurrentRow[4] + "</p>" +
"<p><b>Date Initiated: </b>" + CurrentRow[5] + "</p>" +
// "<p><b>Date Initiated: </b>" + Utilities.formatDate(CurrentRow[5], "GMT", "MM-dd-YYYY") + "</p>" +
"<p><b>Gorgias Link: </b>" + CurrentRow[6] + "</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 = "XXX#XXX.com";
//set subject line
var Subject = "Returns Needing Processed";
//send the actual email
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
}
Don't use .getActiveSheet() when you run the function via a trigger.
The reason is that .getActiveSheet() gets the active sheet of your file which can be any sheet.
Instead use .getSheetByName().
Replace:
var ActiveSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
with:
var ActiveSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
adjust Sheet1 with your specific case.
I am very new to google script and cannot work out why my script is not functioning. When I try to run the code I get the following error code -
TypeError: Cannot read property "range" from undefined. (line 2, file "Code"
If anybody could give a novice some help that would be greatly appreciated!
function sendEmail(event){
var sheet = event.range.getSheet();
if(sheet.getName() !== 'Sheet1') {
// if it's not the correct sheet we end the function here
return;
}
var range = event.range;
var row = range.getRow(); // we get the index of the row of the
edited
cell
var dataRange = sheet.getRange("A" + row + ":C" + row);
var values = dataRange.getValues();
var rowValues = values[0];
var recipient = rowValues[0];
var email = rowValues[1];
var refillsNumber = rowValues[2];
if (refillsNumber = 2) {
// if 'refillsNumber' is not equal to 2 we end the function here
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' +
refillsNumber + ' remaining would you like to buy more?' + '\n\n' +
'Kind regards,' + '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
MailApp.sendEmail(email,subject,message);
return
}
if (refillsNumber !== 0) {
return}
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' +
refillsNumber + ' remaining would you like to buy more? If not then
would you like to end your subsription?' + '\n\n' + 'Kind regards,'
+ '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
MailApp.sendEmail(email,subject,message);
return
}
// in addition to this script which aims to send an email to the
customer when they only have 2 refill remaining -
/// I also want to set up a function that sends an email when they
have 0 refills remaining
Send Emails by Editing Column C
I changed the Sheet name and added an extra condition. I also commented out the MailApp.sends and replaced them with writes to the sidebar so that I could test it without trying to send emails.
You will need to create an onEdit trigger for this function.
function sendMailOnEdit(event){
var sheet = event.range.getSheet();
if(sheet.getName() !== 'Sheet2' || event.range.columnStart!=3) {return;}
var range=event.range;
var row=range.rowStart;
var dataRange = sheet.getRange(row,1,1,3);
var values=dataRange.getValues();
var rowValues=values[0];
var recipient = rowValues[0];
var email = rowValues[1];
var refillsNumber = rowValues[2];
if (refillsNumber==2) {
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' + refillsNumber + ' remaining would you like to buy more?' + '\n\n' + 'Kind regards,' + '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
//MailApp.sendEmail(email,subject,message);
var html=Utilities.formatString('<br />Email: %s<br />Subject: %s<br />message: %s<br /><hr>', email,subject,message);
var userInterface=HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showSidebar(userInterface);
return
}
if (refillsNumber !== 0) {return}
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' + refillsNumber + ' remaining would you like to buy more? If not then would you like to end your subsription?' + '\n\n' + 'Kind regards,' + '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
//MailApp.sendEmail(email,subject,message);
var html=Utilities.formatString('<br />Email: %s<br />Subject: %s<br />message: %s<br /><hr>', email,subject,message);
var userInterface=HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showSidebar(userInterface);
}
This is what my spreadsheet looks like:
And let me remind you that you cannot run this function without an event object.
I'm a teacher and new to AppScript. I have created a spreadsheet to automatically send feedback to students via gmail from a google spreadsheet. It does work and the emails get sent from the spreadsheet but I get the following error 'Invalid Email <>' on the spreadsheet.
If anybody could help it'd be much appreciated.
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menu = [{
name: "Send Email",
functionName: "uiSendEmail"
}];
ss.addMenu("Send Email", menu);
}
function uiSendEmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getDataRange();
range = range.offset(1, 0, range.getNumRows()-1);
range.getValues().forEach( function( recipient, index, data ){
var msgHtml = "Hi " + recipient[0] + "," + "<p>" + "Atttitude to Learning Grade is: " + "<b><u>" + recipient[5] + "</b></u>" + "<p>" + "Feedback: " + recipient[6] + "<p>" + "Improvements to be made: " + recipient[7] + "<p>" + "Overall Grade: " + recipient[8];
var subject = recipient[3] + " - Teacher Feedback";
var msgPlain = msgHtml.replace(/(<([^>]+)>)/ig, ""); // clear html tags for plain mail
GmailApp.sendEmail(recipient[0] + " " + recipient[1] + "<" + recipient[2] + ">", subject, msgPlain, { htmlBody: msgHtml });
});
}
This was from long ago, so I assume you figured something out... (I stumbled upon this trying to solve a related problem).
From your above code and the error, I can see the that the recipient array contains no data.