You can add a custom function to a dropdown menu in the Spreadsheets UI with the following script. This will allow you to circumvent the onEdit() restriction that doesn't allow one to use the MailApp class, but it is at the cost of having users manually call the script instead of the script running automatically.
Here the user will select "Send E-Mail" from the dropdown menu, and it will prompt him/her for the Primary Key via an input prompt modal. The row of the corresponding key will be identified and an e-mail sent out after status is automatically changed to "approved". This script assumes that the spreadsheet contains at least four columns with header rows "Primary Key", "Description", "Email", and "Status" in any order.
Please note: this code was tested successfully. Please update lines 20 and 21 by replacing the square brackets and text contained therein that defines sheetURL and workSheetName variables.
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Send E-Mail', 'sendEmail')
.addToUi();
}
function sendEmail(){
// Display a dialog box with a title, message, input field, and "OK" and "Cancel" buttons. The
// user can also close the dialog by clicking the close button in its title bar.
var ui = SpreadsheetApp.getUi();
var response = ui.prompt('Pop-Up Prompt', 'Please enter primary key:', ui.ButtonSet.OK_CANCEL);
// Process the user's response.
if (response.getSelectedButton() == ui.Button.OK) {
Logger.log('The user entered the following primary key:', response.getResponseText());
// Map the header rows in order that column position is not hard-coded.
var sheetURL = '[ENTER YOUR SHEET URL HERE]';
var workSheetName = '[ENTER YOUR WORKSHEET NAME HERE]';
var sheet = SpreadsheetApp.openByUrl(sheetURL).getSheetByName(workSheetName);
var lastColumn = sheet.getLastColumn();
var headerRange = sheet.getRange(1, 1, 1, lastColumn);
var headers = headerRange.getValues();
for (var i=1; i<headers[0].length+1; i++) {
switch (headers[0][i-1]){
case "Primary Key":
var primaryKeyIndex = i;
break;
case "Description":
var descriptionIndex = i;
break;
case "Email":
var emailIndex = i;
break;
case "Status":
var statusIndex = i;
break;
}
}
// Header rows mapped.
// Search for row corresponding to primary key.
var primaryKey = response.getResponseText();
var keyRow = findInColumn(columnToLetter(primaryKeyIndex), primaryKey);
if (keyRow == -1){
ui.alert('Primary Key "'+ primaryKey + '" not found.');
} else {
ui.alert('Primary Key "'+ primaryKey + '" found at row: ' +keyRow+ '.');
sheet.getRange(keyRow, statusIndex).setValue("Approved");
//Prepare Email
var subject = "test";
var email = sheet.getRange(keyRow, emailIndex).getValue();
var body = "Hi, \n\n Your entry with primary key " + primaryKey + " is now approved.";
MailApp.sendEmail(email, subject, body);
}
} else if (response.getSelectedButton() == ui.Button.CANCEL) {
Logger.log('The user clicked cancel.');
} else {
Logger.log('The user clicked the close button in the dialog\'s title bar.');
}
}
// Helper function to find corresponding row to data in column.
function findInColumn(column, data) {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var column = sheet.getRange(column + ":" + column); // like A:A
var values = column.getValues();
var row = 0;
while ( String(values[row]) && String(values[row][0]) !== String(data) ) {
row++;
}
if (String(values[row][0]) === String(data))
return row+1;
else
return -1;
}
// Helper function to convert Column Number to Column Letter
function columnToLetter(column){
var temp, letter = '';
while (column > 0)
{
temp = (column - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
column = (column - temp - 1) / 26;
}
return letter;
}