Google app script trigger not sending email - google-apps-script

Please can someone show me the error here (I think it will be very obvious for someone who has any knowledge of coding)? I have cobbled this script together from various sources but it does not work - the logic is correct as it works with the standard Google triggers (which i do not think I can use as I want to send email only in office hours Mon - Friday). Thanks in advance;
`enter code here`function startCustomTrigger()
{
ScriptApp.newTrigger('StartProcess').timeBased().everyHours(1).create();
}
function StartProcess() {
var date = new Date();
var day = date.getDay();
var hrs = date.getHours();
if ((day >= 2) && (day <= 6) && (hrs >= 8) && (hrs <= 18)) {
// Get the sheet where the data is, in sheet 'Mail'
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Mail")
var startRow = 2; // First row of data to process since there is a header row
var numRows = sheet.getRange(1,5).getValue(); // Number of rows to process is set by a formula which
counts rows
// Fetch the range of cells A2:B6 where the emails and messages are
var dataRange = sheet.getRange(startRow, 1, numRows, 2)
// Fetch values for each row in the Range to input into the mailing system
var data = dataRange.getValues();
// This processes the emails you want to send
for (i in data) {
var row = data[i];
var emailAddress = row[0]; // First column is the email address
var message = row[1]; // Second column is the message
var subject = row[1]; // This is the subject of the email
// This parses the data for the email to send
MailApp.sendEmail(emailAddress, subject, message);
}
}
}

You have these two declarations:
var message = row[1]; // Second column is the message
var subject = row[1]; // This is the subject of the email
one must be incorrect
Try it this way:
function StartProcess(e) {
var day = e['day-of-week'];//available from event object but a little different than that which comes from Date().getDay()
var hrs = e.hour;//available from event object
if ((day >= 1) && (day <= 5) && (hrs >= 8) && (hrs <= 18)) {
const ss=SpreadsheetApp.getActive();
// Get the sheet where the data is, in sheet 'Mail'
var sheet=ss.getSheetByName("Mail")
var startRow=2; // First row of data to process since there is a header row
var numRows=sheet.getRange(1,5).getValue(); // Number of rows to process is set by a formula which counts rows
// Fetch the range of cells A2:B6 where the emails and messages are
var dataRange = sheet.getRange(startRow, 1, numRows, 2)
// Fetch values for each row in the Range to input into the mailing system
var data = dataRange.getValues();
// This processes the emails you want to send
for (var i=0;i<data.length;i++) {
var row = data[i];
var emailAddress = row[0]; // First column is the email address
var message = row[1]; // Second column is the message
var subject = row[2]; // This is the subject of the email
// This parses the data for the email to send
MailApp.sendEmail(emailAddress, subject, message);
}
}
}
JavaScript getDay()
timebased event objec
If you continue to have problems please provide an image of Mail Sheet.

Related

Send the reminder email as per reminder date in google sheet

Given
Column G is having the expected return date(i.e. reminder date).
Column J is having email address stored
Column L is having return status
Need
Need to send the reminder email(email address Col J) on the reminder date(COl G) if the Column L (Return_Status) is blank.
I already have a code written, can't figure out the exact issue why it is not working.
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails() {
var today = new Date().toLocaleDateString(); // Today's date, without time
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 999; // Number of rows to process
// Fetch the range of cells A2:B999
//var dataRange = sheet.getRange(startRow, 1, numRows, 999)
//var dataRange= sheet.getRange("Form Responses 1!A1:L");
var dataRange= sheet.getRange(startRow,numRows)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = "dummy#gmail.com";
var subject = "RC Reminder # "+row[3];
var message = "Reminder for "+row[4]+" RC of vehicle"+row[3]+" handed over to "+row[5]+" against "+row[2]+" on "+row[0];
var emailSent = row[10];
var reminderDate = new Date(row[6]).toLocaleDateString();
if (reminderDate != today) // Skip this reminder if not for today
continue;
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
MailApp.sendEmail(emailAddress, subject, message,{name:'Sam'});
sheet.getRange(startRow + i, 11).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
In this line of code you're just getting the value of one cell
var dataRange= sheet.getRange(startRow,numRows)
getRange(row, column)
You should change it to:
var dataRange = sheet.getRange(startRow, 1, sheet.getLastRow()-1,sheet.getLastColumn())
getRange(row, column, numRows, numColumns)
This way you will only iterate through the values that are in your sheet and you will not work through empty data. If you have several sheets in your spreadsheet try consider to work with the one you have the data, accesing to the right one like this:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('NAME OF YOUR SHEET');
getSheetByName(name)

App Script - Send Email based on days left to date - Can't make script send it X days left to date

I am using this spreadsheet Here
I am trying to send an email to a specific recipient "email#myemail.com" when there are 3 days left for a specific date.
Each row represents a person and I want the email sent to send me an email for each person whose date of offboarding - date of today is exactly 3 days.
This is my output: Email received
This is the script i am using:
function Offboarding_Reminder() {
// get the spreadsheet object
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
var startRow = 2;
// grab column 11 (the 'days left' column)
var range = sheet.getRange(2,12,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var days_left_values = range.getValues();
// Now, grab the user name column
range = sheet.getRange(2, 1, lastRow-startRow+1, 1);
var reminder_name = range.getValues();
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 == 3) {
// if it's exactly 3, do something with the data.
var user_name = reminder_name[0][i];
msg ="Reminder:"+reminder_name+" offboarding is due in "+days_left+" days.\n";
warning_count++;
}
}
if(warning_count) {
MailApp.sendEmail("email#myemail.com","Reminder Offboarding",msg)
}
};
Two things I don't understand:
Why is my sent email giving me all the user emails instead of just the ones that have days_left == 3?
To automate this script, once it works, I should just add a trigger to the appscript?
Thanks for the help!
I actually revised your code since it wasn't optimized. It had a lot of redundant and unnecessary lines.
Here are the changes:
fetched the range from user column to days_left column once, not separately
created array to store users matching the condition
formatted the email to look better.
Code:
function offboardingReminder() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// set active sheet to first sheet
spreadsheet.setActiveSheet(spreadsheet.getSheets()[0]);
var sheet = spreadsheet.getActiveSheet();
// figure out what the last row is
var lastRow = sheet.getLastRow();
var startRow = 2;
// grab all data from user to days left
var range = sheet.getRange(startRow, 1, lastRow - startRow + 1, 12);
var values = range.getValues();
var users = [];
// loop all data per row
values.forEach(function(row) {
// if days left is 3
if(row[11] == 3) {
// add user if 3 days left
users.push(row[0]);
}
});
// if users has elements
if(users) {
// Formatted the message as html to look nicer
var message = "<html><body><h1>Reminder!!!</h1><p>The following user/s offboarding is due in 3 days:</p>";
// created bulleted list for list of users
var emails = "<ul>";
users.forEach(function(user){
emails = emails + "<li>" + user + "</li>";
});
emails += "</ul>";
message = message + emails + "</body></html>";
MailApp.sendEmail("email#myemail.com", "Reminder Offboarding", "", {htmlBody: message, noReply: true});
}
}
Sample data:
Sample output:
Note:
You can calculate the days left in script instead, but if it is already needed in sheets, then reusing it would be fine.
I populated the days left column via formula =DAYS(C2,TODAY()) for row 2 (dragged for other rows)

Sending Email using google script

Can anyone help me with sending an email via google scripts?
Here the challenge I am facing is that the range of the first column (email) may go up to 1000 lists of the email addresses. Although, now it's working fine (for now) how can I make it a dynamic range of list to be fed over my email lists to the script.
Code:
// This constant is written in column C for rows for which an email
// has been sent successfully.
var EMAIL_SENT = 'Email Success!';
/**
* Sends non-duplicate emails with data from the current spreadsheet.
*/
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Script (Beta)");
var startRow = 2; // First row of data to process
var numRows = 3; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 3);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var emailSent = row[2]; // Third column
if (emailSent !== EMAIL_SENT) { // Prevents sending duplicates
var subject = '[Auto] The Process Has Not Yet Been Started';
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 3).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
Doc Link
In order to make your range dynamic, you could use Sheet.getLastRow(), which returns the position of the last row with content.
Assuming that function sendEmails2 is the one your using for this, you would just have to modify the variable numRows. You would have to change this line:
var numRows = 3; // Number of rows to process
To this one:
var numRows = sheet.getLastRow() - startRow + 1;
Reference:
Sheet.getLastRow()
I hope this is of any help.

