Send Email When New Rows Are Added (Google App Script & Google Sheets) - google-apps-script

I have a google sheet containing 4 columns; title, url, published date and email sent (in that exact order).
When new rows are added to the sheet i want to execute a google script that will look through the 'email sent' column to see if an email has been sent and if not send an email containing the new rows and update the associated row(s) with a yes.
My current code is only getting the first row and nothing else.
Thanks in advance,
Mark
(see my current code below)
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,4);
var AllValues = WholeRange.getValues();
//iterate loop
for (i in AllValues) {
//set current row
var CurrentRow = AllValues[i];
//set subject line
var Subject = "New Content on IG.com";
//set HTML template for information
var message =
"<p><b>Title: </b>" + CurrentRow[1] + "</p>" +
"<p><b>Article: </b>" + CurrentRow[2] + "</p>" +
"<p><b>Published Date: </b>" + CurrentRow[3] + "</p>";
//define column to check if sent
var EmailSent = CurrentRow[4];
//define who to send grants to
var SendTo = "TEST#gmail.com";
//if row has not been sent, then...
if (EmailSent != "Yes") {
//set the row to look at
var setRow = parseInt(i) + StartRow;
//mark row as "sent"
ActiveSheet.getRange(setRow, 4).setValue("Yes");
//send the actual email
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
}
}
}

Try this:
function sendemail() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getActiveSheet();
const sr = 2;
const rg = sh.getRange(sr, 1, sh.getLastRow() - sr + 1, 4);
const vs = rg.getValues();
vs.forEach((r, i) => {
let Subject = "New Content on IG.com";
let message =
"<p><b>Title: </b>" + r[0] + "</p>" +
"<p><b>Article: </b>" + r[1] + "</p>" +
"<p><b>Published Date: </b>" + r[2] + "</p>";
let EmailSent = r[3];
let SendTo = "TEST#gmail.com";
if (EmailSent != "Yes") {
sh.getRange(i + sr, 4).setValue("Yes");
MailApp.sendEmail({to: SendTo,cc: "",subject: Subject,htmlBody: message});
}
})
}
Test:
A
B
C
D
1
Title
url
date
Sent
2
t1
u1
d1
Yes
3
t1
u2
d2
Yes
4
t1
u3
d3
Yes
5
t1
u4
d4
Yes
6
t1
u5
d5
Yes
7
t1
u6
d6
Yes
8
t1
u7
d7
Yes
9
t1
u8
d8
Yes
10
t1
u9
d9
Yes
It turns then all to Yes

Related

Apps Script: Send email depending one a checkbox selected

I am trying to create a small laptop rental system in the Google Sheets which sends email depending on checkbox which is selected (checked).
Two emails which are sent are: 1. Approved and 2. Overdue.
Problem that I have with my attempt is that multiple emails are sent even to the users which already have received the approval email when approved checkbox is selected and that no user is receiving any overdue email when overdue checkbox is selected. Also I have a Trigger set up with On edit. Its been wrecking my head for a while now, an help, pointers are greatly appreciated.
function onCheckboxEdit(e) {
var source = e.source;
var sheet = source.getActiveSheet();
var range = e.range;
var row = range.getRow();
var column = range.getColumn();
console.log("column:: ", column);
var targetRange = sheet.getRange(row, 1, 1, 17);
var targetValues = targetRange.getValues();
console.log("targetRange:: ", targetValues);
var student = targetValues[0][2];
var recipient = targetValues[0][1];
var checkboxValue = targetValues[0][9];
var checkboxValue2 = targetValues[0][17];
var subject = ("Laptop Loan Approved");
var body = ("Hello "+ student +", \n\nWe are happy to confirm that your laptop loan application has been approved.");
var subject2 = ("Laptop Loan");
var body2 = ("Hello "+ student +", \n\nPlease disregard last e-mail sent by us, it was mistakenly sent.");
var subject3 = ("Overdue Laptop Loan");
var body3 = ("Hello "+ student +", \n\nThe laptop you have been loaned is due to be returned.");
if(column = 10 && checkboxValue == true) {
console.log("chekbox marked true")
MailApp.sendEmail(recipient, subject, body)
} else if (column = 10 && checkboxValue == false) {
console.log("chekbox marked false")
MailApp.sendEmail(recipient, subject2, body2)
} else {
console.log("No clue")
}
if(column = 18 && checkboxValue2 == true) {
console.log("chekbox marked true")
MailApp.sendEmail(recipient, subject3, body3)
} else if (column = 18 && checkboxValue2 == false) {
console.log("chekbox marked false")
MailApp.sendEmail(recipient, subject3, body2)
} else {
console.log("No clue")
}
}
if(column = 10 .........)
should be ...
if(column == 10 .........)
or even ...
if(column === 10 .........)
Thanks to JtrM we have an answer!
rrays are zero indexed. Rows and columns are not. var targetRange = sheet.getRange(row, 1, 1, 17); Change the 17 to 18 –
JtrM
Also adding extra (=) eg: Before column = 10 After column == 10 etc...
function onCheckboxEdit(e) {
var source = e.source;
var sheet = source.getActiveSheet();
var range = e.range;
var row = range.getRow();
var column = range.getColumn();
console.log("column:: ", column);
var targetRange = sheet.getRange(row, 1, 1, 18); // <- 17 changed to 18
var targetValues = targetRange.getValues();
console.log("targetRange:: ", targetValues);
var student = targetValues[0][2];
var recipient = targetValues[0][1];
var checkboxValue = targetValues[0][9];
var checkboxValue2 = targetValues[0][17];
var subject = ("Laptop Loan Approved");
var body = ("Hello "+ student +", \n\nWe are happy to confirm that your laptop loan application has been approved.");
var subject2 = ("Laptop Loan");
var body2 = ("Hello "+ student +", \n\nPlease disregard last e-mail sent by us, it was mistakenly sent.");
var subject3 = ("Overdue Laptop Loan");
var body3 = ("Hello "+ student +", \n\nThe laptop you have been loaned is due to be returned.");
if(column == 10 && checkboxValue == true) {
console.log("chekbox marked true")
MailApp.sendEmail(recipient, subject, body)
} else if (column == 10 && checkboxValue == false) {
console.log("chekbox marked false")
MailApp.sendEmail(recipient, subject2, body2)
} else if(column == 18 && checkboxValue2 == true) {
console.log("chekbox marked true")
MailApp.sendEmail(recipient, subject3, body3)
} else if (column == 18 && checkboxValue2 == false) {
console.log("chekbox marked false")
MailApp.sendEmail(recipient, subject3, body2)
} else {
console.log("No clue")
}
}

