Send automated email for specific value of a drop down column - google-apps-script

I have tried many different codes to send an email alert when column F in my Google sheet has the value "Yes". I am selecting this value from a drop down. But no emails are sent. I have tried different emails also. Nothing works. This is the code I am trying right now.
function Email(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("FY");
var row = s.getActiveRange().getRow();
var status = s.getRange(row,6).getValue();
var subject = 'subject'; var message = 'body';
var email ="";
if (e.value === "Yes" && e.range.getColumn() === 6) {
GmailApp.sendEmail(email,subject,message);
}
};

You need to use an installed trigger see here to use this on edit script.
Go to 'Edit' -> 'Current project's triggers' and set a trigger as shown below.
Code:
function onEdit(e){
var getRange = e.range;
var getValue = getRange.getValue();
var getCol = getRange.getColumn();
if(getValue == "Yes" && getCol == 6){
var subject = 'subject';
var message = 'body';
var email = "---------------";
MailApp.sendEmail(email, subject, message);
}
}

Related

Google App Script to trigger on cell value change with email notification

looking for a help to fix my script in Google spreadsheets.
I want to build a function that sends an email every time a certain cell in the list is updated.
Here is my code, but it doesn't work.
Looking for your help to find and fix my issue
function onEdit(e) {
const specificSheet = "Inventory"
const specificCell = "B1"
let sheetCheck = (e.range.getSheet().getName() == specificSheet)
let cellCheck = (e.range.getA1Notation() == specificCell)
if (!(sheetCheck && cellCheck)) {
return
}
else {
sendEmail(){
var subject = "New update";
var emailAddress = "example#gmail.com";
var message = "new update: link";
MailApp.sendEmail(emailAddress, subject, message)
}
}
}
Send email on an Edit
function onMyEdit(e) {
const sh = e.range.getSheet();
if (sh.getName() = "Inventory" && e.range.columnStart == 2 && e.range.rowStart == 1) {
var subject = "New update";
var emailAddress = "example#gmail.com";
var message = "new update: link";
MailApp.sendEmail(emailAddress, subject, message)
}
}
I think this needs to be an installable trigger in order to send an email.
Sometimes Sheet can not process complex operations related to onEdit(e), so maybe this could help:
function onEdit(e) {
const specificSheet = "Inventory";
const specificCell = "B1";
var range = e.range;
var ss = e.source;
var sheetName = ss.getActiveSheet().getName();
var a1Notation = range.getA1Notation();
if ((sheetName==specificSheet) && (a1Notation==specificCell)) {
var props = PropertiesService.getScriptProperties();
props.setProperty("CHECKED","TRUE");
}
}
function sendEmail(){
var subject = "New update";
var emailAddress = "example#gmail.com";
var message = "new update: link";
var props = PropertiesService.getScriptProperties();
var checked = props.getProperty("CHECKED");
if (checked == "TRUE"){
GmailApp.sendEmail(emailAddress, subject, message);
Utilities.sleep(3000);
props.setProperty("CHECKED","FALSE");
}
}
Another thing you should do is setting sendEmail() function is activated by time trigger every minute or so...

Showing exception error while trying to send emails with a sheet as an excel attachment

