Auto Send Email When Checkbox is Checked - Google Sheet - google-apps-script

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

Related

Comparing Dates in Google Sheets Script Editor

I am very new to this, so please bear with me. I am trying to get my code to look at each cell in a column, then compare that date to the current date, and if they match send an email. I am aware I will need a loop of some sort to get it to look through the column, but I haven't even gotten that far. I've tried every method I can find online to just get it to compare one cell to the date and send the email.
I tested the email function prior to adjusting it to compare the date, so I know that is working. Put something definitely isn't working...
function sendEmail() {
//Fetch the date
var removalDateRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Expirations").getRange("E2");
var removalDate = removalDateRange.getValue();
var currentDateRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Alerts").getRange("C2");
var currentDate = new Date();
var ui = SpreadsheetApp.getUi();
//Check Date
if (removalDate == currentDate) {
//Fetch the email address
var emailRange =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Alerts").getRange("B2");
var emailAddress = emailRange.getValue();
//Fetch Item Brand
var itemBrandRange =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Expirations").getRange("B2");
var itemBrand = itemBrandRange.getValue();
//Fetch Item Name
var itemNameRange =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Expirations").getRange("A2");
var itemName = itemNameRange.getValue();
//Fetch Item Location
var itemLocationRange =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Expirations").getRange("H2");
var itemLocation = itemLocationRange.getValue();
// Send Alert Email
var message = 'The ' + itemBrand + ' ' + itemName + ' in ' + itemLocation + ' will expire in 2 months. Please use and replace item.';
// Second Column
var subject = 'Pantry Alert';
MailApp.sendEmail(emailAddress, subject, message);
}
}
EDIT
Okay, I had it working late last night and even got it to loop through, and somehow I've broken it again. I've been looking at answers for hours trying to adjust things to make it work. What am I doing wrong?
function emailAlert() {
// today's date information
var today = new Date();
var todayMonth = today.getMonth() + 1;
var todayDay = today.getDate();
var todayYear = today.getFullYear();
// 2 months from now
var oneMonthFromToday = new Date(todayYear, todayMonth, todayDay);
var oneMonthMonth = oneMonthFromToday.getMonth() + 2;
var oneMonthDay = oneMonthFromToday.getDate();
var oneMonthYear = oneMonthFromToday.getYear();
// getting data from spreadsheet
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Exp");
var startRow = 2; // First row of data to process
var numRows = 500; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, 999);
var data = dataRange.getValues();
//looping through all of the rows
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var expireDateFormat = Utilities.formatDate(new Date(row[5]),
'ET',
'MM/dd/yyyy'
);
//email Information
var subject = 'Pantry Item Needs Attention!';
var message1 =
row[6] + ' ' + row[3] + ' of ' + row[2] + ' ' + row[1] + ' will expire on ' + expireDateFormat + '. Item can be found in ' + row[7]
+ '. Please Remove and Replace Item.' +
'\n' + 'Thanks Steve!';
var message2 =
row[6] + ' ' + row[3] + ' of ' + row[2] + ' ' + row[1] + ' will expire on ' + expireDateFormat + '. Item can be found in ' + row[7] +
'. Please ensure item has been replaced, removed from the pantry, and deleted from inventory.' +
'\n' + 'Thanks Steve!'
//expiration date information
var expireDateMonth = new Date(row[5]).getMonth() + 1;
var expireDateDay = new Date(row[5]).getDate();
var expireDateYear = new Date(row[5]).getYear();
//checking for today
if (
expireDateMonth === todayMonth &&
expireDateDay === todayDay &&
expireDateYear === todayYear
) {
ui.alert(message1);
}
}
}
Dates can be frustrating to work with, so consider doing the whole thing (loop, if then statement...) with an integer first and then returning to the date part if you're having trouble. That said, try adjusting the top of your code to look like the following:
var ss =SpreadsheetApp.getActiveSpreadsheet();
var removalDateVal = ss.getSheetByName("Expirations").getRange("E2").getValue();
var removalDate = new Date(removalDateVal);
var currentDateVal = ss.getSheetByName("Alerts").getRange("C2").getValue();
var currentDate = new Date(currentDateVal);
That will give you two date objects. But BEWARE! These dates contain time as well as calendar date so they may not equal each other even when they appear to. Use setHours() to zero out the date as seen below.
currentDate.setHours(0,0,0);
removalDate.setHours(0,0,0);
Other notes, it's best practice to set a variable for a spreadsheet and worksheet as shown by Google here. It makes the code much more readable.

