Skip to content

Instantly share code, notes, and snippets.

@jnduli
Last active December 16, 2017 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jnduli/ad6ef7e12715c63a6d933368e0c61be0 to your computer and use it in GitHub Desktop.
Save jnduli/ad6ef7e12715c63a6d933368e0c61be0 to your computer and use it in GitHub Desktop.
Google Sheets Script to send and email alert and color a row when a task is late. It assumes the sheet has the following columnsLabels: Features, Status,DateDue.
function onEdit(e) {
var activeSheet = e.source.getActiveSheet();
if (activeSheet.getName() !== 'lookup') {
var range = activeSheet.getDataRange();
editTasksSheet(range, e);
}
}
function editTasksSheet(range, e){
var data = range.getValues();
var columnEditted = e.range.getColumn()-1;
var rowEditted = e.range.getRow()-1;
var valueInput = data[rowEditted][columnEditted];
var dateDueCol = getColumnByName('DateDue', data);
var statusCol = getColumnByName('Status', data);
if (dateDueCol < 0 || statusCol < 0){
return;
} else if (columnEditted === dateDueCol) {
var rowRange = range.offset(rowEditted, 0, 1);
// var dateInput = data[rowEditted][columnEditted];
formatBasedOnDate(rowRange, valueInput);
} else if (columnEditted === statusCol) {
if (valueInput === 'done') {
var rowRange = range.offset(rowEditted, 0, 1);
rowRange.setBackground('#c8e6c9');
} else {
formatBasedOnDate(rowRange, data[rowEditted][dateDueCol]);
}
}
}
function formatBasedOnDate(rowRange, dateInput){
Logger.log("in format Based On Date functon");
if (!isValidDate(dateInput) && dateInput !== '') {
var ui = SpreadsheetApp.getUi()
ui.alert('The date input is not valid');
}
var currentDate = new Date();
var newDate = new Date(dateInput);
if (currentDate <= newDate || dateInput === '') {
rowRange.setBackground('#FFFFFF');
} else {
rowRange.setBackground('#ffcdd2');
}
}
function getColumnByName(colName, data) {
var col = data[0].indexOf(colName);
return col;
}
// From http://stackoverflow.com/questions/1353684
function isValidDate(dateInput) {
if (Object.prototype.toString.call(dateInput) !== "[object Date]")
return false;
return !isNaN(dateInput.getTime());
}
// This script checks the date of due tasks
// It then compares them to the current date
// If the script is late, it sends an email to the people in the emails list
// Warning them of the status
// Thus the people can either change the due dates or mark the tasks complete
function setupGlobalVariables() {
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperties({
'LOOKUP_SHEET' : 'lookup',
'DATEDUE_COLUMN' : 'DateDue',
'FEATURES_COLUMN' : 'Features',
'STATUS_COLUMN' : 'Status',
'EMAILS_COLUMN' : 'Email'
})
}
function mainFunction() {
setupGlobalVariables();
var scriptProperties = PropertiesService.getScriptProperties();
var ss = SpreadsheetApp.getActive();
var allSheets = ss.getSheets();
var emails;
var notificationMessages = [];
for (var s in allSheets){
var sheet = allSheets[s];
var range = sheet.getDataRange();
var data = range.getValues();
var sheetName = sheet.getName();
Logger.log(sheetName);
if (sheetName === 'lookup'){
emails = getEmailsToNotify(data);
continue;
} else {
notificationMessages[sheetName] = getNotificationsFromSheet(range);
}
}
sendEmail(emails, formMessage(notificationMessages), ss.getName() + "Alerts");
}
function formMessage(notificationMessages){
var message = "";
for (var key in notificationMessages){
if(notificationMessages.hasOwnProperty(key) && notificationMessages[key].length > 0){
message += makeTitle("** Late tasks from sheet: " + key);
for (var i=0; i<notificationMessages[key].length; i++){
message += "- " + notificationMessages[key][i] + "\r\n";
}
message += "\r\n\r\n";
}
}
return message;
}
function makeTitle(title) {
// title += "<br/>";
var underline = "";
for (var i=0; i<title.length; i++){
if (title[i] == ' ') continue;
underline += "=";
}
var message = title + "\r\n" + underline + "\r\n";
return message;
}
function getNotificationsFromSheet(range) {
var data = range.getValues();
var dateDueCol = getColumnByName('DateDue', data);
var featuresCol = getColumnByName('Features', data);
var statusCol = getColumnByName('Status', data);
if (dateDueCol < 0 || featuresCol < 0 || statusCol < 0 ){
return ["error : Sheet does not follow expected format"];
} else {
messages = getLateDateDues(dateDueCol, statusCol, featuresCol, range);
return messages;
}
// checkLateDateDues(dateDueCol, statusCol, featuresCol, data);
// return ['this is cool', 'this is another one', 'I love this'];
}
function getEmailsToNotify(data) {
var emailCol = getColumnByName(PropertiesService.getScriptProperties().getProperty('EMAILS_COLUMN'), data);
var emails = [];
if (emailCol < 0)
return emails;
for (var i=1; i<data.length; i++) {
var email = data[i][emailCol];
if (email.trim() !== ''){
emails.push(email);
}
}
return emails;
}
function sendEmail(emails, message, subject){
for (var i=0; i<emails.length; i++){
MailApp.sendEmail(emails[i], subject, message);
}
}
function getLateDateDues(dateDueCol, statusCol, featuresCol, range) {
// loop through the date due column only
var data = range.getValues();
var dateNow = new Date();
var messages = [];
for (var i =0; i<data.length; i++) {
var dateDue = new Date(data[i][dateDueCol]);
var rowRange = range.offset(i, 0, 1);
if (dateNow > dateDue && data[i][statusCol] !== 'done'){
messages.push(data[i][featuresCol] + ' was due on ' + dateDue);
rowRange.setBackground('#ffcdd2');
}
}
return messages;
}
function getColumnByName(colName, data) {
var col = data[0].indexOf(colName);
return col;
}
function createTimeDrivenTriggers() {
ScriptApp.newTrigger('mainFunction')
.timeBased()
.everyDays(1)
.create();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment