I have a spreadsheet that contains different events on different days.
Each event has an instructor and a facilitator.
The script is programmed to send a reminder to the instructor and the facilitator, the night before each event is scheduled.
The problem is there can be multiple events on each day with the same facilitator but different instructor.
The email is currently sending out one email per day - no matter how many days or facilitators.
I need it to send out one email per line and I am having trouble figuring out the necessary loop. I would appreciate help. Here is my script:
function SGIDReminder() {
//get the spreadsheet object
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
//set the first sheet as active
SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);
//fetch this sheet
var sheet = spreadsheet.getActiveSheet();
//figure out what the last row is
var lastRow = sheet.getLastRow();
//the rows are indexed starting at 1; first row is header row so start with 2
var startRow = 2;
//grab column 13; it contains the reminder days left
var range = sheet.getRange(2,13,lastRow-startRow+1, 1);
var numRows = range.getNumRows();
var reminder_send_values = range.getValues();
//grab column for name of reminder
range = sheet.getRange(2,4,lastRow-startRow+1, 1);
var course_values = range.getValues();
//grab column for location
range = sheet.getRange(2,3,lastRow-startRow+1, 1);
var location_values = range.getValues();
//grab column for time
range = sheet.getRange(2,2,lastRow-startRow+1, 1);
var time_values = range.getValues();
//grab column for email
range = sheet.getRange(2,10,lastRow-startRow+1, 1);
var email_values = range.getValues();
//grab column for instructor email
range = sheet.getRange(2,7,lastRow-startRow+1, 1);
var instructor_email_values = range.getValues();
var warning_count = 0;
var msg = "";
//Loop over the reminder_send values
//changed time to hour to avoid message formatting and date addition javascript wanted to add
for (var i = 0; i <= numRows - 1; i++) {
var reminder_send = reminder_send_values[i][0];
if(reminder_send == 1) {
//if it is 1, do something with the data
var course = course_values[i][0];
var location = location_values[i][0];
var hour = time_values[i][0];
var email = email_values[i][0];
var instructor = instructor_email_values[i][0];
msg = msg + "Reminder: You have an SGID scheduled tomorrow at "+hour+" in "+location+" for "+course+".\n Please remind students to bring a smartphone or web capable device with them to class.";
warning_count++;
}
}
//cc instructor - but could bcc or add other emails, from cte, reply to Gregg
if(warning_count) {
MailApp.sendEmail(email, "SGID Reminder Message", msg,
{bcc: "myemail@miamioh.edu", cc: instructor, name: "CTE", replyTo: "coordinator@miamioh.edu"});
}
};
This is not a turn-key solution, but illustrates what you could do.
In order to send more than one email, you need to collect emails for every case that requires an email. Generally, this is done using an Object
or an Array
, or possibly an Array
of Object
s (eg to bundle more than one piece of information).
Probably, it is worthwhile to send only a single email to each instructor containing a list of all the events they have, and a single email to each facilitator containing a list of all the events they have.
This example uses an Object to hold the instructor
and facilitator
information for email processing outside of the spreadsheet data loop. Each relevant email is used as an object key, with the value that is an array of event information.
const data = sheet.getDataRange().getValues();
const headers = data.shift();
const reminderColText = "Reminder Days Left", // Title of the header col
compareCol = headers.indexOf(reminderColText),
// If the row & column intersection has this value, an email is sent for the row's data
sendIfDays = 1;
if (compareCol === -1)
throw new Error("Did not find the header column titled '" + reminderColText + "'")
// Prune the sheet's data to only that which we care about.
const events = data.filter(function (row) { return row[compareCol] === sendIfDays; });
const infoIndices = { eventName: 0, // Event name in Col A
eventTime: 1,
eventLoc: 3, // Event location in Col D
instructorEmail: 4,
facilitatorEmail: 5 };
const emailInfo = { instructors: {}, facilitators: {} };
events.forEach(function (row) {
var ins = row[infoIndices.instructorEmail],
fac = row[infoIndices.facilitatorEmail],
name = row[infoIndices.eventName],
time = row[infoIndices.eventTime],
loc = row[infoIndices.eventLoc];
// Create an Array for each instructor / facilitator email
if (!emailInfo.instructors[ins])
emailInfo.instructors[ins] = [];
if (!emailInfo.facilitators[fac])
emailInfo.facilitators[fac] = [];
// Add the event data to the relevant array
var eData = { name: name, time: time, loc: loc };
emailInfo.instructors[ins].push(eData);
emailInfo.facilitators[fac].push(eData);
});
// Send emails based on the collected information.
[ {r: emailInfo.instructors, f: getFormattedInstructorMessage_},
{r: emailInfo.facilitators, f: getFormattedFacilitatorMessage_}
].forEach( function (o) {
var formatFunc = o.f;
for (var email in o.r) {
var recipientName = getNameFromEmailSomehow_(email);
var msg = formatFunc(recipientName, o.r[email]);
MailApp.sendEmail(email, "Subject", msg);
}
});
The above assumes you have also written some background functions:
getNameFromEmailSomehow_
that converts an email to a name (eg an LDAP lookup, or maybe you have written the instructor/faciliator name in the row and include that in eData
getFormattedInstructorMessage_
and getFormattedFaciliatorMessage_
that take the recipient name and the list of all their events for that upcoming day, and consumes the list of objects to make the email text. You could return HTML (and use the other version of MailApp.sendEmail
) or just plain text, whichever you prefer. An absolutely primitive example formatter:
function basicFormattedMessage_(to, events) {
var msg = "Hello " + to + ",\n";
msg += "You have " + events.length + " events tomorrow:\n";
events.forEach(function (e) {
msg += "\nName: " + e.name;
msg += "\nTime: " + e.time;
msg += "\nRoom: " + e.loc;
msg += "\n";
});
return msg;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.