Trouble automating email from google sheets

I am very new to google script and cannot work out why my script is not functioning. When I try to run the code I get the following error code -
TypeError: Cannot read property "range" from undefined. (line 2, file "Code"
If anybody could give a novice some help that would be greatly appreciated!
function sendEmail(event){
var sheet = event.range.getSheet();
if(sheet.getName() !== 'Sheet1') {
// if it's not the correct sheet we end the function here
return;
}
var range = event.range;
var row = range.getRow(); // we get the index of the row of the
edited
cell
var dataRange = sheet.getRange("A" + row + ":C" + row);
var values = dataRange.getValues();
var rowValues = values[0];
var recipient = rowValues[0];
var email = rowValues[1];
var refillsNumber = rowValues[2];
if (refillsNumber = 2) {
// if 'refillsNumber' is not equal to 2 we end the function here
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' +
refillsNumber + ' remaining would you like to buy more?' + '\n\n' +
'Kind regards,' + '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
MailApp.sendEmail(email,subject,message);
return
}
if (refillsNumber !== 0) {
return}
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' +
refillsNumber + ' remaining would you like to buy more? If not then
would you like to end your subsription?' + '\n\n' + 'Kind regards,'
+ '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
MailApp.sendEmail(email,subject,message);
return
}
// in addition to this script which aims to send an email to the
customer when they only have 2 refill remaining -
/// I also want to set up a function that sends an email when they
have 0 refills remaining
Send Emails by Editing Column C
I changed the Sheet name and added an extra condition. I also commented out the MailApp.sends and replaced them with writes to the sidebar so that I could test it without trying to send emails.
You will need to create an onEdit trigger for this function.
function sendMailOnEdit(event){
var sheet = event.range.getSheet();
if(sheet.getName() !== 'Sheet2' || event.range.columnStart!=3) {return;}
var range=event.range;
var row=range.rowStart;
var dataRange = sheet.getRange(row,1,1,3);
var values=dataRange.getValues();
var rowValues=values[0];
var recipient = rowValues[0];
var email = rowValues[1];
var refillsNumber = rowValues[2];
if (refillsNumber==2) {
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' + refillsNumber + ' remaining would you like to buy more?' + '\n\n' + 'Kind regards,' + '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
//MailApp.sendEmail(email,subject,message);
var html=Utilities.formatString('<br />Email: %s<br />Subject: %s<br />message: %s<br /><hr>', email,subject,message);
var userInterface=HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showSidebar(userInterface);
return
}
if (refillsNumber !== 0) {return}
var message = 'Dear ' + recipient + ',\n\n'+ 'You have ' + refillsNumber + ' remaining would you like to buy more? If not then would you like to end your subsription?' + '\n\n' + 'Kind regards,' + '\n\n' + 'The revol team.';
var subject = 'Refill reminder';
//MailApp.sendEmail(email,subject,message);
var html=Utilities.formatString('<br />Email: %s<br />Subject: %s<br />message: %s<br /><hr>', email,subject,message);
var userInterface=HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showSidebar(userInterface);
}
This is what my spreadsheet looks like:
And let me remind you that you cannot run this function without an event object.

App Script - Send filtered table as HTML in Email

New to Apps scripts...
I'm trying to send a schedule, (a table in sheets), as HTML in an email.
I have managed to piece together a script that does what I want... mostly.
If I use the following range, the script works.
(This is the visible table filtered, where results happen to be in the first 26 rows)
var schedRange = sheet.getRange("A1:J26");
The problem is, the full table is "A1:J261", and when I use the full table range (so I can filter other criteria), I get:
Limit Exceeded: Email Body Size.
Can I specify only the filtered table, excluding all hidden content?
My end objective is to be able to:
Loop through available criteria of COL J, with some exceptions
(haven't started on this yet)
For each criteria, send table as HTML in email.
I've made a public version available here
Any assistance is much appreciated!!
Thanks in advance.
To get around sending only visible only rows, I have a query setup from my original data table, that is dependant on a cell setup with data validation. (essentially a filter)
Instead of running a filter on the whole table, now my table is made up of only what I wanted filtered. (so no hidden rows)
The query looks like this:
=QUERY(DATA!A1:J,"select A, C, D, E, F, G, H, I where J = '"&E1&"'",+1)
Where E1 is the Company I want to email and the result of the query is the table I want to send them.
The following is the script I have been using for the last few months to send the booking email to each company (as a HTML table) within a Gmail email, from Google Sheets.
I can't locate/recall where the various snippets came from, so apologies for not referencing any authors that contributed to this function.
It works a treat for me, so hopefully, all of this can help you!
function sendEmail_draft() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var Avals = ss.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length+1;
var recipient = sheet.getRange("B1").getValue(); // "TO" email address
var name = SpreadsheetApp.getActiveSpreadsheet().getName();
var subject = "DRAFT Booking - "+ sheet.getRange("E1").getValue()+ " ";
subject += Utilities.formatDate(
sheet.getRange("D1").getValue(),
ss.getSpreadsheetTimeZone(),
"EEE, MMM d yyyy"),
sheet.getRange("D1").getValue()
var schedRange = sheet.getRange("A3:H"+Alast);
// Put Name & Date into email first.
// We only want the schedule within borders, so
// these are handled separately.
var body = '<div style="text-align:center;display: inline-block;font-family: arial,sans,sans-serif">'
body += '<H1>'+ "COMPANY NAME "+ sheet.getRange("E1").getValue() +'</H1>';
body += '<H2>'+ "WORKBOOK NAME:- "+ name +'</H2>';
body += '<H2>'+ "Date of Booking - "
+ Utilities.formatDate(
sheet.getRange("D1").getValue(),
ss.getSpreadsheetTimeZone(),
"EEEEE, MMMMM d, yyyy")
+ '</H2>';
body += getHtmlTable(schedRange);
body += '</div>';
debugger;
//recipient = Session.getActiveUser().getEmail(); // For debugging, send only to self
GmailApp.sendEmail(recipient, subject, "Requires HTML", {htmlBody:body})
}
/////////////
/**
* Return a string containing an HTML table representation
* of the given range, preserving style settings.
*/
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();
// Get column widths in pixels
var colWidths = [];
for (var col=startCol; col<=lastCol; col++) {
colWidths.push(sheet.getColumnWidth(col));
}
// Get Row heights in pixels
var rowHeights = [];
for (var row=startRow; row<=lastRow; row++) {
rowHeights.push(sheet.getRowHeight(row));
}
// Future consideration...
var numberFormats = range.getNumberFormats();
// Build HTML Table, with inline styling for each cell
var tableFormat = 'style="border:1px solid black;border-collapse:collapse;text-align:center" border = 1 cellpadding = 5';
var html = ['<table '+tableFormat+'>'];
// Column widths appear outside of table rows
for (col=0;col<colWidths.length;col++) {
html.push('<col width="'+colWidths[col]+'">')
}
// Populate rows
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(),
'EEE, MMM dd YY'); /// 'EEE, MMM dd - h:mm a');
}
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('');
}
You're hitting the defined limit. This was mentioned in Current limitations:

