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.
Related
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.
I am new to coding and wanted to automate sending emails with attachments. Basically what I would like to do is to send a message and Google Drive attachment to a specific email address in my spreadsheet. Each attachment (google drive link) is different for each email address and I have everything laid out on a spreadsheet.
The spreadsheet is composed of three sheets, and I want to get the info from the first sheet only (called Full Data). The structure of the columns is the following:
A1 Full Name
B1 First Name
C1 Last Name
D1 Email Address
E1 File attachment (google drive link)
F1 Date
G1 Status
H1 Message
I1 Email Sent?
I would like to send an email with a template starting with "Hello {Full Name}," and in the row below starts the message.
Here's the code I have for now:
// This constant is written in column C for rows for which an email
// has been sent successfully.
var EMAIL_SENT = 'EMAIL_SENT';
/**
* Sends non-duplicate emails with data from the current spreadsheet.
*/
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var numRows = sheet.getLastRow() - startRow + 1; // Number of rows to process
var startCol = 1;
var numCols = 4; // Number of columns to process (should include column D)
// Fetch the range of cells A2:D
var dataRange = sheet.getRange(startRow, startCol, numRows, numCols);
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[3]; // Third column
var message = row[7]; // Eigth column
var emailSent = row[8]; // Ninth column
if (emailSent !== EMAIL_SENT) { // Prevents sending duplicates
var subject = 'Sending emails from a Spreadsheet';
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 8).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
I realize that I have not set a variable for the attachment. The attachment should be taken from column E (corresponding to the row). For example, John Apple in A2 has attachment X in E2, while Mick Orange in A3 has attachment Y in E3, and so on... The range of data goes down till 130 rows but it would be great to have something that always gets the range until there is data (no matter the number of rows).
Does anyone have an idea on how to make this work?
Thanks a lot in advance!!
If I understand you correctly, your current question differs from your previous one in that:
The message body starts with "Hello {Full Name}".
You are not looking for files with the same name as in the sheet, but files that have a certain URL.
The columns to fetch the data from are not the same.
Taking all this into account, I reworked the solution I proposed in your previous question so that it does what you pretend now (read inline comments to see what the code is doing, step by step):
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Full Data");
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow() - startRow + 1; // Number of rows to process
var startCol = 1;
var numCols = 9; // Number of columns to process (should include column D)
// Fetch the range of cells A2:D
var dataRange = sheet.getRange(startRow, startCol, numRows, numCols);
// 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[3];
var fullname = row[0];
var messageBody = row[7];
var message = "Hello ".concat(fullname, "\n", messageBody); // Creating message body
var emailSent = row[8];
var fileURL = row[4];
var fileId = fileURL.match(/[-\w]{25,}/); // Extracts file id from file url
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "Sending emails from a Spreadsheet";
var file = DriveApp.getFileById(fileId);
MailApp.sendEmail(emailAddress, subject, message, {
attachments: [file], // No need to use getAs if your file is already a PDF
name: 'Custom email Team'
});
sheet.getRange(startRow + i, 9).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
DriveApp does not have an getFileByUrl method, so to get the file, the code first extracts the file id from the url using regex and then calls getFileById.
Let me know if that works for you.
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!
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!
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;
...