Trying to match the date in the spreadsheet with today's date and send email

I have a spreadsheet which looks like this:
Date | Day | S1 | S2 | S3 | S4 | S5 | S6 |
-----------------------------------------------------------------
14/04/20 | Sun | P-1 | H-1 | E-1 | R-1 | F-1 | G-1 |
15/04/20 | Mon | P-1 | H-1 | E-3 | R-1 | F-2 | G-2 |
Intention is to send an email the schedules (S1 till S6) on that particular date.
The script would run on a particular time of the day. It will compare today's date with the date on the first column. if the date matches, the data on that row should be sent to my email address.
I have written the code as below:
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 4; //the date starts from the fourth row
var numRows = 170; //there are a total of 170 rows
var dataRange = sheet.getRange(startRow, 1, numRows, 8);
var data = dataRange.getValues();
for (var i in data) {
var row = data[i];
var dateIter = row[0];
if (dateIter.getDate() == today.getDate() &&
dateIter.getMonth() == today.getMonth() &&
dateIter.getFullYear() == today.getFullYear()) {
var sub1 = row[2];
var sub2 = row[3];
var sub3 = row[4];
var sub4 = row[5];
var sub5 = row[6];
var sub6 = row[7];
var subject = 'Things you have to study today';
var message = "You have to study today" + sub1 + ", " + sub2 + ", " + sub3 + ", " + sub4 + ", " + sub5 + ", and " + sub6 + ". All the best." ;
break;
}
}
var emailAddress = 'myemail goes here';
MailApp.sendEmail(emailAddress, subject, message);
}
I am not sure about the date functions as I wrote in my code. I am getting an error as below:
TypeError: dateIter.getDate is not a function (line 11, file "Code")
I learnt about the date functions that I wrote here in this answer https://stackoverflow.com/a/14351783/9422511
What is the proper way of doing this?
Edit:
Added what Michael has suggested. There is another error which is as shown below:
ReferenceError: today is not defined (line 12, file "Code")
I have solved the problem. I did the following:
1. Cleared the date column, re-formatted it as date. And entered the date again according to the date format in the column.
2.Modified the date portion as suggested by Michael Pearson.
3. 'Today' has been made a object as below:
var today = new Date();
I was doing a mistake initially. The mailing portion of the code is put inside the loop itself.
Here is the code:
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 4;
var numRows = 170;
var dataRange = sheet.getRange(startRow, 1, numRows, 8);
var data = dataRange.getValues();
for (var i in data) {
var row = data[i];
var dateIter = row[0];
var date = new Date(dateIter);
var today = new Date();
if (date.getDate() == today.getDate() &&
date.getMonth() == today.getMonth() &&
date.getFullYear() == today.getFullYear()) {
var sub1 = row[2];
var sub2 = row[3];
var sub3 = row[4];
var sub4 = row[5];
var sub5 = row[6];
var sub6 = row[7];
var subject = 'Things you have to study today';
var message = "You have to study today" + sub1 + ", " + sub2 + ", " + sub3 + ", " + sub4 + ", " + sub5 + ", and " + sub6 + ". All the best." ;
var emailAddress = 'email goes here';
MailApp.sendEmail(emailAddress, subject, message);
break;
}
}
}
Thanks for the suggestions.
dateIter references a cell, and therefore does not have a getDate() function.
If the cell contains a string value, you could do something like :
var date = new Date(row[0]);
if (date == today.getDate()
etc.

Automating Google Spreadsheets – Email Reminders

I have a Google Spreadsheet and have modified the code below as indicated to send an email alert 7 days before the date condition is due. This works perfectly, however it only looks at the first sheet and the spreadsheet contains 23 sheets in total. I think I need to include an array and loop the code but cannot work this out so would appreciate some help! Thanks in advance.
function checkReminder() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// set the first sheet as active
SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);
// fetch this sheet
var sheet = spreadsheet.getActiveSheet();
// figure out what the last row is
var lastRow = sheet.getLastRow();
// the rows are indexed starting at 1, and the first row
// is the headers, so start with row 2
var startRow = 7;
// grab column 14 (the 'days left' column)
var range = sheet.getRange(7, 14, lastRow - startRow + 1, 1);
var numRows = range.getNumRows();
var days_left_values = range.getValues();
// Now, grab the reminder name column
range = sheet.getRange(7, 15, lastRow - startRow + 1, 1);
var reminder_info_values = range.getValues();
// Now, grab the deceased name column
range = sheet.getRange(3, 1);
var name_of_sheet = range.getValue();
var warning_count = 0;
var msg = "";
// Loop over the days left values
for (var i = 0; i <= numRows - 1; i++) {
var days_left = days_left_values[i][0];
if (days_left == 7) {
// if it's exactly 7, do something with the data.
var reminder_name = reminder_info_values[i][0];
msg = msg + "Reminder: " + name_of_sheet + " inscription work is due in " + days_left + " days.\n";
warning_count++;
}
}
if(warning_count) {
MailApp.sendEmail("my#email.com",
"Reminder Inscription Schedule Message", msg);
}
};

Script running incorrectly for email sent when specific column has data

I have the below script that is running but marks the "Email_Sent" column for every row (all 1000), I would like it to only send an email if Column A, B or C has an entry. (This is copied from the first sheet if someone marks a Yes in a specific column) and only if the Sent_Email column is blank as well.
function sendEmails()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Email"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
for (var i = 1; i < data.length; ++i)
{
var rowData = data[i];
var emailAddress = rowData[1];
var recipient = rowData[0];
var message1 = rowData[3];
var message2 = rowData[4];
var message3 = rowData[5];
var message4 = rowData[6];
var message5 = rowData[7];
var emailSent = rowData[9];
var message = 'Hi ' + recipient + ',\n\n' + message1 + ' ' + message2 +
',\n\n' + message3 + ',\n' + message4 + ',\n' + message5;
var subject = 'Medical Questionairre Check';
if (emailSent != 'EMAIL_SENT' && MailApp.getRemainingDailyQuota()>0 &&
emailAddress && subject && message)
{
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(i+1, 9).setValue('EMAIL_SENT');// Make sure the cell is
updated right away in case the script is interrupted
}
}
}
Here is the link to the spreadsheet.
https://docs.google.com/spreadsheets/d/1SOPiXhU3KWHpHyZEiDUSk8m5qzO5CyALWio6doQvJ4Q/edit?usp=sharing
A Simple Fix
Just had to change emailSent = rowData[25] rather than rowData[9]
function sendEmails()
{
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheetByName('Sheet2');
var dataRange=sheet.getDataRange();
var data=dataRange.getValues();
for (var i=1;i<data.length;++i)
{
var rowData = data[i];
var emailAddress = rowData[1];
var recipient = rowData[0];
var message1 = rowData[3];
var message2 = rowData[4];
var message3 = rowData[5];
var message4 = rowData[6];
var message5 = rowData[7];
var emailSent = rowData[25];//Change from 9 to 25
var message = 'Hi ' + recipient + ',\n\n' + message1 + ' ' + message2 + ',\n\n' + message3 + ',\n' + message4 + ',\n' + message5;
var subject = 'Medical Questionairre Check';
var rdq=MailApp.getRemainingDailyQuota();
if (!emailSent && rdq>0 && emailAddress && subject && message)
{
MailApp.sendEmail(emailAddress, subject, message)
//Logger.log('emailAddress: %s subject: %s message: %s emailSent: %s',emailAddress,subject,message,emailSent);
sheet.getRange(i+1, 26).setValue('EMAIL_SENT');
}
}
}
The spreadsheet after execution:

