Google Sheet Auto Email Script - javascript

I have a form that contains 84 questions, not all of them are mandatory.
This is the script I manage to write so far:
function SendEmail() {
var ActiveSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var StartRow = 2;
var RowRange = ActiveSheet.getLastRow() - StartRow + 1;
var WholeRange = ActiveSheet.getRange(StartRow,1,RowRange,84);
var AllValues = WholeRange.getValues();
var message = "";
for (i in AllValues) {
var CurrentRow = AllValues[i];
var EmailSent = CurrentRow[85];
if (EmailSent == "Sent")
continue;
# I know this part takes only the first 5 column, I wrote them only as an example. In bold the headers of each column.
message =
"<p><b>Kind of content: </b>" + CurrentRow[2] + "</p>" +
"<p><b>Project Name: </b>" + CurrentRow[3] + "</p>" +
"<p><b>Project Description: </b>" + CurrentRow[4] + "</p>" +
"<p><b>Name of your team: </b>" + CurrentRow[5] + "</p>" +
"<p><b>Scope of work: </b>" + CurrentRow[6] + "</p>";
var setRow = parseInt(i) + StartRow;
ActiveSheet.getRange(setRow, 85).setValue("sent");
}
var SendTo = "email#gmail.com";
var Subject = "New"+" " + CurrentRow[2] +" "+"project request";
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
}
What I want is to send an email every time somebody fills the form and the content of the email should include only the last row and only the columns with data with their header.
The way this script is written will generate an email with 84 rows, most of them empty and not relevant. Can somebody give me a hand with it?
Thank you so much for your help!!

You can use sheet.getLastRow() to get the index of the last row in the sheet that has data.
For finding columns that have data, you can iterate through the row data and look for cell values that are not blank.
var header = sheet
.getRange(1,1,1,sheet.getLastColumn())
.getDisplayValues()[0];
var data = sheet
.getRange(sheet.getLastRow(),1,1,sheet.getLastColumn())
.getDisplayValues()[0];
var output = [];
for (var d=0; d<data.length; d++) {
if (data[d] !== "") {
output.push(header[d] + " = " + data[d]);
}
}
return data.join("\n");

I know you are too naive to coding and Amit is a busy person, so just to help you, I am plugging in the code he has provided to your code with a small correction, so you can just copy the entire code :)
function SendEmail() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lRow = sheet.getLastRow();
var emailSent = sheet.getRange(lRow, 86).getValue();
var header = sheet
.getRange(1,1,1,sheet.getLastColumn())
.getDisplayValues()[0];
if (emailSent != "Sent"){
var data = sheet
.getRange(lRow,1,1,sheet.getLastColumn())
.getDisplayValues()[0];
var output = [];
for (var d=0; d<data.length; d++) {
if (data[d] !== "") {
output.push(header[d] + " = " + data[d]);
}
}
var message = output.join("\n");
var SendTo = "email#gmail.com";
var Subject = "New"+" " + sheet.getRange(lRow, 3).getValue() +" "+"project request";
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
sheet.getRange(lRow, 86).setValue("sent");
}
}

You can use filter, for example
var AllValues = WholeRange.getValues().filter( row => row[5] != '');
will reduce AllValues to only those there column 6 isn't empty

Related

How can I add a hyperlink to a javascript message?