How to get an email sent from only the last row of my form

I am very new to coding and I can't figuer out what I am doing wrong. I need 1 email sent from the last entry in my form. So as the students submit their pre-test they get an email that contains the result of their pre-test.
This is what my code looks like:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 3; // First row of data to process
var numRows = 1; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 3, numRows, 1)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[1]; // Second column
var message = row[2]; // Third column
var subject = "Résultat de formatif";
// This logs the value in the very last cell of this sheet
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
var lastCell = sheet.getRange(lastRow, lastColumn);
Logger.log(lastCell.getValue());
MailApp.sendEmail(emailAddress, subject, message);
}
}
I do that by:
adding a separate column "STATUS" to the sheet
in your email sending function iterate over rows and act only on rows with "STATUS" being blank
after successfully sending email for a row, put something to the "STATUS" column
Please review the event object documentation.
You can install a "trigger" to automatically run your script on every form submission. Because this is triggered per submission, you don't need to worry about trying to find the last row or if the email had already been sent.
function sendEmails(formResponse) {
var answers = formResponse.values;
var emailAddress = answers[1]; // Second column
var message = answers[2]; // Third column
var subject = "Résultat de formatif";
// This logs the value in the very last cell of this sheet
var range = formResponse.range;
var row = range.getRow();
var column = range.getLastColumn();
try {
MailApp.sendEmail(emailAddress, subject, message);
} catch (e) {
console.error("Did not send email to " + emailAddress + ". See error: " + e);
range.getSheet().getRange(row, column+1).setValue("EMAIL NOT SENT");
return;
}
range.getSheet().getRange(row, column+1).setValue("EMAIL SENT");
}

Date Search for Automatic Reporting - Google Docs

Ok I've been through this site forward and backward before asking this but for some reason I can't get the code I've implemented to work automatically. I just need the script to run (I setup a trigger already) to check the email in column 3 of sheet 5 (called Reports). I need it to send me an email with column 1 data and column 2 data if today's date matches the date given.
Can someone look at the code and give me a little help?
function sendEmails() {
var spreadsheet = SpreadsheetApp.openById('Unique ID for spreadsheet');
var sheet = spreadsheet.getSheets()[4];
var startRow = 2; // First row of data to process
var numRows = 250; // Number of rows to process
// Fetch the range of cells
var dataRange = sheet.getRange(startRow, 1, numRows, 4)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
var emailAddress = 'email#email.com';
var subject = "Report Today";
for (i in data) {
var row = data[i];
if( row[3] == true) {
var message = row[0]+row[1];
try {
MailApp.sendEmail(emailAddress, subject, message);
} catch(errorDetails) {
MailApp.sendEmail("Email#email.com", "sendEmail script error", errorDetails.message);
}
}
}
}
Make sure that the dates match to be able to compare them, by setting the time (hours, mins, secs) equal to 0.
function sendEmails() {
var spreadsheet = SpreadsheetApp.openById('[Spreadsheet_Id]');
var sheet = spreadsheet.getSheets()[4];
var startRow = 2; // First row of data to process
var numRows = 10; // Number of rows to process
// Fetch the range of cells
var dataRange = sheet.getRange(startRow, 1, numRows, 4);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
var emailAddress = 'email#email.com';
var subject = "Report Today";
var today = new Date();
today.setHours(0,0,0,0);
for (i in data) {
var row = data[i];
row[3].setHours(0,0,0,0);
if( row[3] == today ) {
Logger.log("Send email with: " + row);
var message = row[0]+row[1];
try {
MailApp.sendEmail(emailAddress, subject, message);
} catch(errorDetails) {
MailApp.sendEmail(emailAddress, "sendEmail script error", errorDetails.message);
}
}
}
}