Google Apps Script personalised Email notifications - email

I want a script that will send out an email from a spreadsheet when a new row of data is entered. I'd like some of this data to be included in the subject, and some more data and a link to the spreadsheet in the main body.
I'm currently using a script that sends an email when a certain column in the spreadsheet is updated, but I'd now like to personalise it a bit more and make it quicker for the recipient to review without having to always open the spreadsheet.
This is my spreadsheet:
And this is my current script:
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Requests");
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
if (cell.indexOf('F')!=-1)
{
MailApp.sendEmail({
to: "email#yourdomain.co.uk",
subject: "Request",
htmlBody: "There has been a new request. <br \> <br \> To review it, use the link below. <br \> <br \> " +
"Requests"
});
}
}
I'd like the quantity (column F) and date (column E) to be included in the email subject, and the quantity (F), date (E) and depot (D) included in the main body, with the link to the spreadsheet.
EDIT: Columns G, H & I would be filled in at a later date by the recipient of the email.
Thanks in advance
EDIT:
My script is now looking like this:
function getActiveRowValues(sheet){
var cellRow = sheet.getActiveRange().getRow();
// get depot value
var depotCell = sheet.getRange("D" + cellRow);
var depot = depotCell.getDisplayValue();
// get date value
var dateCell = sheet.getRange("E" + cellRow);
var date = dateCell.getDisplayValue();
// get quantity value
var quantCell = sheet.getRange("F" + cellRow);
var quant = quantCell.getDisplayValue();
// return an object with your values
return {
depot: depot,
date: date,
quantity: quant
}
if (cell.indexOf('F')!=-1)
{
var rowVals = getActiveRowValues(sheet);
MailApp.sendEmail({
to: "email#yourdomain.co.uk",
subject: "Request" + " date " + rowVals.date + " quant " + rowVals.quant,
htmlBody: "There has been a new request. <br \> <br \> To review it, use the link below. <br \> <br \> " + "<table border = \"1\" cellpadding=\"10\" cellspacing=\"0\"><tr><th>Depot</th><th>Date</th><th>Quantity</th></tr><tr><td>"+rowVals.depot+"</td><td>"+rowVals.date+"</td><td>"+rowVals.quant+"</td></tr></table>" +
"Requests"
});
}}
But getting the error:
TypeError: Cannot call method "getActiveRange" of undefined. (line 2,
file "Code")

Add this function in your script that will extract your required details from the respective column:
/**
* get values of depot, date and quantity from their respective cells.
* #returns {Object.<string, string>}
*/
function getActiveRowValues(sheet){
var cellRow = sheet.getActiveRange().getRow();
// get depot value
var depotCell = sheet.getRange("D" + cellRow);
var depot = depotCell.getDisplayValue();
// get date value
var dateCell = sheet.getRange("E" + cellRow);
var date = dateCell.getDisplayValue();
// get quantity value
var quantCell = sheet.getRange("F" + cellRow);
var quant = quantCell.getDisplayValue();
// return an object with your values
return {
depot: depot,
date: date,
quantity: quant
}
}
Then call getActiveRowValues inside your if condition and also update your subject and htmlBody variables:
if (cell.indexOf('F')!=-1)
{
var rowVals = getActiveRowValues(sheet);
MailApp.sendEmail({
to: "email#yourdomain.co.uk",
subject: "Request" + " date " + rowVals.date + " quant " + rowVals.quantity,
htmlBody: "There has been a new request. <br \> <br \> To review it, use the link below. <br \> <br \> " + "<table border = \"1\" cellpadding=\"10\" cellspacing=\"0\"><tr><th>Depot</th><th>Date</th><th>Quantity</th></tr><tr><td>"+rowVals.depot+"</td><td>"+rowVals.date+"</td><td>"+rowVals.quantity+"</td></tr></table>" +
"Requests"
});
}
And your overall script should look like this:
function sendNotification(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//var sheet = ss.getSheetByName("Requests");
var sheet = ss.getActiveSheet();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var emailAdd = "email#yourdomain.co.uk";
if(event.range.getA1Notation().indexOf("F") > -1 && sheet.getRange("F" + row).getDisplayValue() && emailAdd.length > 1)
{
var rowVals = getActiveRowValues(sheet);
MailApp.sendEmail({
to: emailAdd,
subject: "Request" + " date " + rowVals.date + " quant " + rowVals.quantity,
htmlBody: "There has been a new request. <br \> <br \> To review it, use the link below. <br \> <br \> " + "<table border = \"1\" cellpadding=\"10\" cellspacing=\"0\"><tr><th>Depot</th><th>Date</th><th>Quantity</th></tr><tr><td>"+rowVals.depot+"</td><td>"+rowVals.date+"</td><td>"+rowVals.quantity+"</td></tr></table>" +
"Requests"
});
}
}
/**
* get values of depot, date and quantity from their respective cells.
* #returns {Object.<string, string>}
*/
function getActiveRowValues(sheet){
var cellRow = sheet.getActiveRange().getRow();
// get depot value
var depotCell = sheet.getRange("D" + cellRow);
var depot = depotCell.getDisplayValue();
// get date value
var dateCell = sheet.getRange("E" + cellRow);
var date = dateCell.getDisplayValue();
// get quantity value
var quantCell = sheet.getRange("F" + cellRow);
var quant = quantCell.getDisplayValue();
// return an object with your values
return {
depot: depot,
date: date,
quantity: quant
}
}

