how to use GmailApp.Sendemail when certain conditions are met? - google-apps-script

I have 5 columns (C2:C, E2:E, F2:F, J2:J, L2:L) in a sheet that i'd like to use when certain conditions are met to send an email
if F2:G <= E2:E, send email with subject like "check out C2:C"
if E2:E >= L2:L AND J2:J <> "", send email with subject like "take a look at C2:C"
I did a bit of searching and found 2 different instances to check for a condition and to send email but not able to put the 2 together to make it work like the above. Below are 2 different scripts, one is commented out just to show what i was working with...
Here is what I have so far:
function Alert() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Display");
var ERange = sheet.getRange("E2:E").getValues();
var FRange = sheet.getRange("F2:F").getValues();
var results = [];
for(var i=0;i>ERange.length;i++){
if(ERange[i]<=FRange[i]){
results.push("this line met conditions3 "+(i+2)); // +2 because the loop start at zero and first line is the second one (E2)
}
}
MailApp.sendEmail('xx#yy.com', 'subject', results.join("\n"));
};
//function AlertEmails() {
// var ss = SpreadsheetApp.getActiveSpreadsheet();
// ss.setActiveSheet(ss.getSheetByName("EmailDetails"));
// var sheet = SpreadsheetApp.getActiveSheet();
// var dataRange = sheet.getRange("A2:C3");
// var data = dataRange.getValues();
// for (i in data) {
// var rowData = data[i];
// var emailAddress = rowData[1];
// var recipient = rowData[0];
// var message1 = rowData[2];
// var message = 'Dear ' + recipient + ',\n\n' + message1;
// var subject = 'googleSheets test automated script!';
// GmailApp.sendEmail(emailAddress, subject, message);
// }
//}
thanks guys!!

I would write it like this:
function Alert() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheetByName("Display");
var Evalues=sheet.getRange(2,5,sheet.getLastRow()-1,1).getValues();
This range format is a little less error prone. With E2:E you often get nulls between the bottom of data and maxrows.
var Fvalues=sheet.getRange(2,6,sheet.getLastRow()-1,1).getValues();
var results=[];
In the following line you have i>Evalues.length which is not true so it
terminated immediately.
for(var i=0;i<Evalues.length;i++){
You and I both left out the column indices. I just added them into the line below:
if(Evalues[i][0]<=Fvalues[i][0]){
results.push("This line met conditions3 "+(i+2));
}
}
MailApp.sendEmail('xx#yy.com', 'subject',results.join("\n"));
}

Related

send mail with attachment in each row on google app script

I use attachment in each cell to send mail auto.
Note:
column 0: Firstname Column 4: Email Address Colum 5: Year Column 6: File Attachment.
var EMAIL_SENT = 'EMAIL_SENT';
//Sends non-duplicate emails with data from the current spreadsheet.
function autosendEmails() {
var ws = SpreadsheetApp.openById('Your Sheet Id');
var sheet= ws.getSheetByName('Mail Merge');
var startRow = 2; // First row of data to process
var numRows = ws.getLastRow(); // Number of rows to process // Fetch the range of cells E2:H3
var dataRange = sheet.getRange(startRow, 1, numRows, 7);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
// var FileID = DriveApp.getFileById('Your File Id')
for (var i = 0; i < data.length; i++) {
var row = data[i]; var emailAddress = row[4]; // First column
var Subjectmail ="Test mail"
var bodyemail = "Dear"
var pdfname = row[6];
var emailSent = row[7]; // Four column
if (emailSent !== EMAIL_SENT) {
// Prevents sending duplicates
var subject = 'Test mail';
MailApp.sendEmail(emailAddress, Subjectmail, bodyemail, {attachments: pdfname});
sheet.getRange(startRow + i, 8).setValue(EMAIL_SENT); // Make sure the cell is updated right away in case the script is interrupted SpreadsheetApp.flush();
}
}
}
Taking into consideration you're retrieving the file name from var pdfname = row[6]; , then what you must do to attach the file to your mail and send it, it's to retrieve the actual file from your drive and putting it into an array as I did in this example:
// Inside your function, just change this line
function autosendEmails() {
...
MailApp.sendEmail(emailAddress, Subjectmail, bodyemail, {
attachments: buildAttachment(pdfname) // Call this function to be able to send an attachment file
});
...
}
// Add this function to your code
function buildAttachment(pdfname){
// Initialize the array
var fileArr = [];
// Get the file form your drive
var getMyFile = DriveApp.getFilesByName(pdfname).next();
// build an array
fileArr.push(getMyFile);
// return the file within an array
return fileArr;
}
Reference
This post could help you, too.
Docs
Class MailApp
Class DriveApp
This might work better for you:
Read the comments for explanation.
function autosendEmails() {
var ws = SpreadsheetApp.openById('Your Sheet Id');
var sheet= ws.getSheetByName('Mail Merge');
var startRow = 2; // First row of data to process
var dataRange = sheet.getRange(startRow, 1, sheet.getLastRow()-1,sheet.getLastColumn());//you were missing your last column and you were grabbing an empty row and the end of your list because the third parameter is the number of rows in the data not the number of rows in the sheet.
var data=dataRange.getValues();
for (var i=0;i<data.length;i++) {
var row=data[i];
var emailAddress = row[4]; // First column
var Subjectmail ="Test mail"
var bodyemail = "Dear"
var pdfname = row[6];
var emailSent = row[7]; // Four column
if (emailSent !== "EMAIL_SENT") {
MailApp.sendEmail(emailAddress, Subjectmail, bodyemail, {attachments: ["an array of files"]});//attachments should be an array of files not an array of filenames
sheet.getRange(startRow + i, 8).setValue(EMAIL_SENT);
}
}
}
This is an example I normally use
function SendMailFC() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var message ="HELLO"
for (var i = 2; i <= 3; i++) {
var row = values[i];
var mail = row[7];
var name = row[4].substring(0,row[4].indexOf(" ",row[4].indexOf(" ")+1));
var company = row[1].substring(0,row[1].indexOf(","));
var Greeting = 'Hello ' + name+',<br><br>';
var stat = row[10];
var subject = "SUBJECT";
if(stat){
GmailApp.sendEmail(FROM, subject, "", {htmlBody: '<html>'+greeting+message+'</html>'} );
}
}

