Created
July 26, 2020 21:15
-
-
Save kurtkaiser/75daac07cd548c5dd24ece84831c3fc2 to your computer and use it in GitHub Desktop.
Google Calendar Appointment Booking System Owner Approval
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Calendar Reservation Approval System | |
// Kurt Kaiser, 2018 | |
// All Rights Reserved | |
var ss = SpreadsheetApp.getActiveSpreadsheet(); | |
var sheet = ss.getActiveSheet(); | |
var lastRow = sheet.getLastRow(); | |
var lastColumn = sheet.getLastColumn(); | |
// Calendar to output requests | |
var calendar = CalendarApp.getCalendarById('[email protected]'); | |
// Creates an object from the last form submission | |
function Submission(row){ | |
this.timestamp = sheet.getRange(row, 1).getValue(); | |
this.name = sheet.getRange(row, 2).getValue(); | |
this.reason = sheet.getRange(row, 3).getValue(); | |
this.date = new Date(sheet.getRange(row, 4).getValue()); | |
this.dateString = (this.date.getMonth() + 1) + '/' + | |
this.date.getDate() + '/' + this.date.getYear(); | |
this.time = sheet.getRange(row,5).getValue(); | |
this.timeString = this.time.toLocaleTimeString(); | |
this.email = sheet.getRange(row, 6).getValue(); | |
// Adjust time and make end time | |
this.date.setHours(this.time.getHours()); | |
this.date.setMinutes(this.time.getMinutes()); | |
this.endTime = new Date(this.date); | |
this.endTime.setHours(this.time.getHours() + 1); | |
} | |
// Check for conflicting events | |
function getConflicts(request) { | |
var conflicts = calendar.getEvents(request.date, request.endTime); | |
if (conflicts.length < 1) { | |
request.status = "New"; | |
} else { | |
request.status = "Conflict"; | |
sheet.getRange(lastRow, lastColumn - 1).setValue("Reject"); | |
sheet.getRange(lastRow, lastColumn).setValue("Sent: Conflict"); | |
} | |
} | |
// Convert data of status and notified columns into array | |
function StatusObject(){ | |
this.statusArray = sheet.getRange(1, lastColumn -1, lastRow, 1).getValues(); | |
this.notifiedArray = sheet.getRange(1, lastColumn, lastRow, 1).getValues(); | |
this.statusArray = [].concat.apply([], this.statusArray); | |
this.notifiedArray = [].concat.apply([], this.notifiedArray); | |
} | |
// Get the index of the row that has had a status change | |
function getChangeIndex(statusChange){ | |
statusChange.index = statusChange.notifiedArray.indexOf(""); | |
statusChange.row = statusChange.index + 1; | |
if (statusChange.index == -1){ | |
return; | |
} else if (statusChange.statusArray[statusChange.index] != "") { | |
statusChange.status = statusChange.statusArray[statusChange.index]; | |
sheet.getRange(statusChange.row, lastColumn).setValue("Sent: " + statusChange.status); | |
statusChange.notifiedArray[statusChange.index] = "update"; | |
} else { | |
statusChange.status = statusChange.statusArray[statusChange.index]; | |
statusChange.notifiedArray[statusChange.index] = "no update"; | |
} | |
} | |
// Draft contents for emails depending on needed message | |
function draftEmail(request){ | |
request.buttonLink = "https://goo.gl/forms/c9pVUbeUYaA3tQ0A2" | |
request.buttonText = "New Request"; | |
switch (request.status) { | |
case "New": | |
request.subject = "Request for " + request.dateString + " Appointment Received"; | |
request.header = "Request Received"; | |
request.message = "Once the request has been reviewed you will receive an email updating you on it."; | |
break; | |
case "New2": | |
request.email = "[email protected]"; | |
request.subject = "New Request for " + request.dateString; | |
request.header = "Request Received"; | |
request.message = "A new request needs to be reviewed."; | |
request.buttonLink = "https://docs.google.com/spreadsheets/d/1zfIdZBx8gTGc4rsPqbs7wHbW3626taaQEm1QDB-Hv68/edit?usp=sharing"; | |
request.buttonText = "View Request"; | |
break; | |
case "Approve": | |
request.subject = "Confirmation: Appointment for " + request.dateString + " has been scheduled"; | |
request.header = "Confirmation"; | |
request.message = "Your appointment has been scheduled."; | |
break; | |
case "Conflict": | |
request.subject = "Conflict with " + request.dateString + " Appointment Request"; | |
request.header = "Conflict"; | |
request.message = "There was a scheduling conflict. Please reschedule."; | |
request.buttonText = "Reschedule"; | |
break; | |
case "Reject": | |
request.subject = "Update on Appointment Requested for " + request.dateString; | |
request.header = "Reschedule"; | |
request.message = "Unfortunately the request times does not work. Could "+ | |
"we reschedule?"; | |
request.buttonText = "Reschedule"; | |
break; | |
} | |
} | |
// Creates a calendar event using the submitted data | |
function updateCalendar(request){ | |
var event = calendar.createEvent( | |
request.name, | |
request.date, | |
request.endTime | |
) | |
} | |
// Send Email | |
function sendEmail(request){ | |
MailApp.sendEmail({ | |
to: request.email, | |
subject: request.subject, | |
htmlBody: makeEmail(request) | |
}) | |
} | |
// -------------------- Main Functions --------------------- | |
function onFormSubmission(){ | |
var request = new Submission(lastRow); | |
getConflicts(request); | |
draftEmail(request); | |
Logger.log(request.status); | |
sendEmail(request); | |
if (request.status == "New"){ | |
request.status = "New2"; | |
draftEmail(request); | |
sendEmail(request); | |
} | |
} | |
// Triggered function to check if any status has changed | |
function onEdit(){ | |
var statusChange = new StatusObject(); | |
while (true){ | |
getChangeIndex(statusChange); | |
if (statusChange.index == -1){ | |
return; | |
} else { | |
var request = new Submission(statusChange.row); | |
if (statusChange.status){ | |
request.status = statusChange.status; | |
if (statusChange.status == "Approve"){ | |
updateCalendar(request); | |
} | |
draftEmail(request); | |
sendEmail(request); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Calendar Reservation Project | |
// Kurt Kaiser, 2018 | |
// All rights reserved | |
function makeEmail(request) { | |
return ( | |
'<!DOCTYPE html><html><head><base target="_top"></head><body><div style="text-align: center;' + | |
'font-family: Arial;"><div id="center" style="width:300px;border: 2px dotted grey;background:' + | |
'#ececec; margin:25px;margin-left:auto; margin-right:auto;padding:15px;"><img src="https://upload.' + | |
"wikimedia.org/wikipedia/commons/thumb/6/69/Calendar_font_awesome.svg/512px-Calendar_font_awesome" + | |
'.svg.png"width="180" style="margin:10px 0px"><br /><div style=" border: 2px dotted grey;' + | |
'background:white;margin-right:auto; margin-left:auto; padding:10px;"><h2>' + | |
request.header + | |
"</h2><h3>" + | |
request.message + | |
"<br /><br/>" + | |
request.name + | |
"<br />" + | |
request.dateString + | |
"<br />" + | |
request.timeString.slice(0, request.timeString.length - 4) + | |
"<br />" + | |
request.reason + | |
"<br /></h3><br />" + | |
'<a href="' + | |
request.buttonLink + | |
'" class="btn" style="-webkit-border-radius: 28;' + | |
"-moz-border-radius: 5;border-radius: 5px;font-family: Arial; color: #ffffff;font-size: 15px;" + | |
'background: #ff7878;padding:8px 20px 8px 20px;text-decoration: none;">' + | |
request.buttonText + | |
'</a><br /><br /></div></div><div><p style="font-size:12px">' + | |
'Created by<a href="https://www.linkedin.com/in/kurtkaiser/"> Kurt Kaiser</a> </p></div></body></html>' | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment