I am trying to make an auto emailer with the google sheets script tool and I took this code directly from google and did some very minor adjustments so it will add subject and so i can better understand it...or so i thought, it sends emails fine but evert test email i get does not have a subject.
sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // Starts at row 2, row 1 has all the titles
var numRows = 2; // Allows the HORIZONTAL rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, 2); // Set range to process
var data = dataRange.getValues(); //Assign values to the range
for (var i in data) {
var row = data[i];
var emailAddress = row[0]; // First column (email address)
var message = row[1]; // Second column (message)
var subject = row[2]; // Third column (subject)
MailApp.sendEmail(emailAddress, subject, message);
}
}
furthermore if there is any other way for me to do this cleaner then I am open for more advice and tips. thank you.
Issue with your code:
In your script, sheet.getRange(startRow, 1, numRows, 2) is used as the range for retrieving the values. In this case, the columns "A" and "B" are retrieved.
Solution
The subject is put in the column "C", please modify to sheet.getRange(startRow, 1, numRows, 3). By this, var subject = row[2] has the value of the column "C".
Reference
getRange(row,column,numrows,numcolumns)
– Tanaike
Related
Stack overflowers!
I have a problem with my Sendemail Script, which is sending the same message for 8 times (really annoying, isn't it?) to each mail address. (It has been working fine until today though, I send remainders to five people daily; and my google sheet has two columns, one is for email address and the other is the message)
My code looks like this:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 5; // Number of rows to process
// Fetch the range of cells A2:B6
var dataRange = sheet.getRange(startRow, 1, numRows, 5);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i in data) {
var row = data[I];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var subject = 'ATTENTION!!!!!!';
MailApp.sendEmail(emailAddress, subject, message);
}
}
How can I solve this annoying problem? (I am not a developer; I am just a learner who can use internet sources very well; So, I don't understand scripts much and still can edit or change it a bit.)
There is currently a bug with time-driven triggers
As a consequence, the trigger might fire multiple times - more frequent than you specify.
You can "star" the issue on Google's Issue Tracker to indicate that you are also concerned.
In the meantime, as a workaround:
Use Script Properties to save the last execution time
Implement an if statement at the beginning of your code that executes the rest of the code only if the last execution time (retrieved from the script properties) is not less than the specified interval
Sample:
function sendEmails() {
if(!PropertiesService.getScriptProperties().getProperty("lastExecution")){
PropertiesService.getScriptProperties().setProperty("lastExecution", new Date().getTime());
}
var lastExecution = PropertiesService.getScriptProperties().getProperty("lastExecution");
var now = new Date().getTime();
var oneDay = 1000*3600*24;
if(now-lastExecution >= oneDay){
//here the rest of you code
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 5; // Number of rows to process
// Fetch the range of cells A2:B6
var dataRange = sheet.getRange(startRow, 1, numRows, 5);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i in data) {
var row = data[I];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var subject = 'ATTENTION!!!!!!';
MailApp.sendEmail(emailAddress, subject, message);
PropertiesService.getScriptProperties().setProperty("lastExecution", now);
}
}
}
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.
New to Google Scripts so I'm bumping my head on this entry level code. I want to send an email based on a specific sheet in a spreadsheet. The tab or sheet is named 'Test 2'. Currently this is my code.
/* Sends emails with data from the current spreadsheet.*/
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var startRow = 2; // First row of data to process
var numRows = 2; // Number of rows to process
var dataRange = getRange(startRow, 1, numRows, 2); // Fetch the range of cells A2:B6
var data = dataRange.getValues(); // Fetch values for each row in the Range.
for (var i in data) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var subject = 'THIS IS A TEST';
MailApp.sendEmail(emailAddress, subject, message);
}
}
And right now it's throwing this error.
ReferenceError: "getRange" is not defined. (line 8, file "Code")
How can I get it to run while referencing that sheet 'Test 2'?
Thanks!
You want to avoid the error of "getRange" is not defined..
You want to retrieve the values from the cell "A2:B6" of the sheet Test 2.
If my understanding is correct, how about the following modification?
From:
var dataRange = getRange(startRow, 1, numRows, 2);
To:
var dataRange = sheet.getSheetByName("Test 2").getRange("A2:B6");
Note:
In this case, at first, retrieve the sheet object of Test 2 and use the method of getRange for the sheet object.
I thought that a1Notation might be suitable for your situation.
Reference:
getSheetByName()
getRange(a1Notation)
If I misunderstood your question and this was not the direction you want, I apologize.
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.
script failing with Invalid email: undefined (line 29, file "newCode")
Have worked through some errors but am stuck on this.
Besides the error message I found a debugger option and ran that.
It didn't make a lot of sense but this line seem to match the complaint.
"emailAddress undefined"
I feel like it might have to do with what I've done here:
var emailAddress = row[3]; // columnD
All I think I did in the borrowed code was change which column I want to pull the info from. In this case an email address. As far as I know Column D in Google Sheets is referenced as "3" ColA=0, ColB=1...ColD=3.
I can't hard code the email address as it will vary one row to the next.
Can someone advise how this is in error?
function Initialize() {
var triggers = ScriptApp.getProjectTriggers();
for(var i in triggers) {
ScriptApp.deleteTrigger(triggers[i]);
}
ScriptApp.newTrigger("SndMail()")
.forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet())
.onFormSubmit()
.create();
}
// Write a value to column G for rows where an email sent successfully and sends non-duplicate emails with data from the current spreadsheet.
function SndMail() {
var EMAIL_SENT = 'Sent';
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 75; // Number of rows to process.
// Fetch the range of cells A2:G76
var dataRange = sheet.getRange(startRow, 2, 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 = row[3]; // columnD
var message = 'Please create a Logistics Case and log the CAS# for: <br/> row[4 + 5]'; // columnE
var mailout = row[6]; // columnG
if (mailout != EMAIL_SENT) { // Prevents sending duplicates
var subject = 'Logistics Claim case request';
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 3).setValue(Sent);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
What should be happening is that when a google form is submitted the sheet is updated and a script runs to email the intended recipient (email addy in Column D) and subsequently put the text "Sent" in Column G. Which is then filters subsequent function runs, avoiding duplicate email sends.
How about this modification?
Modification point:
When value is retrieved from sheet.getRange(startRow, 2, numRows), only column "B" is retrieved.
By this, var emailAddress = row[3] becomes undefined.
I think that the reason of your issue is this. In order to avoid the error, how about modifying as follows?
Modified script:
From:
var dataRange = sheet.getRange(startRow, 2, numRows);
To:
var dataRange = sheet.getRange(startRow, 2, numRows, sheet.getLastColumn());
or
var dataRange = sheet.getRange(startRow, 2, numRows, 7); // A2:G76 ?
Reference:
getRange(row, column, numRows, numColumns)
If I misunderstood your question, I apologize.