Im trying to send an email from google sheets and I've setup the columns to represent the subject, text and email addresses. The problem is that I need to add a hyperlink in the middle of the message and im stuck here. I can't get the paragraph to format correctly AND have the hyperlink replace a word in the middle of the sentence.
This is the code:
function AISEMAIL() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet1=ss.getSheetByName('Email Addresses');
var sheet2=ss.getSheetByName('Email Fields');
var subject = sheet2.getRange(2,1).getValue();
var message = sheet2.getRange(2,2).getValue();
var calendardisplayname = sheet2.getRange(2,3).getValue();
var calendarlink = sheet2.getRange(2,4).getValue();
var formdisplayname = sheet2.getRange(2,5).getValue();
var formlink = sheet2.getRange(2,6).getValue();
message=message.replace("<calendar>",calendardisplayname).replace("<form>",formdisplayname);
var n=2;
for (var i = 2; i < n+1 ; i++ ) {
var emailAddress = sheet1.getRange(i,1).getValue();
let options = {
htmlBody: message
+ '' + calendardisplayname + ''
+ '' + formdisplayname + ''
}
GmailApp.sendEmail(emailAddress, subject, message,options);
}
}
Problem:
You are always trying to append the links at the end on your options. Also, it becomes redundant. What you need to do is include the links when you replace the values of <calendar> and <form>.
Code:
// Add the links on the replace
message = message
.replace("<calendar>", '' + calendardisplayname + '')
.replace("<form>", '' + formdisplayname + '');
var n = 2;
for (var i = 2; i < n + 1; i++) {
var emailAddress = sheet1.getRange(i, 1).getValue();
let options = {
htmlBody: message
}
GmailApp.sendEmail(emailAddress, subject, message, options);
}
Old Output:
New Output:
This is just a guess, but could you use HtmlService to create your html message?
function AISEMAIL() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet1=ss.getSheetByName('Email Addresses');
var sheet2=ss.getSheetByName('Email Fields');
var subject = sheet2.getRange(2,1).getValue();
var message = sheet2.getRange(2,2).getValue();
var calendardisplayname = sheet2.getRange(2,3).getValue();
var calendarlink = sheet2.getRange(2,4).getValue();
var formdisplayname = sheet2.getRange(2,5).getValue();
var formlink = sheet2.getRange(2,6).getValue();
message=message.replace("<calendar>",calendardisplayname).replace("<form>",formdisplayname);
var n=2;
for (var i = 2; i < n+1 ; i++ ) {
var emailAddress = sheet1.getRange(i,1).getValue();
//ADDED htmlText VARIABLE
var htmlText;
let options = {
// ADDED HtmlService.createHtmlOutput()
htmlBody: htmlText = HtmlService.createHtmlOutput(message
+ '' + calendardisplayname + ''
+ '' + formdisplayname + '');
}
// CHANGED message TO htmlText
GmailApp.sendEmail(emailAddress, subject, htmlText,options);
}
}
REFERENCES
HtmlService
Also, if you need to create dynamic html for each email, check out these links...
createTemplateFromFile()
.evaluate()
Templated HTML

How come boolean value is logged as a checkbox is undefined when logged?

I am trying to log the value of the check variable which is column 11 it is a checkbox and should come up as true or false if it is ticked or not ticked. However I get a log saying that the value is undefined and I'm not quite so sure as to why this is.
could someone please help? I have put a comment for your reference.
function sendEmail() {
//setup function
var ActiveSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var StartRow = 2;
var RowRange = ActiveSheet.getLastRow() - StartRow + 1;
var WholeRange = ActiveSheet.getRange(StartRow,1,RowRange,11);
var AllValues = WholeRange.getValues();
var message = "";
for (i in AllValues) {
var CurrentRow = AllValues[i];
var EmailSent = CurrentRow[13];
//problem here
var check = CurrentRow[11];
Logger.log(check)
if (EmailSent == "sent")
continue;
//set HTML template for information
message +=
"<p><b>Timestamp by: </b>" + CurrentRow[1] + "</p>" +
"<p><b>Requester Email: </b>" + CurrentRow[2] + "</p>" +
"<p><b>Star Rating: </b>" + CurrentRow[3] + "</p>" +
"<p><b>Request Category: </b>" + CurrentRow[4] + "</p>" +
"<p><b>Description: </b>" + CurrentRow[5] + "</p>" +
"<p><b>Label: </b>" + CurrentRow[6] + "</p>" +
"<p><b>Ticket ID: </b>" + CurrentRow[7] + "</p>" +
"<p><b>Comment: </b>" + CurrentRow[8] + "</p>" +
"<p><b>Status: </b>" + CurrentRow[9] + "</p><br><br>";
var setRow = parseInt(i) + StartRow;
ActiveSheet.getRange(setRow, 13).setValue("sent");
}
var SendTo = "email#email.org.au" + "," + "email#email.org.au";
var Subject = "CT IT feedback";
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
}
As mentioned above, you are going to need to think about looping with nested for loop if you are getting values from a sheet.
I am not familiar with those functions you are using in your snippet, but for learning, I have included an example of how to step through a sheet below.
See example below.
var sheet = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
];
// Think of the above array as your sheet.
// You will step go 1, 2, 3, 4 and then step down a row
// to 5, 6, 7, 8 and so on.
var rows = sheet.length;
var rowCount;
for(var i = 0; i < rows; i++) {
rowCount = 0;
for(var j = 0; j < sheet[i].length; j++) {
rowCount += sheet[i][j];
}
// Finished calculating the row.
console.log(rowCount);
}
First, for...in is used for iterating over the properties of an object, not for arrays. I'd recommend using forEach instead. So try changing this:
for (i in AllValues) {
var CurrentRow = AllValues[i];
// Rest of code in loop
}
For this:
AllValues.forEach(function(CurrentRow) {
// Rest of code in loop
})
Apart from this, CurrentRow only goes till index 10, so it cannot access CurrentRow[11] and CurrentRow[13]. So, when you are defining WholeRange, you should take at least 14 columns:
var WholeRange = ActiveSheet.getRange(StartRow, 1, RowRange, 14);
Hope this is useful for you!

Correct script to send only the last row of data in Google Sheets

The script I have is sending out the information in the format I want. The problem I have is that it is sending out each row as an indiviual email instead of only sending out the latest data. I only want the last row of data to be sent out.
function CustomEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
lastRow = sheet.getLastRow();
startrow= 2;
var range = sheet.getRange("A2:Z1000");
var UserData = range.getValues();
for (i in UserData) {
var row = UserData[i];
var name = row[2];//market
var senderEmail = ''
if (name === 'South')
{senderEmail = 'tom#no.com';}
else if (name === 'West')
{senderEmail = 'bob#bob.com';}
else if (name === 'East')
{senderEmail = 'non#no.com';}
var AgentOwner = row[18];//Agent Owner
var address = row[20];//Address
var City = row[21];//City
var State = row[22]//state
var Incident = row[17]//incident type
var Date = row[4]//date and time
emailBody = "New Security Incident Report from: " +AgentOwner+ "\nAddress: " +address+ "\nCity: " +City+ "\nState: " +State + "\nIncident: " +Incident + "\nDateTime:" +Date
MailApp.sendEmail(senderEmail,"Security Incident Report", emailBody);
}
}
Try this -
function CustomEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.getRange(sheet.getLastRow(), 1, 1, sheet.getLastColumn())[0];
Logger.log(row);
var name = row[2]; //market
var senderEmail = '';
if (name === 'South') {
senderEmail = 'tom#no.com';
} else if (name === 'West') {
senderEmail = 'bob#bob.com';
} else if (name === 'East') {
senderEmail = 'non#no.com';
}
var AgentOwner = row[18]; //Agent Owner
var address = row[20]; //Address
var City = row[21]; //City
var State = row[22]; //state
var Incident = row[17]; //incident type
var Date = row[4]; //date and time
emailBody =
'New Security Incident Report from: ' +
AgentOwner +
'\nAddress: ' +
address +
'\nCity: ' +
City +
'\nState: ' +
State +
'\nIncident: ' +
Incident +
'\nDateTime:' +
Date;
MailApp.sendEmail(senderEmail, 'Security Incident Report', emailBody);
}
Edit:
Go to script, paste new code, run the function, then in menu, View > Log and see if the row values are logged properly. If any issues with data indices, adjust them accordingly.

Automated duplicate check & bcc using Google Script

I wrote this JS to send email automatically using Google Script into a spreadsheet.
Unfortunately, the duplicate check is not working, and the bcc line trigger an error.
Actually I want to send an email only for the LAST answer into the spreadsheet everytime.
Could you help me?
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = active;
var dataRange = sheet.getRange(startRow, 1, numRows, 14)
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var name = row[2];
var surname = row[3];
var salesRepEmail = row[4];
var qualityAnalystEmail = "john#doe.com"
var customerEmail = row[5];
var websiteURL = row[6];
var solution1 = row[7];
var solution2 = row[8];
var solution3 = row[9];
var toResolve1 = row[10];
var toResolve2 = row[11];
var toResolve3 = row[12];
var checkDate = row[13];
var message = 'Bonjour '+ name + ' ' + surname + ', ' + 'blablabla';
var emailSent = row[14]; // Third column
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "Votre Optimisation De Site Mobile pour " +websiteURL;
MailApp.sendEmail(customerEmail, subject, message, {
cc: "",
bcc: qualityAnalystEmail,+ " " + salesRepEmail,
});
sheet.getRange(startRow + i, 15).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
Your code is triggering on bcc line cause you put a extra comma. As seen on the documentation, the bcc parameters should be a string with
a comma-separated list of email addresses to BCC
In your cas, you should'nt have:
bcc: qualityAnalystEmail,+ " " + salesRepEmail
but:
bcc: qualityAnalystEmail + ", " + salesRepEmail
which gives:
MailApp.sendEmail(customerEmail, subject, message, {
cc: "",
bcc: qualityAnalystEmail+ ", " + salesRepEmail
});
(You also put a extra comma after your bcc parameters which is not good)
Thank you so much , Please find below the datas and the script.
I will try to call the variables into the HTML afterwards using Google Scriptlet. For the moment, the simple text is sufficient. It seems to be working like that, but the code is not clean.
Image Du Tableau
// This constant is written in column O for rows for which an email
// has been sent successfully.
var EMAIL_SENT = "EMAIL_SENT";
function testSchemas() { {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = sheet.getLastRow();
var numRows = 1; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, 15)
// 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 name = row[2];
var surname = row[3];
var salesRepEmail = row[4];
var qualityAnalystEmail = "xxx#yyy.com"
var customerEmail = row[5];
var websiteURL = row[6];
var solution1 = row[7];
var solution2 = row[8];
var solution3 = row[9];
var toResolve1 = row[10];
var toResolve2 = row[11];
var toResolve3 = row[12];
var checkDate = row[13];
function doGet() {
return HtmlService
.createTemplateFromFile('Index')
.evaluate();
}
Logger.log(doGet);
var htmlBody = HtmlService.createHtmlOutputFromFile('Index').getContent();
var message = 'Bonjour '+ name + ' ' + surname + ', ' + 'c\'est avec grand plaisir que je vous écris pour résumer ... - '+solution1+' \n\n- '+solution2+' \n\n- '+solution3+' \n\nMalgré...';
var emailSent = row[14]; // Third column
if (emailSent != "EMAIL_SENT") { // Prevents sending duplicates
/*MailApp.sendEmail(customerEmail, subject, message, {
cc: "",
bcc: qualityAnalystEmail + ", " + salesRepEmail
}); */
MailApp.sendEmail({
to: customerEmail,
bcc: qualityAnalystEmail + ", " + salesRepEmail,
subject: 'Résumé De Notre Consultation Du Site Mobile ' + websiteURL,
htmlBody: htmlBody,
});
}
Logger.log(name);
sheet.getRange(startRow + i, 15).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}

Bold text in email - Google Spreadsheet

I'm looking some way to bold text in email and when I open the msgBox.
I want bold only headlines, like in picture below:
this is my script, you choose some cell in row that interests you and run the function. Function show information about data from every cell in row, like inforamtion about "Name" and "email". Then if you push send it will send email with this informations. I want bold headlines for better clarity.
function sendEmail(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var fr1 = ss.getSheetByName("Sheet1");
var cell = ss.getActiveCell().getRow();
var lastColumn = fr1.getLastColumn();
var lastRowValues = fr1.getRange(cell,1,1,lastColumn).getValues();
var Nr = lastRowValues[0][0];
var Data = lastRowValues[0][1];
var Information = lastRowValues[0][2];
var Name = lastRowValues[0][3];
var email = lastRowValues[0][4];
var urlOfSS = ss.getUrl();
var message = "Message" +
"\n " +
"\nNr: " + Nr +
"\nData: " + Data +
"\nInformation: " + Information +
"\nName " + Name +
"\nEmail: " + email +
"\n " +
"\n Link to spreadsheet:" +
"\n " + urlOfSS;
var emails = ss.getSheetByName("Sheet1");
var numRows = emails.getLastRow();
var emailTo = email;
var subject = "Zgłoszenie FAS - " + Nr;
if (email == ""){
Browser.msgBox('This row is empty - Choose another');
} else {
var ui = SpreadsheetApp.getUi();
var l = ss.getSheets()[0]
var response = ui.alert('Email', "Do you want email \nNr: " + l.getRange(cell, 1).getValue() + "\nData: " + l.getRange(cell, 2).getValue() + "\nInforamtion: " + l.getRange(cell, 3).getValue()
+ "\nName: " + l.getRange(cell, 4).getValue(), ui.ButtonSet.YES_NO);
if (response == ui.Button.YES) {
GmailApp.sendEmail(emailTo, subject, message);
} else {
Logger.log('The user clicked "No" or the dialog\'s close button.');
}
}
}
Regards
If I understand the requirement, Only the side headers(underlined in the screenshot) needs decoration.
While going through the Google Apps Scripts - Documentation, I came through this.
Hope this helps you.
Using the HtmlServices & HtmlOutputFromFile() would fulfill your requirement.
Please refer to Custom Dialogs. This would help you
https://developers.google.com/apps-script/guides/dialogs

Categories

Resources