Email of specific data rang / table from Google Sheet - google-apps-script

function B2B() {
var summary = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Summary");
var subject = "B2B - Delivery Status on";
var recipient = "******#***.in";
var dataRange = summary.getRange('B2:AA49');
var data = dataRange.getValues();
summary.getRange(2, 2, 25, 25).getValue;
var body = "I just discovered Apps Script and it's so cool!" + data;
MailApp.sendEmail(recipient, subject, body);
}
Used this query which is working and mail is going but, selected data range is table which i am not getting in table format in the mail.

Try this
function B2B() {
var summary = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Summary");
var subject = "B2B - Delivery Status on";
var recipient = "******#***.in";
var dataRange = summary.getRange('B1:AA49');
var [headers, ...rows] = dataRange.getValues();
MailApp.sendEmail({
to: recipient,
subject: subject,
htmlBody: "I just discovered Apps Script and it's so cool!" + "<br><br>" + tableHTML([headers], rows)
})
}
function tableHTML(headers, data) {
var tableformat = 'cellspacing="2" cellpadding="2" border="1" style="width:100%;border-collapse:collapse;border:1px solid #ccc"';
var header = headers.map(h => '<tr><th>' + h.join('</th><th>') + '</th></tr>')
var rows = data.map(r => '<tr><td>' + r.join('</td><td>') + '</td></tr>')
return '<table ' + tableformat + ' >\n' + header.join('\n') + rows.join('\n') + '</table>'
}
you need htmlbody instead of body
tableHTML is a function that will tranform the data into a table
map
join

Related

Google Sheets Script, if email null then skip to next email and make a status if email are already sent

I'm using google sheets script to send an email,
how to skip a row when the email is null?
and how to create an status when the email is sent?
thank you
function sendMails() {
var wrkBk = SpreadsheetApp.getActiveSpreadsheet();
var wrkShtEmailIDs= wrkBk.getSheetByName("recipient");
var wrkShtMessage= wrkBk.getSheetByName("email_body");
var subject = wrkShtMessage.getRange('A2').getValue();
var message = wrkShtMessage.getRange('B2').getValue();
for (var i=5;i<=100;i++){
var emailAddress = wrkShtEmailIDs.getRange('C' + i).getValue();
var finalmsg = "";
finalmsg = "Hi " + emailAddress + "\n" + "\n" + message;
MailApp.sendEmail(emailAddress, subject, finalmsg);
}
}
Try for instance, respecting your syntax
function sendMails() {
var wrkBk = SpreadsheetApp.getActiveSpreadsheet();
var wrkShtEmailIDs = wrkBk.getSheetByName("recipient");
var wrkShtMessage = wrkBk.getSheetByName("email_body");
var subject = wrkShtMessage.getRange('A2').getValue();
var message = wrkShtMessage.getRange('B2').getValue();
for (var i = 5; i <= 100; i++) {
var emailAddress = wrkShtEmailIDs.getRange('C' + i).getValue();
if (emailAddress != '') {
var finalmsg = "";
finalmsg = "Hi " + emailAddress + "\n" + "\n" + message;
MailApp.sendEmail(emailAddress, subject, finalmsg);
wrkShtMessage.getRange('D' + i).setValue('sent') // status in D
}
}
}

Trigger based email send on google sheets giving some random results i dont understand