I am trying to send emails with a specific tab of a Google Spreadsheet as an Excel attachment to 40-50 students using installable edit trigger. It is showing
Exception: You do not have permission to call UrlFetchApp.fetch. Required permissions: googleapis.com/auth/script.external_request.
I reviewed several related posts and answer at Stackoverflow and Google but can't find anyway to do it manually.
My codes are:
function classAttendance(e){
var spreadsheet = SpreadsheetApp.getActive();
var dashboard = spreadsheet.getSheetByName("Dashboard");
var sheetName = dashboard.getRange("A4").getValue();
var sheetw = dashboard.getRange("A8");
var sheetw2 = dashboard.getRange("G8");
if (sheetName == 'All'){
if (e.range.getA1Notation() === 'C6' && e.range.getValue() === "Send Emails") {
sheetw.setValue('Sending emails to all students. Please Wait!').setFontColor('Red');
//refreshSheet();
sendEmails();
sheetw.setValue('You may take class attendance now. Thank You!').setFontColor('Green');
sheetw2.setValue('You may do manual entry now. Thank You!').setFontColor('Green');
}
if ((e.range.getA1Notation() === 'C6') && (e.range.getValue() === "Start 1-Period" || e.range.getValue() === "Start 2-Period" || e.range.getValue() === "Error Correction")) {
dashboard.getRange("C6").setValue('Please Select');
}
}
}
function sendEmails(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssID = ss.getId();
var sheetName = ss.getName();
var sh = SpreadsheetApp.getActive();
var sheet1 = sh.getSheetByName("TempDataSet");
var shID = sheet1.getSheetId().toString();
var subject = 'Your Attendance Record at BDU';
var body = 'Dear Student,'+ '\n\n' + 'Greetings! Please find the attendance record attached for your reference.' + '\n\n' + 'Thank you.';
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var url = "https://docs.google.com/spreadsheets/d/"+ ssID + "/export?format=xlsx&id="+ssID+"&gid="+shID;
var result = UrlFetchApp.fetch(url , requestData);
var contents = result.getContent();
var column = 3;
contents.sort({column: column, ascending:true});
var sheet2 = sh.getSheetByName('StudentList');
var data = sheet2.getLastRow();
var students = [];
var students = sheet2.getRange(2, 6, data).getValues();
for (var i=0; i<students.length; i++){ // you are looping through rows and selecting the 1st and only column index
if (students[i][0] !== ''){
MailApp.sendEmail(students[i][0].toString(), subject ,body, {attachments:[{fileName:sheetName+".xls", content:contents, mimeType:"application//xls"}]});
}
}
}
I created a standalone scripts where there are many functions including sendEmails() at my Google drive, then invoked the scripts as a library to my Google spreadsheet. Then I called the library in the script editor of my Google Sheet and also created an onEdit trigger for sendEmails(). All other functions in the library called are working fine.
The library seems to be added after adding the trigger. Hence authorization scopes are missing from previous authorization. The following should trigger re-authorization:
Remove the installed edit trigger and re-add it.
Click Run button after selecting classAttendance2 manually from script editor>

How do I call a mailApp function within an onEdit function?

I have an onEdit function where if executed should send an email. However, some research has turned up that the mailApp functions don't work with onEdit. I'm currently toying around with workarounds but wondering if others have solutions they've come up with.
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var sheetName = sheet.getName();
//if editing specific sheet
if (sheetName == "draft_test" ) {
//if editing 6th column
var r = e.source.getActiveRange();
if (r.getColumn() == 6 ) {
var player = sheet.getActiveCell().getValue();
// Display a dialog box with a message and "Yes" and "No" buttons.
var ui = SpreadsheetApp.getUi();
var response = ui.alert('Do you want to draft '+player+'?', ui.ButtonSet.YES_NO);
// Process the user's response.
if (response == ui.Button.YES) {
//***********FOR SOME REASON EXECUTING THIS FUNCTION ISNT WORKING******************
emailLeague();
//sortAutoRoster();
} else {
}
}
}
}
function emailLeague() {
var draftSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("draft_test");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("test_email");
var emailSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Manager Info");
//actual email address omitted
var recipient = 'emailaddress#gmail.com';
//get array of all picks on "draft test" tab, and find latest one
var picks = draftSheet.getRange(3,6,146,1).getValues();
for (var i=0; i<picks.length; i++){
if (picks[i] == ""){
var latestPick = i;
break;
}
}
var subject = sheet.getRange(i+1, 2).getValue();
var body = sheet.getRange(i+1, 1).getValue();
MailApp.sendEmail(recipient, subject, body);
}

MailApp.SendEmail script for multiple tabs

I have been looking how to write the script to check and run on multiple tabs. What I have now, I would need to copy/paste and set execution triggers one by one.
Script I have:
function SendEmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("1");
var value = sheet.getRange("F3").getValue();
var subject = "subject";
var message = "message";
if (value >0){
MailApp.sendEmail("email", subject, message);
}
}
I have this running every 8 hours (trigger run).
I am looking to add more tabs so that for each tab the script can check and send an email if the value of individual tabs is more than 0.
Any ideas on how to do this?
The value in every tab is under F3. Tab names, for example, 1,2,3,4...
Thank you!!!
This should do what you looking for if I understood the issue correctly.
function SendEmail() {
//Get the Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Get all Sheets in the Spreadsheet
var sheets = ss.getSheets();
//Create a variable for the email address, subject and message
var email = "";
var subject = "";
var message = "";
//Can change the starting sheet by changing the value of "i" - 0 will be the first sheet.
for (var i = 0; i < sheets.length; i++){
var sheet = sheets[i];
var value = sheet.getRange("F3").getValue();
switch(sheet.getSheetName) {
case "Sheet1":
email = "email1#domain.com";
break;
case "Sheet2":
email = "email2#domain.com";
break;
default:
value = 1
email = "yourEmailAddress#domain.com";
subject = "Message Failed to Send";
message = "There was an error sending email, please investigate";
}
if (value >0){
MailApp.sendEmail(email, subject, message);
}//END OF IF STATEMENT
}//END OF FOR LOOP
}//END OF FUNCTION

Why is my .appendRow from Array adding an extra row?

I pretty much have the Apps Script file working as intended. However, each time it is triggered, it also adds a second line where the sessionEmail is not captured and is blank.
function onEdit() {
var sessionEmail = Session.getActiveUser().getEmail();
var spreadsheetTimeZone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var lastUpdatedString = Utilities.formatDate(new Date(), spreadsheetTimeZone, "MM/dd/yyyy' 'HH:mm:ss");
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() == "Workload") { //checks that we're on the correct sheet
var r = s.getActiveCell();
if (r.getColumn() == 14) { //checks the column
var status = r.getValue();
var note = r.offset(0, -1);
var noteValue = note.getValue()
var delivery = r.offset(0, -5);
var deliveryValue = delivery.getValue()
}
// Validating fields are filled in
if (status == "Complete") {
var ui = SpreadsheetApp.getUi();
if (noteValue == '') { // if no note is entered, stop script with message box
var noStatus = ui.alert(
'Warning!',
'Please enter notation before choosing Complete.',
ui.ButtonSet.OK);
r.setValue('')
return;
}
// get destination range
var array = [lastUpdatedString, sessionEmail, deliveryValue, noteValue]
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pasteSheet = ss.getSheetByName("Historical Notes Sheet");
pasteSheet.appendRow(array)
// clear response row
note.setValue('')
r.setValue('')
}
}
}
Image of what the results look like:
If any of you have any ideas on how to resolve this, and only append 1 line that has all the values, I would really appreciate it.
Thanks!
Update:
Logging the variable produces the following (expected) results, where the e-mail address appeared in the string.
Results still populating 2 rows:
Thanks for helping me troubleshoot.
I went into View>Executions, and noticed that the script was running twice each time at about 2 milliseconds apart. I think the function name onEdit() was acting like an On Edit trigger, and causing the script to run with another On Edit trigger that I had set up for it.
I tried removing the trigger, and leaving it with the onEdit()name, but that was causing it to not grab the sessionEmail. Changing the code to the below, and adding the trigger back causes the code to run as expected.
function appendLine() {
var sessionEmail = Session.getActiveUser().getEmail().toString();
var spreadsheetTimeZone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var lastUpdatedString = Utilities.formatDate(new Date(), spreadsheetTimeZone, "MM/dd/yyyy' 'HH:mm:ss");
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() == "Workload") { //checks that we're on the correct sheet
var r = s.getActiveCell();
if (r.getColumn() == 14) { //checks the column
var status = r.getValue();
var note = r.offset(0, -1);
var noteValue = note.getValue()
var delivery = r.offset(0, -5);
var deliveryValue = delivery.getValue().toString();
}
// Validating fields are filled in
if (status == "Complete") {
var ui = SpreadsheetApp.getUi();
if (noteValue == '') { // if no note is entered, stop script with message box
var noStatus = ui.alert(
'Warning!',
'Please enter notation before choosing Complete.',
ui.ButtonSet.OK);
r.setValue('')
return;
}
// get destination range
var array = [lastUpdatedString, sessionEmail, deliveryValue, noteValue]
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pasteSheet = ss.getSheetByName("Historical Notes Sheet");
pasteSheet.appendRow(array)
// clear response row
note.setValue('')
r.setValue('')
}
}
}
Thanks again to everyone for your help!