How do I skip blank cells using MailApp.SendEmail? - google-apps-script

I've been using Google form to collect information to a workbook, then using that information to send customized emails back to the sender. I am a noob at coding, but I have managed to cobble together enough for this task. My problem is that, when it comes to a blank email cell it stops. I've tried to put in a loop to make it skip, with no success. Any help would be appreciated. This is the program I am using without a loop.
// This constant is written in column C for rows for which an email
// has been sent successfully.
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 2000; // Number of rows to process
// Fetch the range of cells A2:B2001
var dataRange = sheet.getRange(startRow, 1, numRows, 2001)
// 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 = "Bounce Reply";
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();
}
}
}

You can use string.match() function to determine if a cell is empty or not. Since you are looking for email address you might as well see if the cell has '#' sign. If not exclude the cell and continue on to the next cell like so:
if (emailAddress.match('#') === null){
continue; // skip this iteration of the loop and go to the next one
}
Your final code will look like:
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 2000; // Number of rows to process
// Fetch the range of cells A2:B2001
var dataRange = sheet.getRange(startRow, 1, numRows, 2001)
// 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
if (emailAddress.match('#') === null){
continue; // skip this iteration of the loop and go to the next one
};
var message = row[1]; // Second column
var emailSent = row[2]; // Third column
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "Bounce Reply";
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();
}
}
}
Edit
To check if something is empty or not you can try something like this.
if (message.match(/[a-zA-Z0-9_]/) === null) { //" /[a-zA-Z0-9_]/ " is regex to match any and every alphanumeric letter including underscore
continue; // skip this iteration of the loop and go to the next one
}
You can find more details on function match and regex here.
Hope that helps!

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)

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.

Adding multiple lines of body in script editor

I am currently using the following code in a spreadsheet to send emails.
// This constant is written in column C for rows for which an email
// has been sent successfully.
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 2; // 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 = "Sending emails from a Spreadsheet";
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();
}
}
}
In the above the message is only being processed from a single cell while i want it to use multiple cells.
Example:
the second column contains the body to be sent
how can i tweak the same.
Put the message in a single cell and format it as you wish within that cell. i.e. if you want to skip down a line or 2 hold control and press return and the cursor will go to the next line.
Get the cell in the script.
When you send the email the formatting will be retained.
You can also use '\n\n'on the script message to jump rows.

Executing the correct enteries and ignoring the wrong entries(sending email) from a google form by google app script

I have a google form which collects few details and an email-id, however if there is a wrong entry in the email, the script fails and does not execute the next row, it gets stuck there. Now i want the script to ignore the wrong entries and execute for the correct entries.I have my code below.
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow(); // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 5, 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 = "You have been registered for follwoing events:-";
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 7).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
For this you can add a if condition before this line of code
if(valid email address){
MailApp.sendEmail(emailAddress, subject, message);
}
else{continue;}
to verify if the email id has a valid value or not.
You can also check this approach.
Hope that helps!

How to fetch the row number of a Google Spread Sheet via Google Apps Script?

I have a google script I am using and I was wanting to insert the current row I am working with into a value which will be re added into a formula I set back in the spreadsheet. I want to do this in case someone resubmits the same data, so they are emailed the changes. At the moment this script is just a proof of concept for me, so I can then go on and code the entire process.
The problem I am having with the script is with the value currentRow. It seems to get the value of the first pass and then does not change it, which is problematic when you have more than one entry to process.
I use the value currentRow in the variable RESEND_EMAIL, so it can generate a formula which looks to see if the two columns are alike (I am going to use the date time stamp and copy it in just the first time to column D (also known as var resend[4]).
This way I can set the script to run automatically and check if this column is set as "Yes", in which case it will send and email again and then change the a value (shown here as email address - but I will use the timestamp instead) so that the formula RESEND_EMAIL changes resend back to "No".
How do I always ger the correct row Number in the value currentRow?
// This constant is written in column C for rows for which an email
// has been sent successfully.
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 2; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 6)
// 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
var resend = row[4];
var extension = row [5];
var currentRow = sheet.getActiveRange().getRow();
var RESEND_EMAIL = "=IF(A"+ currentRow +"=D" + currentRow +",\"No\",\"Yes\")";
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "Sending emails from a Spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 3).setValue(EMAIL_SENT);
sheet.getRange(startRow + i, 5).setFormula(RESEND_EMAIL);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
if (resend == "Yes") { // Prevents sending duplicates
var subject = "Sending emails from a Spreadsheet";
message = message + " " + extension;
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 4).setValue(emailAddress);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
As shown in your code i variable value becomes the current row.
...
var currentRow = startRow + i;
...