I have been trying to make a script that will send email of a range of cells over email. While the sending email part works perfectly, when i add time based trigger to it, its sending out a random email i dont understand.
I am trying to send out a range of cells in my sheet that gets updated live to my boss automatically at 9:30Am everyday.
function sendEmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getDataRange();
var recipient = 'aaaabalamurali1996#gmail.com'
var subject = 'NRV Tracker'
var date = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy")
var schedRange = sheet.getRange("A1:Y6");
//var schedRange = sheet.getRange(Col == 3 && compare == date);
var body = '<div style="text-align:center;display: inline-block;font-family: arial,sans,sans-serif">'
body += '<H1>'+ 'NRV Tracker ' +'</H1>';
body += '<H2>'
body += getHtmlTable(schedRange);//change this line
body += '</div>';
debugger;
recipient = 'abc#abc.com'; // For debugging, send only to self
GmailApp.sendEmail(recipient, subject, "Requires HTML", {htmlBody:body})
var ts = ss.getSheetByName("D-1 Day");
var srange = sheet.getRange("A1:Y6");
var trange = ts.getRange("A1:Y6");
srange.copyTo(trange, {contentsOnly: true});
}
function getHtmlTable(range){
var ss = range.getSheet().getParent();
var sheet = range.getSheet();
startRow = range.getRow();
startCol = range.getColumn();
lastRow = range.getLastRow();
lastCol = range.getLastColumn();
// Read table contents
var data = range.getValues();
// Get css style attributes from range
var fontColors = range.getFontColors();
var backgrounds = range.getBackgrounds();
var fontFamilies = range.getFontFamilies();
var fontSizes = range.getFontSizes();
var fontLines = range.getFontLines();
var fontWeights = range.getFontWeights();
var horizontalAlignments = range.getHorizontalAlignments();
var verticalAlignments = range.getVerticalAlignments();
var colWidths = [];
for (var col=startCol; col<=lastCol; col++) {
colWidths.push(sheet.getColumnWidth(col));
}
var rowHeights = [];
for (var row=startRow; row<=lastRow; row++) {
rowHeights.push(sheet.getRowHeight(row));
}
var tableFormat = 'style="font-size: 10px; border:1px solid black;border-collapse:collapse;text-align:center" border = 1 cellpadding = 1';
var html = ['<table '+tableFormat+'>'];
// Column widths appear outside of table rows
for (col=0;col<colWidths.length;col++) {
html.push('<col width="'+colWidths[col]+'">')
}
for (row=0;row<data.length;row++) {
html.push('<tr height="'+rowHeights[row]+'">');
for (col=0;col<data[row].length;col++) {
// Get formatted data
var cellText = data[row][col];
if (cellText instanceof Date) {
cellText = Utilities.formatDate(
cellText,
ss.getSpreadsheetTimeZone(),
'M/d');
}
var style = 'style="'
+ 'color: ' + fontColors[row][col]+'; '
+ 'font-family: ' + fontFamilies[row][col]+'; '
+ 'font-size: ' + fontSizes[row][col]+'; '
+ 'font-weight: ' + fontWeights[row][col]+'; '
+ 'background-color: ' + backgrounds[row][col]+'; '
+ 'text-align: ' + horizontalAlignments[row][col]+'; '
+ 'vertical-align: ' + verticalAlignments[row][col]+'; '
+'"';
html.push('<td ' + style + '>'
+cellText
+'</td>');
}
html.push('</tr>');
}
html.push('</table>');
return html.join('');
}
When i use the trigger i am getting this email.
enter image description here
Try referencing the range of cells that you wish to send to a new sheet and use the code below to send that sheet as a PDF. It is very easy to implement.
// Generate a PDF file from a Google spreadsheet and send it to a specified email address
function emailSpreadsheetAsPDF() {
const sheetToPrint = "SPREADSHEET NAME"; // name of the sheet to print
const ss = SpreadsheetApp.getActiveSpreadsheet(); // the sheets to use
const email = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('SHEET NAME').getRange('E3').getValue().toString(); // grab the email address from the specified cell
const subject = `SUBJECT - ${ss.getName()}`; // the subject of the email
const body = "BODY"; // body of the email
const shID = ss.getSheetByName(sheetToPrint).getSheetId(); // the ID of the sheet
const url = 'https://docs.google.com/spreadsheets/d/SS_ID/export?'.replace('SS_ID', ss.getId()); // url of the spreadsheet
const exportOptions =
'exportFormat=pdf&format=pdf' + // export as pdf / csv / xls / xlsx
'&size=A4'+ // size of the PDF (legal / A4 / letter)
'&portrait=true'+ // orientation of the PDF (false for landscape)
'&fitw=true'+ // fit to page width (false for actual size)
'&sheetnames=false&printtitle=false'+ // hide optional headers and footers
'&pagenumbers=false&gridlines=false'+ // hide page numbers and gridlines
'&fzr=false'+ // do not repeat row headers (frozen rows) on each page
'&gid='+shID; // the sheet's Id
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
// generate the PDF file
var response = UrlFetchApp.fetch(url+exportOptions, params).getBlob();
// send the email to the specified address with the specified body text and attached PDF file
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments: [{
fileName: `FILE NAME - ${ss.getName()}` + ".pdf",
content: response.getBytes(),
mimeType: "application/pdf"
}]
});
}
All you have to do is change the SPREADSHEET NAME, SHEET NAME, SUBJECT, BODY, and FILE NAME. Changing around the ExportOptions could also potentially help you.
Once you have this implemented, just set up a trigger for it to run every morning at 9AM.
If you have any questions, do not hesitate to contact me.

Auto Send Email When Checkbox is Checked - Google Sheet

I tried the script from Auto Email Function for Google Sheets Mobile and it worked the first time. When I tried to change the variables, it does not automatically send the email, unless I run the script again, it would then update the response sheet and then clears the checkbox. Please help me with this. Kindly see my code below.
function EmailNotification(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Course_AutoEmail'); //source sheet
var columnb = sheet.getRange('I:I'); //Column with check boxes
var columnbvalue = columnb.getValues();
var notifysheet = ss.getSheetByName('Responses'); //destination sheet
var data = [];
var rownum = [];
//Condition check in B:B (or check box column); If true copy the same row to data array
for (let i = 0; i < columnbvalue.length; i++) {
if (columnbvalue[i][0] === true) {
var columnb2 = sheet.getRange('I747:I'); //row started in row 747
columnb2.setValue('false');
data.push.apply(data, sheet.getRange(i + 1, 1, 1, 20).getValues());
//Copy matched ROW numbers to rownum
rownum.push(i);
//Copy data array to destination sheet
notifysheet.getRange(notifysheet.getLastRow() + 1, 1, data.length, data[0].length).setValues(data);
var activeRow = notifysheet.getLastRow();
var name = notifysheet.getRange(activeRow, 1).getDisplayValue(); // The number is the column number in the destination "responses" sheet that you want to include in the email
var employeeID = notifysheet.getRange(activeRow, 2).getDisplayValue();
var position = notifysheet.getRange(activeRow, 3).getDisplayValue();
var team = notifysheet.getRange(activeRow, 4).getDisplayValue();
var date = notifysheet.getRange(activeRow, 10).getDisplayValue();
var rec1 = notifysheet.getRange(activeRow, 19).getDisplayValue();
var rec2 = notifysheet.getRange(activeRow, 20).getDisplayValue();
var email = rec1 + "," + rec2;
var subject = name + ': 201 Completion';
//Body of the email message, using HTML and the variables from above
var message =
'<br><div style="margin-left:10px;">Hi, </div>' +
'<br><div style="margin-left:10px;">Good day!</div>' +
'<br><div style="margin-left:10px;"><b>' + name + '</b> has completed the course. </div>' +
'<br><div style="margin-left:20px;"><h3 style="text-decoration: underline; color: #f36f21">Employee Details: </h3></div>' +
'<div style="margin-left:25px;">Name: <b>' +
name +
'</b></div>' +
'<div style="margin-left:25px;">Position: <b>' +
position +
'</b></div>' +
'<div style="margin-left:25px;">Team: <b>' +
team +
'</b></div>' +
'<div style="margin-left:25px;">Completion Date: <b>' +
date +
'</b></div>' +
'<br><br><div style="margin-left:10px;">Let me know if you have any questions. </div>' +
'<br><div style="margin-left:10px;">Thanks! </div>';
MailApp.sendEmail(email, subject, '', {
htmlBody: message,
name: 'Updates',
});
}
}
}
I read your code.
if you don't want your checked checkbox unchecked in spreadsheet.
so you have to remove `columnb2.setValue('false');` line of code.
this line is made checkbox unchecked.
solution of other problems : http://one7techlab.com

How do I add Email Sent to a status column and exclude those rows when the script runs again?

I am very new to scripting and am struggling to write a script for our youth league program's apparel fundraiser. The script, when triggered by clicking an image, will send an email to all of the recipients on a list, add 'email sent' to status column 'I' in all of the rows that the email sent to...then whenever the script is run again, only send emails to the new rows of data that haven't been emailed yet.
The script that I have inserts email sent, but if the script is run again it doesn't pay attention to the status column 'I' and I get duplicate emails. I've used tutorial videos to get me this far, but now I'm stuck. I've tried to get help from similar questions, but I'm not experienced enough to modify it to fit my needs. Here is a copy of the google sheet, the 'Send Emails' sheet has the info the script is running from. UPDATED:
https://docs.google.com/spreadsheets/d/1MBVhLj1A7Z_cpYxs_s5ae11ykJvTmS16E0jW4tGsNU4/edit?usp=sharing
function sendOrderEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Send Emails"));
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var dataRange = sheet.getRange("A2:I10");
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var rowData = data[i];
var emailAddress = rowData[0];
var recipient = rowData[1];
var message1 = rowData[2];
var parameter1 = rowData[3];
var message2 = rowData[4];
var message3 = rowData[5];
var parameter2 = rowData[6];
var message4 = rowData[7];
var emailSent = rowData[9];
var message = 'Hi ' + recipient + ',\n\n' + message1 + parameter1 + ' ' + message2 + ' ' + message3 + parameter2 + '. ' + message4 + '\n\n' + 'Tri-Valley Youth League Softball';
var subject = 'Order Reference Number ' + parameter2;
if (emailSent != "EMAIL_SENT" ) { // Prevents sending duplicates
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 9).setValue("EMAIL_SENT");
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
Try this:
function sendOrderEmails() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheetByName("Send Emails");
var startRow=2;
var dataRange=sheet.getRange("A2:J10");//Include column 10 in the range
var data=dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var rowData = data[i];
var emailAddress = rowData[0];
var recipient = rowData[1];
var message1 = rowData[2];
var parameter1 = rowData[3];
var message2 = rowData[4];
var message3 = rowData[5];
var parameter2 = rowData[6];
var message4 = rowData[7];
var emailSent = rowData[8];//This is column 9
var message = 'Hi ' + recipient + ',\n\n' + message1 + parameter1 + ' ' + message2 + ' ' + message3 + parameter2 + '. ' + message4 + '\n\n' + 'Tri-Valley Youth League Softball';
var subject = 'Order Reference Number ' + parameter2;
if (emailSent != "EMAIL_SENT" ) {
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 9).setValue("EMAIL_SENT");
}
}
}
I did this so that you can see the difference row and columns and data indices.
function rowsColumnsAndIndices() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var rg=sh.getRange(1,1,26,26);
var vA=rg.getValues();
for(var i=0;i<vA.length;i++) {
for(var j=0;j<vA[i].length;j++) {
vA[i][j]=Utilities.formatString('r: %s, c: %s\ni: %s,j: %s', i+1,j+1,i,j);
}
}
rg.setValues(vA);
}

Failed to send email: no recipient

Good day! I need help in debugging this error: "Failed to send email: no recipient". The function sends emails based on the values of a range. Please check the code below.
function sendArticleCountEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Send-Emails"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange(2, 1, sheet.getLastRow(), 5);
var data = dataRange.getValues();
for (i in data) {
var rowData = data[i];
var subject = 'DepEd Email/Account';
var FirstName = rowData[0];
var LastName = rowData[1];
var GeneratedEmail = rowData[2];
var Password = rowData[3];
var emailAddress = rowData[4];
MailApp.sendEmail({
to: emailAddress,
subject: subject,
htmlBody: '<h3>' + 'Good day Mr./Mrs./Ms. '+ FirstName + ' ' + LastName +'!</h3>' +
'<p>Here is your email/account (email and password):</p>' +
'<p><span style="background-color: #ffff00;"><strong><a name="gEmail">' + GeneratedEmail + '</a></strong></span></p>' +
'<p><span style="background-color: #ffff00;"><strong><a name="pword">' + Password + '</a></strong></span></p>' +
'<p>You can now login to mail.google.com to check your account.</p>' +
'<p>If you want to change password, login first then follow this link.</p>'
});
}
ss.getSheetByName('Form Responses 2').getRange(254, 12, sheet.getLastRow(), 1).copyTo(ss.getSheetByName('Form Responses 2').getRange(254, 14, sheet.getLastRow(), 1));
}
The function runs and sends all emails but then it gives the error. I suspect it loops to an empty row and can't find a recipient but I already have dataRange with sheet.getLastRow().
Often there will be a blank row returned at the end from a Range#getValues() call. We can add an if statement to skip sending if there is no data in a row:
function sendArticleCountEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Send-Emails"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange(2, 1, sheet.getLastRow(), 5);
var data = dataRange.getValues();
for (i in data) {
var rowData = data[i];
if(!rowData[4]) continue; //Skip this iternation if no email
var subject = 'DepEd Email/Account';
var FirstName = rowData[0];
var LastName = rowData[1];
var GeneratedEmail = rowData[2];
var Password = rowData[3];
var emailAddress = rowData[4];
MailApp.sendEmail({
to: emailAddress,
subject: subject,
htmlBody: '<h3>' + 'Good day Mr./Mrs./Ms. '+ FirstName + ' ' + LastName +'!</h3>' +
'<p>Here is your email/account (email and password):</p>' +
'<p><span style="background-color: #ffff00;"><strong><a name="gEmail">' + GeneratedEmail + '</a></strong></span></p>' +
'<p><span style="background-color: #ffff00;"><strong><a name="pword">' + Password + '</a></strong></span></p>' +
'<p>You can now login to mail.google.com to check your account.</p>' +
'<p>If you want to change password, login first then follow this link.</p>'
});
}
ss.getSheetByName('Form Responses 2').getRange(254, 12, sheet.getLastRow(), 1).copyTo(ss.getSheetByName('Form Responses 2').getRange(254, 14, sheet.getLastRow(), 1));
}
Alternatively, we can not grab the last row: var dataRange = sheet.getRange(2, 1, sheet.getLastRow()-1, 5);