How to ensure Script sends an email containing an HTML table with full range of data?

I have created a function that will allow me to send emails to a list of contacts via Google Sheets. The email will include a subject line and a table containing the data from my spreadsheet. The problem i am facing is that the HTML table is only sending the headers and 1 row of data. I can't find the error i have made.
The table will be ever increasing so i would like to email function to include all cells that have data in it. Is this possible?
I have adapted this Script/HTML code from How to format email from spreadsheet data using arrays? but i am now stuck with how to amend it further for my needs.
function testMail(){
var emails = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Contacts");
var startRow = 2; // First row of data to process
var numRows = 2; // Number of rows to process
// Fetch the range of cells A1:B1
var dataRange = emails.getRange(startRow, 1, 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[0]; // First column
var subject = "Current list of BGC 4 Acronyms";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var acronym = ss.getSheetByName("Sheet1");
var abbv = acronym.getRange("A5:A50").getValues();
var explan = acronym.getRange("B5:B50").getValues();
var message = composeMessage(abbv,explan);
var messageHTML = composeHtmlMsg(abbv,explan);
Logger.log(messageHTML);
MailApp.sendEmail(emailAddress, subject, message, {'htmlBody':messageHTML});
}
function composeMessage(abbv,explan){
var message = 'Here are the data you submitted :\n'
for(var c=0;c<explan[0].length;++c){
message+='\n'+abbv[0][c]+' : '+explan[0][c]
}
return message;
}
function composeHtmlMsg(abbv,explan){
var message = '<br><br><table style="background-color:lightblue;border-collapse:collapse;" border = 1 cellpadding = 5><th>Acronym</th><th>Explanation</th><tr>'
for(var c=0;c<explan[0].length;++c){
message+='<tr><td>'+abbv[0][c]+'</td><td>'+explan[0][c]+'</td></tr>'
}
return message+'</table>';
}
The expected result is an email sent to each address in the list with a subject line and full table of data. What i am actually getting is this
Try changing this:
for(var c=0;c<explan[0].length;++c){
message+='\n'+abbv[0][c]+' : '+explan[0][c]
}
To this:
I assume that abbv and explan are columns.
for(var c=0;c<explan.length;c++){
message+='<br />' + abbv[c][0]+ ' : ' + explan[c][0];
}
Try this:
function composeHtmlMsg(abbv,explan){
var message = '<br><br><table style="background-color:lightblue;border-collapse:collapse;" border = 1 cellpadding = 5><th>Acronym</th><th>Explanation</th><tr>'
for(var c=0;c<explan.length;c++){
message+='<tr><td>'+abbv[c][0]+'</td><td>'+explan[c][0]+'</td></tr>'
}
return message+='</table>';
}
Based upon your spreadsheet sample I think this could work:
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Sheet1');
var rg1=sh.getRange(5,1,sh.getLastRow()-4,1);
var rg2=sh.getRange(5,2,sh.getlastRow()-4,1);
var explan=rg1.getValues();
var abbv=rg2.getValues();

Send email to the address in one column with body from another, when a keyword is present

I need to send mail notification to specific email address in Column A2 with body email from B2 when writing keyword in C2. Column A will be filled up from a Google Form.
https://docs.google.com/spreadsheets/d/15HrfUNhIyqLD948aRq0h9iAUW4Y_9LGe8HQm3MP2rZ0/edit?usp=sharing
function kirim() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 1; // 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, 1, numRows, 2)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var subject = "test meneh from spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
}
}
I dont't really know what the trigger column is for and there was any subject so I left it blank. But this should do what you need. You'll probably need to change the sheetname and if you want to call this with a timer based trigger you may want to replace the first line with var ss=SpreadsheetApp.openById('SpreadsheetID');
function kirim()
{
var ss=SpreadsheetApp.getActive();
var sht=ss.getSheetByName('SimpleEmail');
var rng=sht.getDataRange();
var rngA=rng.getValues();
var changed=false;
var re=/ok/i;
for(var i=1;i<rngA.length;i++)
{
if(rngA[i][2].match(re))//case insensitive and of the following will work: Ok ok oK OK
{
GmailApp.sendEmail(rngA[i][0], '', rngA[i][1]);
rngA[i][3]='EMAIL_SENT';
changed=true;
}
}
if(changed)rng.setValues(rngA);
}

Send content of Google Sheet with Google App Script

I'm trying to create a script that'll send me the content of a google sheet by email on a weekly basis.
Can someone point me in the right direction?
EDIT: It needs to be in the in the Body
This will send the sheet as a xls to your email. Get this to work then set a time based trigger. - also notice this is a private sheet, that gets set public for a brief moment while it emails and then sets back to private.
function getGoogleSpreadsheetAsExcel(){
try {
var ss = SpreadsheetApp.getActive();
var sheet = DriveApp.getFileById(ss.getId());
// sets sharing to public - to send out email.
sheet.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
var url = "https://www.googleapis.com/drive/v3/files/" + ss.getId() + "/export?mimeType=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet&key=" + "YOUR_KEY_GOES_HERE";
var blob = UrlFetchApp.fetch(url).getBlob();
Logger.log(url);
blob.setName(ss.getName() + ".xlsx");
var now = new Date();
MailApp.sendEmail("YOUR_EMAIL_ADDRESS_GOES_HERE", "Backup " + now , "Backup " + now , {attachments: [blob]});
} catch (f) {
Logger.log(f.toString());
}
// returns the file back to Private access
sheet.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.EDIT);
}
Here's my solution so far but it's not clean & far from ideal:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn());
var data = range.getValues();
var body = '';
for( var row in data ) {
for( var col in data[row] ) {
body += data[row][col] + '\t';
}
}
body += '\n';
}
Logger.log(body);
// MailApp.sendEmail('your#email.com', 'Director Dealings', body);
}
You may check this tutorial on how to send emails from a Spreadsheet.
function sendEmails() {
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, 2)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var subject = "Sending emails from a Spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
}
}
You need to use the MailApp.sendEmail(). Just be noted that there are four versions of this method

sendEmail function in Google Sheets

I have been struggling for days to get this appScript to function within my Google Sheets. Currently it is getting "stuck" on MailApp.sendEmail line, particularly on emailAddress. It gives me this error message "Invalid email: undefined". I based the majority of the script on their Sending Emails from a Spreadsheet Tutorial. So I'm not too sure where it might be going wrong.
Any help is much appreciated!
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = ss.getSheetByName("Candidates Ready for Offer");
var startRow = 2; // First row of data to process
var numRows = ss.getSheetByName("Candidates Ready for Offer").getLastRow()-1;
// Fetch recent additions
var dataRange = ss.getSheetByName("Candidates Ready for Offer").getRange(startRow, 3)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[5];
var message = "row[1]" + "row [2]" + "at" + "row[4]" + "is ready for an offer!"
var subject = "Candidate is Ready for Offer";
MailApp.sendEmail(emailAddress, subject, message);
}
}
Thanks for sharing your sheet. There was actually a number of reasons why it wasn't working which I'll try and explain. Anyway, your script on the shared sheet will now function as you want it to. Here is what it looks like:
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = ss.getSheetByName("Candidates Ready for Offer");
var startRow = 4; // First row of data to process
var numRows = sh0.getLastRow()-startRow+1;
// Fetch recent additions
var dataRange = sh0.getRange(startRow,1,numRows,6);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
Logger.log(data);
for (i in data) {
var row = data[i];
var emailAddress = row[3];
Logger.log(emailAddress);
var message = "row[1]" + "row [2]" + "at" + "row[4]" + "is ready for an offer!"
var subject = "Candidate is Ready for Offer";
MailApp.sendEmail(emailAddress, subject, message);
}
}
There's no need to keep calling the same sheet when you've already defined it as the variable sh0
The data range was including the first 3 rows. You didn't want this. Some simple maths in the var numRows allows the spreadsheet to only take the range containing data starting at row 4.
You were referencing the wrong column for email address. It was in column 4.
I hope this helps/makes sense.
Oli
The problem is your var dataRange. At the moment your code is only getting the range of one cell (startrow,3) instead of an array.
Replacing .getRange(startrow,3) with getDataRange() should fix your issue.