Need to Set_Formula on Insert_Row from IFTTT

Novice Google Apps Scripter here,
I have an IFTTT applet which adds a row to this spreadsheet via email: Data Test
I seem to have the formulas set up correctly, but when a new row is added, the formulas obviously do not auto-populate into that new row. When a row is inserted, in which the corresponding cells in Columns A and B are not blank, I'd like set certain formulas in that row.
The script I have so far (see below) does give me the formulas I want, but only in Row1.
I'd like the script to set those same formulas into corresponding cells of any new row that is inserted.
For example, IFTTT.com automation will populate cells A6 and B6 with text (i.e., next blank row in linked spreadsheet) -- I need all of the formulas currently entered to then apply to B6 (as opposed to B2)
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var cell = sheet.getRange("C1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("details",$B2)+7,SEARCH(",",$B2)-SEARCH("details",$B2)-7),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("D1");
cell.setFormula('=IFERROR(TRIM(LEFT(SUBSTITUTE(MID(B2,FIND("$",B2),LEN(B2))," ",REPT(" ",100)),100)),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("E1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("exceed",$B2)+7,SEARCH("%",$B2)-SEARCH("exceed",$B2)-6),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("F1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("due",$B2)+3,SEARCH(";",$B2)-SEARCH("due",$B2)-3),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("G1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("held on",$B2)+7,SEARCH(". Lottery",$B2)-SEARCH("held on",$B2)-7),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("H1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("posted by",$B2)+9,SEARCH(". ",$B2)-SEARCH("",$B2)-167),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
}
Any assistance will be greatly appreciated!
Try this out:
var ss = SpreadsheetApp.getActiveSpreadsheet();
function onOpen() {
var items = [
{name: 'Add Row', functionName: 'addrow'},
];
ss.addMenu('Add Row', items);
}
function addrow() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var result = ui.prompt(
'Enter number of Row',
ui.ButtonSet.OK_CANCEL);
// Process the user's response.
var button = result.getSelectedButton();
var rownum = result.getResponseText();
if (button == ui.Button.OK) {
// User clicked "OK".
sheet.insertRowAfter(rownum);
var cell = sheet.getRange("C" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("details",$B' + rownum +')+7,SEARCH(",",$B' + rownum +')-SEARCH("details",$B' + rownum +')-7),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("D" + rownum);
cell.setFormula('=IFERROR(TRIM(LEFT(SUBSTITUTE(MID(B' + rownum +',FIND("$",B' + rownum +'),LEN(B' + rownum +'))," ",REPT(" ",100)),100)),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("E" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("exceed",$B' + rownum +')+7,SEARCH("%",$B' + rownum +')-SEARCH("exceed",$B' + rownum +')-6),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("F" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("due",$B' + rownum +')+3,SEARCH(";",$B' + rownum +')-SEARCH("due",$B' + rownum +')-3),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("G" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("held on",$B' + rownum +')+7,SEARCH(". Lottery",$B' + rownum +')-SEARCH("held on",$B' + rownum +')-7),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("H" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("posted by",$B' + rownum +')+9,SEARCH(". ",$B' + rownum +')-SEARCH("",$B' + rownum +')-167),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
} else if (button == ui.Button.CANCEL) {
// User clicked "Cancel".
} else if (button == ui.Button.CLOSE) {
// User clicked X in the title bar.
}
}
This is something that I've done in the past. I was surprised to learn that there was a setFormula command because I didn't use it in this situation and the below technique is working fine.
for(var i = 0;i < rowA[0].length; i++)
{
var initial_value = rowA[0][i];
//rowA[0][i] = '=ArrayFormula(IF(Row($B:$B)=1,"' + initial_value + '",IF(LEN($B:$B),IF(REGEXMATCH($C:$C,"(?i)(' + initial_value + ')"),$D:$D,""),)))';
rowA[0][i] = '=ArrayFormula(IF(Row(' + sr + ')=1,"' + initial_value + '",IF(LEN(' + sr + '),IF(REGEXMATCH(' + sr + ',"(?i)(' + initial_value + ')"),' + vr + ',""),)))';
}
rowrng.setValues(rowA);
It's a little different from what your doing in that I'm setting all of the array values before running the setValues command. But this has been working for months.