You can just concatenate values on the HTML of the body and the subject
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Requests");
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var thisIsAVariable = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Requests").getRange("A1").getValue();
if (cell.indexOf('F')!=-1)
{
MailApp.sendEmail({
to: "email#yourdomain.co.uk",
subject: "Request" + + thisIsAVariable +,
htmlBody: "concatenate like: "+ thisIsAVariable +"There has been a new request. <br \> <br \> To review it, use the link below. <br \> <br \> " + thisIsAVariable +
"Requests"
});
}}

Related

Email notification when cell value is <=7 or >=7

I need help trying to make this script work. I want to get daily email notifications if column Y3:Y is less than or equal to 7 OR Y3:Y is greater than or equal to 0. I want it to return information from column Q specific to that row.
So far, I have:
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = "x#email.com";
var message = '';
if(cell.indexOf('Y')<=7){
message = sheet.getRange('Q'+ sheet.getActiveCell().getRowIndex()).getValue()
}
var subject = 'Order is due soon for'+sheet.getName();
var body = sheet.getName() + ' order is due soon. Click ' + ss.getUrl() + ' to see which PO is due, look at row # to see details: «' + row + '». PO#: «' + cellvalue;
MailApp.sendEmail(recipients, subject, body);
};
I have this for my trigger.
Here is the sheet: https://docs.google.com/spreadsheets/d/1HUaW1ZowU1ss1_JInLuML7jeVffDwZ5pl-EujooBJU4/edit?usp=sharing
I have a feeling my trigger is incorrect. Sorry in advance, still new to this.
Thanks!
I think this is closer to what you want
function sendNotification() {
var ss = SpreadsheetApp.getActive();
var sh = ss.getActiveSheet();
var cell = ss.getActiveCell().getA1Notation();
var row = sh.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = "x#email.com";
const vs = sh.getRange("A3:Y" + sh.getLastRow()).getValues();
const name = sh.getName();
const url = ss.getUrl();
let rows = [];
vs.forEach((r, i) => {
if (r[24] > -1 && r[24] < 8) {
rows.push(r);//save array of all rows
let message = r[16];
let row = i + 3;//added row number
let subject = 'Order is due soon for' + name;
var body = name + ' order is due soon. Click ' + url + ' to see which PO is due, look at row # to see details: «' + row + '». PO#: «' + cellvalue;
MailApp.sendEmail(recipients, subject, body);
}
})
Logger.log(JSON.stringify(rows));
}

Convert Google Sheet to an .xlsx file and send it as an email attachment with Apps Script [duplicate]

