This script works, except it sends multiple emails, This script check Column F for any value above 0 then sends an email.Column F is where i manually enter data. Trying to get it to only send one email and put a "Email Sent" in column H. Then check if column H has a "Email Sent" if so don't send email again.
Here Is what my sheet looks like
https://docs.google.com/spreadsheets/d/1o5jKMDECIFozrwAQx6EDvPL1NkoMQ1nbpkd6AdS9ULk/edit?usp=sharing
function sendEmails() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses"); //get the sheet "Form Responses"
var data = sSheet.getRange(2, 1, sSheet.getLastRow(),sSheet.getLastColumn()).getValues(); //get the values of your table, without the header
var lastRow = sSheet.getLastRow();//gets the last row of entered data
var yourColumn = "H";//set your column
var yourFunction = ("Email Sent");//whatever function or formula or data you want,just don't forget to use lastRow do do the row number
sSheet.getRange(yourColumn+lastRow).setValue(yourFunction);
for (var i = 0; i < data.length; i++) { // For each element of your tab
var row = data[i];
if(row[5] > 0) { // If the person have got at least 1 report outstanding (column E)
var body = "Good day "+ row[0] + " you have " + row[5] + " Internal Audit reports outstanding.";
GmailApp.sendEmail(row[1],"Outstanding Internal Audit Reports", body); // Sending a mail to alert
}
}
}
Try This:
function sendEmailsToTechs() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName("Form Responses");
//var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var data=rg.getValues();
var hRange=sh.getRange(2,8,sh.getLastRow(),1);
var hValues=hRange.getValues();
for (var i=1;i<data.length;i++){
var row = data[i];
if(row[5] && row[7]!='Email Sent') {
var body = "Good day "+ row[0] + " you have " + row[5] + " Internal Audit reports outstanding.";
GmailApp.sendEmail(row[1],"Outstanding Internal Audit Reports", body);
//Logger.log(body);
hValues[i-1][0]='Email Sent';
}
}
hRange.setValues(hValues);//Puts the values into the spreadsheet all at one time.
}
Related
I am trying to have this script loop per column. If a date in the column is the same as today's date, the script will send an email using the persons name and email address detailed in the same row.
Table of Expiry Dates
function myFunction()
{
var spreadSheet = SpreadsheetApp.getActiveSheet();
var dataRange = spreadSheet.getDataRange();
var data = dataRange.getValues();
var date = Utilities.formatDate(new Date(), "GMT", "dd/MM/yyyy")
var engcheck1 = dataRange.getColumn[2];
for (var i = 1; i < data.length; i++)
if (engcheck1 == date)
{
var row = data[i];
var emailAddress = row[7]; //position of email header — 1
var name = row[1]; // position of name header — 1
var subject = "Your Currency for Engineering is now expired";
var text = "Please note that your currency has expired today (" + date +"). You are now unauthorised to carry out any engineering tasks until you have been signed off by a member of the engineering team.";
var message = "Dear " + name + "," + "\n\n" + text + "\n\n" + "Please get back in currency at your earliest convenience." + "\n\n" + "Many thanks," + "\n" + "Dominic Paul"
MailApp.sendEmail(emailAddress, subject, message);
}(i);
}
Without the 'If' statement, the script will loop through each row and sending out an email address. When I include the 'If' statement, nothing is sent to the email addresses. Either I am using the if statement incorrectly or I am not targeting the column accurately. I tried creating a variable engcheck1 for column 2 ONLY but no email is sent despite today being one of the dates in column 2 (C).
I did not understand, what is var engcheck1 = dataRange.getColumn[2];.
If you need to send and email if date is the same as the value in C column, provided column C has type Plain text, this is the answer:
function myFunction() {
var spreadSheet = SpreadsheetApp.getActiveSheet();
var dataRange = spreadSheet.getDataRange();
var lastRow = SpreadsheetApp.getActiveSpreadsheet().getDataRange().getNumRows();
var dateData = spreadSheet.getRange("C1:C" + lastRow).getDisplayValues().flat();
var data = dataRange.getValues();
var date = Utilities.formatDate(new Date(), "GMT", "dd/MM/yyyy")
for (var i = 1; i < data.length; i++) {
var rowDate = dateData[i];
var row = data[i];
// if the date in row is the same as date variable
if (rowDate === date) {
var emailAddress = row[7]; //position of email header — 1
var name = row[1]; // position of name header — 1
var subject = "Your Currency for Engineering is now expired";
var text = "Please ...";
var message = "Dear ...";
MailApp.sendEmail(emailAddress, subject, message);
};
}
}
Try this:
function myFunction() {
const ss = SpreadsheetApp.getActive();
var sh = ss.getActiveSheet();
var rg = sh.getDataRange();
var vs = rg.getValues();
const dt = new Date();
var dtv = new Date(dt.getFullYear(),dt.getMonth(),dt.getDate()).valueOf();
vs.forEach((r,i) => {
let d = new Date(r[2]);
let dv = new Date(d.getFullYear(),d.getMonth(),d.getDate()).valueOf();
if(dv == dtv ) {
//send you email
}
})
}
I have a sendEmail function which works almost perfectly with my Google Sheet.
The getLastRow function return all my blank rows because they have an hidden formula and I'd like to grab only filled rows.
Here is my code :
var EMAIL_SENT = 'EMAIL SENT';
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow();
// Fetch the range of cells
var dataRange = sheet.getRange(2, 1,numRows-1,20);
// 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[7] + "," + row[9] + "," + row[13];
var message = row[18];
var emailSent = row[19];
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = 'Un nouvel adhérent vous a été affecté';
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 20).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
Already tried var data = dataRange.getDisplayValues(); instead of var data = dataRange.getValues();without significant result.
Do you have any idea ?
Here is a sample of my sheet :
Solution:
Replace this:
var numRows = sheet.getLastRow();
with:
var numRows = sheet.getRange("F1:F").getDisplayValues().filter(String).length;
The latter will filter out the cells of your sheet that are empty even if they contain a formula.
References:
getDisplayValues()
filter()
Why don't you just add an if statement inside a for loop and check if one of the cells is empty, and break the loop if so.
Your code would look something like this:
var EMAIL_SENT = 'EMAIL SENT';
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow();
// Fetch the range of cells
var dataRange = sheet.getRange(2, 1,numRows-1,20);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
if(row[6] === "") break;
var emailAddress = row[7] + "," + row[9] + "," + row[13];
var message = row[18];
var emailSent = row[19];
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = 'Un nouvel adhérent vous a été affecté';
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 20).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
I'm having an issue where I want to be able to send an email with CC's based off cell values. i.e. both the main recipient email and CC email are in the spreadsheet in the same row. The code should cycle through each row and send an email to the recipient and attaches the CC to that email.
My code is as follows:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // Start at second row because the first row contains the data labels
var numRows = 10; // Put in here the number of rows you want to process
// Fetch the range of cells A2:B4
// Column A = Email Address, Column B = First Name
var dataRange = sheet.getRange("A2:C")
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var name = row[0];
var emailAddress = row[1];
var daysAbsent = row[2];
var CC = row[3];
var message = "Hi " + name + ",\n. We see that you have been absent for " + daysAbsent + " days.";
var subject = "Attendance Notification";
MailApp.sendEmail(emailAddress, subject, message,{
cc: CC
});
}
}
Is it possible to encrypt a converted google sheet into PDF before sending it as an attachment in an email ?
This is my current code: It hides the sheet I don't need to be converted and converting the other sheet into PDF. What I would like to achieve here is for the converted PDF to be password encrypted because it contains some personal information.
function myFunction() {
Utilities.sleep(200);
var sheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 1");
var pdfsheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
sheet.hideSheet();
var substringsubject = pdfsheet.getRange("B4:B4").getValues();
var substringnname = pdfsheet.getRange("B3:B3").getValues();
var substringidnum = pdfsheet.getRange("B7:B7").getValues();
var startRow =9; // First row of data to process B9:B9
var numRows =1; // Number of rows to process
// Fetch the range of cells B9:B9
var dataRange = pdfsheet.getRange(startRow, 1, numRows, 2)
// 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 email = row[1];
var emailcc = row[2];
// Subject of email message
var subject = "USER ACCOUNT DETAILS " + substringsubject + " " + substringidnum + "";
var ss= SpreadsheetApp.getActiveSpreadsheet();
// Email Body can be HTML too
var body = '<body>' + ' Hi ' + substringnname +',<br><br>' +
'Please see attached file for your account details.</p>' +
//'<p> Click here to go to google.<p>'
'</body>'
var pdf = DriveApp.getFileById(ss.getId()).getAs("application/pdf");
pdf.setName(substringsubject+" "+substringidnum+" .pdf");
// If allowed to send emails, send the email with the PDF attachment
MailApp.sendEmail({
to:email,
cc:emailcc,
subject:subject,
htmlBody:body,
attachments:[pdf]
});
sheet.showSheet();
}
}
Thank you.
You can't protect your PDF directly from Apps script. See this previous SO question.
I have created this code to send a template email from Google Spreadsheet. I really need to BCC another recipient. I have checked out Class Gmail App. It didn't quite make sense to me.
var EMAIL_SENT = "EMAIL_SENT";
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menu = [{
name: "Send Email",
functionName: "sendEmails2"
}];
ss.addMenu("Send Email", menu);
}
function sendEmails2() {
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, 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 = "Hello Team,\n\n" + row[1] + " Please do the Following:..."; // Second column
var emailSent = row[2]; // Third column
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "Team Email";
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();
}
}
}
Check the version of sendEmail(recipient, subject, body, options) method with optional arguments, which can include bcc.
Class GmailApp also has a similar method sendEmail(recipient, subject, body, options), which can include bcc.
Example:
...
var options = {
bcc: 'bccmail0#domain.ext, bccmail1#domain.ext'
};
MailApp.sendEmail(emailAddress, subject, message, options);
...