Test for missing user input, and stop or delay a Google script from running

I have the below Google script running in a Google sheet.
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);
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 + " 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>";
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.
};
}
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
} }
It works fine, but if the person who fills out the spreadsheet doesn't fill out the columns in ascending order, the email that gets sent misses out information.
Is there a way to delay the running of the script until the row (columns B,C,D,E,F & G) has been completed? I've looked at utilities.sleep but not sure where to put it in the script. When I've tried to do so, it doesn't seem to make any difference.
Test the return object for missing values. The way that the following code does this is to convert the object to an array, and then get the length of the array. There should be 4 elements in the array. If the value of any of the variables that go into the object is undefined, then that element will be missing, and therefore the array will have fewer than 4 elements.
function sendNotification() {
var rowVals = getActiveRowValues(sheet);//Returns an object
var testArray = JSON.stringify(o).split(",");//Convert object to an array
Logger.log('length: ' + testArray.length)
if (testArray.length !== 4) {//Object must have 4 elements
Browser.msgBox('There is missing data!');
return; //quit
}
}
function getActiveRowValues() {
var depot = 'something';
var date;//For testing purposes - leave this as undefined
var name = 'the name';
var team = 'team is';
var o = {
depot: depot,
date: date,
name: name,
team: team
}
Logger.log(JSON.stringify(o))
return o;
}
You could improve upon this by highlighting cells with missing data, or determining exactly which piece of data is missing and informing the user.
This is probably not the answer that you want to hear. But I'm not familiar with any trigger that's associated to specific cells. The question has come up many times and the closest we have is the on edit event. I suppose you could check on each on edit to see if the appropriate cells contained appropriate data. Personally, I would prefer a dialog or sidebar for this situation and then I could have all of the power of Javascript in an html environment to help with the form submission process and in the end I'd probably just put a send button there.
I carried on playing around with utilities.sleep and have now got it to work as shown below.
function sendNotification(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
if(event.range.getA1Notation().indexOf("G") > -1 && sheet.getRange("G" + row).getDisplayValue() > 999)
{
Utilities.sleep(1200000)
var rowVals = getActiveRowValues(sheet);
var aliases = GmailApp.getAliases();
Logger.log(aliases);
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 + " 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>";
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.
};
}
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
} }
It now delays the script from running for 1 minute, allowing time for the remaining cells to be completed before the script pull data from them.