I have this code that search new doc in drive folder, and send files via email
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var email = "xxx#gmail.com";
var timezone = ss.getSpreadsheetTimeZone();
var today = new Date();
var oneDayAgo = new Date(today.getTime() - 1 * 24 * 60 * 60 * 1000);
var startTime = oneDayAgo.toISOString();
var search = '(trashed = false or trashed = false) and (modifiedDate > "' + startTime + '")';
var folder1 = DriveApp.getFoldersByName('SaveToPDF').next();
var files1 = folder1.searchFiles(search);
var row = "", count=0;
while( files1.hasNext() ) {
var file1 = files1.next();
var fileName = file1.getName();
var fileURL = file1.getUrl();
var lastUpdated = Utilities.formatDate(file1.getLastUpdated(), timezone, "yyyy-MM-dd HH:mm");
var dateCreated = Utilities.formatDate(file1.getDateCreated(), timezone, "yyyy-MM-dd HH:mm")
row += "<li>" + lastUpdated + " <a href='" + fileURL + "'>" + fileName + "</a></li>";
sheet.appendRow([dateCreated, lastUpdated, fileName, fileURL]);
count++;
}
if (row !== "") {
row = "<p>" + count + " file(s) have changed in your Google Drive in the past 24 hours. Here's the list:</p><ol>" + row + "</ol>";
row += "<br><small>To stop these notifications, please <a href='" + ss.getUrl() + "'>click here</a> and choose <em>Uninstall</em> from the Drive Activity menu.<br/></small>";
MailApp.sendEmail(email, "Google Drive - File Activity Report", "", {htmlBody: row, cc: "xxx#gmail.com"} );
}
I need to convert sheet files to XLSX format before send.
Can someone help me?
Thanks
You can follow this tutorial on how to convert the current Google Spreadsheet to Excel XLSX format and then emails the file as an attachment to the specified user using getGoogleSpreadsheetAsExcel() method.
function getGoogleSpreadsheetAsExcel(){
try {
var ss = SpreadsheetApp.getActive();
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + ss.getId() + "&exportFormat=xlsx";
var params = {
method : "get",
headers : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
var blob = UrlFetchApp.fetch(url, params).getBlob();
blob.setName(ss.getName() + ".xlsx");
MailApp.sendEmail("amit#labnol.org", "Google Sheet to Excel", "The XLSX file is attached", {attachments: [blob]});
} catch (f) {
Logger.log(f.toString());
}
}
Here are some similar threads which might help:
Google apps script to email google spreadsheet excel version
Converting .xls to google spreadsheet in google apps script

Sending an email with an html body from another email address via google sheets

I'm having a problem sending an html body message from a Google sheet from another email address that is an alias.
I can send it using the mailApp, but when I switch to the GmailApp I can't seem to get it to work.
The script I am using is below:
function sendNotification(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var emailAdd = "email#yourdomain.com";
if(event.range.getA1Notation().indexOf("G") > -1 && sheet.getRange("G" + row).getDisplayValue() > 999 && emailAdd.length > 1)
{
var rowVals = getActiveRowValues(sheet);
var aliases = GmailApp.getAliases();
Logger.log(aliases);
GmailApp.sendEmail(
"email#yourdomain.com",
"Allocation Request - " + rowVals.quantity + " cases on " + rowVals.date,
{htmlBody: "There has been a new allocation request from " + rowVals.name + " in the " + rowVals.team + " team.<br \> <br \> "
+ "<table border = \"1\" cellpadding=\"10\" cellspacing=\"0\"><tr><th>Issuing Depot</th><th>Delivery Date</th><th>Case Quantity</th></tr><tr><td>"+rowVals.depot+"</td><td>"+rowVals.date+"</td><td>"+rowVals.quantity+"</td></tr></table>"
+ "<br \>To view the full details of the request, use the link below.<br \> <br \>" +
"Allocation Requests"
+"<br \> <br \><i>This is an automated email. Please do not reply to it.<\i>"},
{from: aliases[0]}
);
}
}
function getActiveRowValues(sheet){
var cellRow = sheet.getActiveRange().getRow();
// get depot value
var depotCell = sheet.getRange("E" + cellRow);
var depot = depotCell.getDisplayValue();
// get date value
var dateCell = sheet.getRange("F" + cellRow);
var date = dateCell.getDisplayValue();
// get quantity value
var quantCell = sheet.getRange("G" + cellRow);
var quant = quantCell.getDisplayValue();
// return an object with your values
var nameCell = sheet.getRange("B" + cellRow);
var name = nameCell.getDisplayValue();
var teamCell = sheet.getRange("C" + cellRow);
var team = teamCell.getDisplayValue();
return {
depot: depot,
date: date,
quantity: quant,
name: name,
team: team
} }
I've managed to get the email to send from my alias, but it just sends and message containing [object], whereas not sending it from an alias works fine.
Could someone take a look and see what I'm doing wrong? I've not been able to find an answer on here yet. Thanks.
Create an object then add elements to the object:
var bodyHTML,o,sendTO,subject;//Declare variables without assigning a value
o = {};//Create an empty object
bodyHTML = "There has been a new allocation request from " + rowVals.name;
o.htmlBody = bodyHTML;//Add the HTML to the object with a property name of htmlBody
o.from = aliases[0]; //Add the from option to the object
sendTO = "email#yourdomain.com";
subject = "Allocation Request - " + rowVals.quantity + " cases on " + rowVals.date;
GmailApp.sendEmail(sendTO,subject,"",o);//Leave the third parameter as an empty string because the htmlBody advanced parameter is set in the object.

Problems with email notification

I'm new to using the google doc script editor so please be kind. Here's what I have so far:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//Get Active cell
var mycell = ss.getActiveSelection();
var cellcol = mycell.getColumn();
var cellrow = mycell.getRow();
//Define variables from sheet by column
//Column count starts at 0, not 1.
var timestamp = e.values[cellrow,14];
var yourName = e.values[cellrow, 0];
var email = e.values[cellrow, 1];
var plot2013 = e.values[cellrow, 5];
var plotrequest = e.values[cellrow, 6];
var sharing = e.values[cellrow, 7];
var totalprice = e.values[cellrow, 8];
var paid = e.values[cellrow, 13];
var subject = "TSF Payment Confirmation"
//email body
var emailBody = "Thank you for your payment submitted on " + timestamp +
"\n\nThe details you entered were as follows: " +
"\nYour name: " + yourName +
"\nYour plot #: " + plot2013 +
"\nNumber plots requested: " + plotrequest +
"\nSharing plot with: " + sharing +
"\nTotal payment: " + totalprice;
//html version of email body
var htmlBody = "Thank you for your payment submitted on <i>" + timestamp +
"</i><br/> <br/>The details you entered were as follows: " +
"<br/><font color=\"red\">Your Name:</font> " + yourName +
"<br/>Your Email: " + plot2013;
"<br/>Plots requested: " + plotrequest;
"<br/>Sharing plot with: " + sharing +
"<br/>Total payment: " + totalprice;
//sends email if cell contents are 'yes'
if (e.values[13,cellrow] == "yes") {
//Sends email
MailApp.sendEmail(email, subject, emailBody);
}
}
And what I'm hoping is that once a user clicks in column 13 (assuming its counting from 0 on the left, and not variable numbers) and types 'yes' it will email the information from that users row as specified.
I'm getting an error message, saying:
var timestamp undefined
I got that from this example here: http://alamoxie.com/blog/tech-tips/sending-confirmation-emails-google-docs-form/
You're trying to reference the cells in a way that doesn't make sense (or work). Try this tested/working code instead:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
// Ensure the event was triggered by typing "yes" in the appropriate column
if(e.range.getColumn() == 14 && e.value.toUpperCase() == "YES"){
// Get the corresponding row
var row = sheet.getRange(e.range.getRow(), 1, 1, sheet.getLastColumn()).getValues()[0];
// Define variable from row by column
var timestamp = row[14];
var yourName = row[0];
var email = row[1];
var plot2013 = row[5];
var plotrequest = row[6];
var sharing = row[7];
var totalprice = row[8];
var paid = row[13];
var subject = "TSF Payment Confirmation"
// Construct the email body
var emailBody = "Thank you for your payment submitted on " + timestamp +
"\n\nThe details you entered were as follows: " +
"\nYour name: " + yourName +
"\nYour plot #: " + plot2013 +
"\nNumber plots requested: " + plotrequest +
"\nSharing plot with: " + sharing +
"\nTotal payment: " + totalprice;
// Construct an HTML version of the email body
var htmlBody = "Thank you for your payment submitted on <i>" + timestamp +
"</i><br/> <br/>The details you entered were as follows: " +
"<br/><font color=\"red\">Your Name:</font> " + yourName +
"<br/>Your Email: " + plot2013;
"<br/>Plots requested: " + plotrequest;
"<br/>Sharing plot with: " + sharing +
"<br/>Total payment: " + totalprice;
// Send email
MailApp.sendEmail(email, subject, emailBody);
}
}
Notice I put everything in a conditional statement; there's no sense in trying to parse all that data if a cell in column N wasn't changed to "yes". Immediately after, I retrieve all the values from the edited row and fill all your variables with the result. The rest is pretty much the same as you wrote it.
Good luck!

Adding paragraphs to automated email

I have created a script that automatically sends out emails that pulls information from several cells and populates the body of the email with the information alongside a standard body of the text.
However I can't work out a way to script in a paragraph space between the lines. I have done a workaround of creating a variable with the value of a cell that is just a paragraph space but, as other people will be using this spreadsheet, I am worried that the cell will get deleted and the formatting will change.
Is there another way to format paragraphs into the body of the email?
See my code below if that helps! The variable I need to format is "Var Message"
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = 99;
var dataRange = sheet.getRange(startRow, 1, numRows, 16)
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var EMAIL_SENT = "Contacted";
var currentdate = Utilities.formatDate(sheet.getRange("n2").getValue(), "GMT" , "dd/MM/yyyy" );
var staffmember = sheet.getRange("o2").getValue();
var paragraph = sheet.getRange("f2").getValue();
var row = data[i];
var emailAddress = row[0];
var name = row[1];
var company = row[2];
var website = row[3];
var role = row[4];
var show = row[9];
var date = Utilities.formatDate(row[15], "GMT" , "dd/MM/yyyy" );
var date2 = Utilities.formatDate(row[15], "GMT" , "dd/MM" );
var time = Utilities.formatDate(row[11], "GMT" , "HH:mm" );
var message = "Hello," + paragraph + "Could you please authorise or decline the following Arts Industry comp request from the Fringe Office? If you could reply within 72 hours, that would be great:" + paragraph + name + " " + company + " " + website + " " + role + paragraph + show + " " + date + " " + time + paragraph + "Many thanks," + paragraph + staffmember ;
var subject = "ARTS INDUSTRY REQUEST";
var emailSent = row[12];
if (emailSent != EMAIL_SENT) {
if (date > currentdate) {
var subject = "ARTS INDUSTRY REQUEST";
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 13).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
else if (emailSent != EMAIL_SENT) {
if (date < currentdate) {
var subject2 = "URGENT: ARTS INDUSTRY REQUEST" + " " + date2;
MailApp.sendEmail(emailAddress, subject2, message);
sheet.getRange(startRow + i, 13).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
}
}
}
}
For plaintext emails, you can use the "newline" escape sequence \n.
If you have K&R "C - The Programming Language", you'll find a full list of escape sequences in chapter 2. An online reference is available here.
var message = "Hello,\n"
+ "Could you please authorise or decline the following Arts Industry comp request from the Fringe Office? If you could reply within 72 hours, that would be great:\n\n"
+ name + " " + company + " " + website + " " + role
+ '\n' + show + " " + date + " " + time
+ '\n\n'
+ "Many thanks,"
+ '\n\n'
+ staffmember ;
You can use the advanced options of MailApp.sendEmail() function to achieve paragraph and line breaks more efficiently. Here is an example
var content = "Here is some text <br> " +
"that is split over two lines" ;
MailApp.sendEmail(recipient, subject, '',{'htmlBody' : content } );