I am intending to send an email after 5 days comparing the timestamp in my google sheet. But it is not working.
Below is my code:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = sheet.getLastRow();
var dataRange = sheet.getRange(startRow, 2, numRows, 15)
var data = dataRange.getValues();
for (var i = 0; i < data.length; i++) {
var row = data[i];
var Timestamp = row[0];
var todaydate = new Date();
var secondDate = new Date();
secondDate.setDate(todaydate.getDate()+5);
if (Timestamp <= secondDate){
var messageHtml = "Hi " +
"<br><br>Test " +
"<br><br>test" +
"<br>Thank You<br><br>";
var message = messageHtml.replace(/\<br\/\>/gi, '\n').replace(/(<([^>]+)>)/ig, "");
// clear html tags and convert br to new lines for plain mail
var subject = "Uniform Order Form Pending Process";
MailApp.sendEmail("test#gmail.com", subject,message);
}
}
};
Sorry that maybe it might be something very simple but hope you guys can advise me.
Thanks
Try
secondDate.setDate(todaydate.getDate()+5 * 86400000);
one day is: 1000 * 60 * 60 * 24, which is 86400000 milliseconds.
Related
I have a table with 8 columns with dates. I need to track them if they are to expire, but for 3 of them I need to alert alert 3 months before and for the remaining columns, 6 months before.
I think that I am on the right track with the code below, but still not doing what it needs to be done.
I start with one month in the beginning. Can somebody help me?
function emailAlert() {
// today's date information
var today = new Date();
var todayMonth = today.getMonth() + 1;
var todayDay = today.getDate();
var todayYear = today.getFullYear();
var newToday = new Date()
var oneMonthFromToday = new Date(newToday.setMonth(newToday.getMonth()+1));
var oneMonthMonth = oneMonthFromToday.getMonth() + 1;
var oneMonthDay = oneMonthFromToday.getDate();
var oneMonthYear = oneMonthFromToday.getFullYear();
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = 100;
var dataRange = sheet.getRange(startRow, 1, numRows, 999);
var data = dataRange.getValues();
//looping through all of the rows
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var expireDateFormat = Utilities.formatDate(
new Date(row[6]),
'ET',
'MM/dd/yyyy'
);
var subject = '';
var message = ' You have expiring pass. ' + '\n';
MailApp.sendEmail('lubomira.petkova88#gmail.com', subject, message);
}
It is not clear on your post but the code below assumed only 1 column needs to be checked. Feel free to adjust the conditions but this should be the main idea of your code.
Code:
function checkPasswordExpiry() {
// today's date information
var today = new Date();
today.setHours(0,0,0,0);
// 3 months before
var prev3Months = new Date();
prev3Months.setMonth(today.getMonth() - 3);
prev3Months.setHours(0,0,0,0);
// 6 months before
var prev6Months = new Date();
prev6Months.setMonth(today.getMonth() - 6);
prev6Months.setHours(0,0,0,0);
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
// get number of rows/columns in sheet instead of manually setting it
var numRows = sheet.getLastRow();
var numCols = sheet.getLastColumn();
var dataRange = sheet.getRange(startRow, 1, numRows, numCols);
var data = dataRange.getValues();
//looping through all of the rows
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var expireDateFormat = Utilities.formatDate(
new Date(row[6]),
'ET',
'MM/dd/yyyy'
);
var date = new Date(row[6]);
date.setHours(0,0,0,0);
var subject = 'Password Expiry';
var message = 'Hi ' + row[0] + ', \nYour password is expiring';
var email = 'lubomira.petkova88#gmail.com';
if(date.getTime() === prev6Months.getTime()) {
message += " in 6 months. ( " + expireDateFormat + " )";
MailApp.sendEmail(email, subject, message);
}
else if(date.getTime() === prev3Months.getTime()) {
message += " in 3 months. ( " + expireDateFormat + " )";
MailApp.sendEmail(email, subject, message);
}
else if(date.getTime() === today.getTime()) {
message += " today. ( " + expireDateFormat + " )";
MailApp.sendEmail(email, subject, message);
}
}
}
The code above does check column G whether it is already 6 months before today, 3 months before today or exactly the date. If you need to check multiple columns, just replace the conditions inside and it should still work.
Sample email:
Note that the code above should be triggered every day so it can check the data daily.
Code:
function createTimeDrivenTriggers() {
ScriptApp.newTrigger('checkPasswordExpiry')
.timeBased()
.everyDays(1)
.atHour(0)
.create();
}
Function createTimeDrivenTriggers needs to be run just once. Please see reference below.
Reference:
Time driven triggers
everyDays()
If I wasn't able to provide you the answer you are hoping for, I sincerely apologize. Feel free to comment below what are the changes that are needed to be done.
I'm trying to put on some Google Function to make that in the title. I'm very beginner but I'm up for the challenge. I managed to make a button that clears the whole range (C5:G102).
But I want now a code that clears that range only for the dates that are older than today.
I have columns with subject, a deadline, description, etc. The whole date goes from column C to G. So when I click the button I want all subjects in that row that already has an older deadline than today, to be cleared out. The dates are in the column D.
Can that be done?
I have only this:
function clearRange() {
//replace 'Sheet1' with your actual sheet name
var sheet = SpreadsheetApp.getActive().getSheetByName('ADD');
sheet.getRange('C5:G102').clearContent();
}
So, after some trying I came up with this: but it doesn't work...
function ClearOlder() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('ADD');
var lastRow = sheet.getLastRow();
var columnD = sheet.getRange(2, 4, sheet.getLastRow(), 1).getValues();
var day = 24*3600*1000
var today = parseInt((new Date().setHours(0,0,0,0))/day);
for (var i=1; i < columnD.length; i++) {
var dataday = parseInt(new Date(columnD[i][4]).getTime()/day);
if (dataday < today) {sheet.getRange(i+1, 4, lastRow, 1).clearContent();}
}
}
You can actually compare date directly in javascript. You do not need the parseInt() function.
var TEN_DAYS = 10 * 24 * 60 * 60 * 1000;
// days hrs min sec ms
var expiry = new Date() - TEN_DAYS;
var date1 = new Date('2019-02-5');
var date2 = new Date('2019-02-1');
var date3 = new Date('2019-01-25');
console.log(expiry > date1); //Less than 10 days ago
console.log(expiry > date2); //Less than 10 days ago
console.log(expiry > date3); //More than 10 days ago
Updated: Your columnD selector was off.
function clearOlder() {
//consider camelCase --> clearOlder()
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sheet.getLastRow();
var columnD = sheet.getRange(2, 4, sheet.getLastRow(), 1).getValues(); //OP updated this to better fit their specific spreadsheet.
var one_day = 24*3600*1000;
var expiry = new Date() - one_day;
for (var i=1; i < columnD.length; i++) {
var dataday = new Date(columnD[i][0]);
if (expiry > dataday) {
sheet.getRange(i+1, 1, 1, 4).clearContent(); //OP updated this to better fit their specific spreadsheet.
}
}
}
Yes! I got it!!!
function clearOlder() {
//consider camelCase --> clearOlder()
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sheet.getLastRow();
var columnD = sheet.getRange(1, 4, sheet.getLastRow(), 5).getValues();
var one_day = 24*3600*1000;
var expiry = new Date() - one_day;
for (var i=1; i < columnD.length; i++) {
var dataday = new Date(columnD[i][0]);
if (expiry > dataday) {
sheet.getRange(i+1, 1, 1, 5).clearContent();
}
}
}
I have a Spreadsheet with many sheets inside it, Each sheet represents one month, and has dates in column B. I'm trying to create a function that searches for the current date and inserts the current time in column C. I've got a function to work by specifying the sheet, but I want it to find the sheets itself.
I've got the following code:
function insertTime() {
var date = new Date();
var hours = date.getHours()
var minutes = date.getMinutes()
var timeStamp = hours + ':' + minutes
var ss = SpreadsheetApp.getActiveSpreadsheet()//// get the sheet
var sheets = ss.getSheets();// get all the sheets
var today = new Date(); //get todays date
for (var sheetNum = 1; sheetNum < sheets.length; sheetNum++){
var sheet = ss.getSheets()[sheetNum]
var columnB = sheet.getRange(2, 2, sheet.getLastRow()-1, 1); // get all the rows
var bValues = columnB.getValues(); // get the values
for (var i = 0; i < bValues.length; i++) { // repeat loop
var fDate = new Date(bValues[i][0]);
if (fDate.getDate() == today.getDate() &&
fDate.getMonth() == today.getMonth() &&
fDate.getFullYear() == today.getFullYear()) { // if the date in the cell is today's date...
sheet.getRange(i + 2, 3, 1, 1).setValue(timeStamp);
}
}
}
}
Which is giving me the following error: "The coordinates or dimensions of the range are invalid. (line 16)"
At least one of your sheets is empty or has only 1 row of data.
In this case on line 16, sheet.getLastRow()-1 will be 0 or -1 which is creating the error.
I figured it out in the end, I used the forEach function:
function myFunction(){
var date = new Date();
var hours = date.getHours()
var minutes = date.getMinutes()
var timeStamp = hours + ':' + minutes
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
sheets.forEach (function (sheet) {
var columnB = sheet.getRange(2, 2, 70, 1);
var bValues = columnB.getValues();
var today = new Date();
for (var i = 0; i < bValues.length; i++) {
var fDate = new Date(bValues[i][0]);
if (fDate.getDate() == today.getDate() &&
fDate.getMonth() == today.getMonth() &&
fDate.getFullYear() == today.getFullYear()) {
sheet.getRange(i + 2, 7, 1, 1).setValue(timeStamp);
}
}
}
Trying to send an email to a list in a Google Sheet, but only if column N gets marked "Yes." Acceptable data in column N is "Yes" or "No" so I want to test that and send emails only to the rowData that contain "yes" there. Then write the date in the adjacent column on the same row. I can't seem to figure out how to iterate through the array of objects and couldn't find any good resources to explain this. Help greatly appreciated. My best effort was emailing all the rows and then also filling in the date no matter what was in column N (Yes/No/Blank).
function sendEmails() {
validateMySpreadsheet() //a function that checks for "Yes" in column N
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getActiveSheet();
var dataRange = dataSheet.getRange(2, 1, dataSheet.getMaxRows() - 1, 16);
var d = new Date();
var dd = d.getDate();
var mm = d.getMonth() + 1; //Months are zero based
var yyyy = d.getFullYear();
var date = mm + "/" + dd + "/" + yyyy;
var needsaYes = "Yes";
//Gets the email template
var templateSheet = ss.getSheetByName("Template");
var emailTemplate = templateSheet.getRange("A1").getValue();
// Create one JavaScript object per row of data.
objects = getRowsData(dataSheet, dataRange);
//This is where I am stuck - how to check if column N contains a "Yes" before allowing the MailApp.SendEmail command to run.
for (var i = 0; i < objects.length; ++i) {
// Get a row object
var rowData = objects[i];
var values = dataRange.getValues();
for (var j = 0; j < values.length; ++j) {
var row = values[j];
var checkFirst = row[13]; //row J, Column N?
if (checkFirst = needsaYes) { //does column N contain "Yes"?
var emailText = fillInTemplateFromObject(emailTemplate, rowData);
var emailSubject = "mySubject";
MailApp.sendEmail(rowData.email, emailSubject, emailText);
dataSheet.getRange(2 + i, 15).setValue(date); //then write the date
SpreadsheetApp.flush();
}
}
}
}
I didn't check whole code but
if (checkFirst = needsaYes)
It may be the problem, you need to use ==
I figured it out I needed to just use the .getValues() method for my data range rather than the whole sheet and also remove the unnecessary second for loop:
var rowData = objects[i]; var checkData = ss.getActiveSheet().getDataRange().getValues();
var row = checkData[i]
var colN = row[13] if (colN == needsaYes) { //etc.
Apologies in advance - I am not a programmer. Just trying to piece together something for my business. Currently, I have a script that references a spreadsheet and sends out an automated email to my receptionist. This script provides all of the information I'd like it to but problem is that it sends out a separate email for every entry. Ideally, I would like to send a single email to my receptionist that contains a list of all of the appointments for the upcoming day.
Issues I'm having include:
I need to consolidate multiple emails into a single email containing a list of the upcoming appointments for the next day.
I don't know how to select the rows I need because they are date values (DD/MM/YYYY). So I'm Looking for a way to read the date, recognize that it is one day before the appointment, and add these entries to a single list.
If anyone can help me out with this it would be greatly appreciated!
Here's what I have so far:
function receptionist() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 2; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, 8)
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[2];
var timeslot = sheet.getRange(i+2,7,1,1).getValues();
var name = sheet.getRange(i+2,2,1,1).getValues();
var date = Utilities.formatDate(new Date(sheet.getRange(i+2,6,1,1).getValue()),"EST", "E MMM dd, yyyy");
var receptionist= name+" scheduled on "+date+" at "+timeslot;
var subject = "Appt. List";
var emailAddress = "receptionist#example.com";
MailApp.sendEmail({emailAddress, subject, receptionist});
Thanks in Advance!
I've tested this code, and it works:
function receptionist() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 2; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, 8)
var data = dataRange.getValues();
var receptionist = "Today's Appointments \r\r";
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[2];
var timeslot = sheet.getRange(i+2,7,1,1).getValue();
var name = sheet.getRange(i+2,2,1,1).getValue();
var dateData = sheet.getRange(i+2,6,1,1).getValue();
var dayOfAppointment = dateData.getFullYear() + dateData.getMonth() + dateData.getDate();
var todaysDate = new Date();
var todaysDayNumber = todaysDate.getFullYear() + todaysDate.getMonth() + todaysDate.getDate();
if (todaysDayNumber === dayOfAppointment) {
var date = Utilities.formatDate(new Date(),"EST", "E MMM dd, yyyy");
var thisAppointment = name+" scheduled on "+date+" at "+timeslot + "\r";
receptionist+=thisAppointment;
};
};
var subject = "Appt. List";
var emailAddress = "receptionist#example.com";
MailApp.sendEmail(emailAddress, subject, receptionist);
};
You do need a for loop. I removed the curly braces from the .sendEmail() parameters. Note the "\r" values to wrap each line to a new line. This Line:
receptionist+=thisAppointment;
makes the receptionist variable longer by one appointment line on each iteration. I didn't go through every line of code to determine whether the code is optimal or not. The basics of what you need are there. It may work "as is".