Can you Sendnotification in Google Script for multiple sheets?

I'd like to send a notification to someone when a particular cell (ie document) is updated. Specifically, when a cell in one row is updated, it would send a notification to the owner listed in the same row. For example B47 gets updated, it send an email to B3.
I've gotten the script to work when it's pointed to one sheet. But when I try to ask the script to run over multiple sheets/tabs, I get error 'Script function not found: sendNotification' Is it possible to have this script work for multiple sheets/tabs in the same google doc? Updates are pulling from a different source so I'd like to keep using getSheetbyName instead of getActiveSheet.
Any help would be much appreciated. Here's my code where it stands:
function shellFunction() {
var sheets = ['Arabic', 'Portuguese'];
for (var s in sheets) {
toTrigger(sheets[s]);
}
function toTrigger(sheetName) {
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheets[s]);
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = sheet.getRange('J' + sheet.getActiveCell().getRowIndex()).getValue();
var message = '';
if (cell.indexOf('B') != -1) {
message = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue()
}
var subject = 'The ' + sheet.getRange('F' + sheet.getActiveCell().getRowIndex()).getValue() + ' ' + sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' needs your Translation';
var body = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' has been updated. Can you please update ' + sheet.getRange('G' + sheet.getActiveCell().getRowIndex()).getValue() + '? Please remember to update the date column in the Resource Document when the translation is complete:' + ss.getUrl();
MailApp.sendEmail(recipients, subject, body);
}
}
}
Should this line
var sheet = ss.getSheetByName(sheets[s]);
be changed to
var sheet = ss.getSheetByName(sheetName);
since that is the name of the passed sheet?
EDIT
There were a couple other items which may have caused issue. I made edits for this result:
function shellFunction() {
var sheets = ['Arabic', 'Portuguese'];
for (var s in sheets) {
toTrigger(sheets[s]);
}
}
function toTrigger(sheetName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = sheet.getRange('J' + sheet.getActiveCell().getRowIndex()).getValue();
var message = '';
if (cell.indexOf('B') != -1) {
message = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue()
}
var subject = 'The ' + sheet.getRange('F' + sheet.getActiveCell().getRowIndex()).getValue() + ' ' + sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' needs your Translation';
var body = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' has been updated. Can you please update ' + sheet.getRange('G' + sheet.getActiveCell().getRowIndex()).getValue() + '? Please remember to update the date column in the Resource Document when the translation is complete:' + ss.getUrl();
MailApp.sendEmail(recipients, subject, body);
}
My first change was to not nest the functions. To do this I added a closing curly bracket before the toTrigger function and removed one of the last in your code. After that there was another nested function which actually made up all of the toTrigger function. It was called sendNotifocation which matched your error. I removed that by removing the line after the toTrigger function declaration and another curly bracket at the end of your code.
Last, I made the above edit. In my test it seemed to work fine, except that I commented out the call to actually send an email and only debugged to the line just prior to that point.