Last active
February 4, 2026 05:17
-
-
Save cly/240d71e14fe061651a0c7f6b498ebcd9 to your computer and use it in GitHub Desktop.
Email as meeting room auto accept / deny
This file contains hidden or 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
| { | |
| "timeZone": "America/Los_Angeles", | |
| "dependencies": { | |
| }, | |
| "exceptionLogging": "STACKDRIVER", | |
| "runtimeVersion": "V8", | |
| "oauthScopes": [ | |
| "https://www.googleapis.com/auth/script.external_request", | |
| "https://www.googleapis.com/auth/calendar", | |
| "https://www.googleapis.com/auth/script.send_mail" | |
| ] | |
| } |
This file contains hidden or 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
| // --- CONFIGURATION --- | |
| const ROOM_NAME_OVERRIDE = ""; // Leave empty "" to auto-detect, or type "Conference Room A" | |
| const DISCORD_MESSAGE_ID = ''; | |
| const DISCORD_WEBHOOK_URL = ''; | |
| function autoProcessMeetingInvites() { | |
| const calendar = CalendarApp.getDefaultCalendar(); | |
| const tz = calendar.getTimeZone(); | |
| // 1. Determine Room Name | |
| // Attempts to get the name from your Google Account (First + Last) | |
| let detectedName = ROOM_NAME_OVERRIDE; | |
| if (!detectedName) { | |
| try { | |
| // Note: This requires the script to be run by the account owner | |
| const userEmail = Session.getActiveUser().getEmail(); | |
| const contact = ContactsApp.getContact(userEmail); | |
| detectedName = contact ? contact.getFullName() : calendar.getName(); | |
| } catch (e) { | |
| detectedName = calendar.getName(); // Fallback to the Calendar's name | |
| } | |
| } | |
| var startDate = new Date(); | |
| var endDate = new Date(); | |
| endDate.setDate(startDate.getDate() + 30); | |
| var events = calendar.getEvents(startDate, endDate); | |
| for (var i = 0; i < events.length; i++) { | |
| var event = events[i]; | |
| if (event.getMyStatus() === CalendarApp.GuestStatus.INVITED) { | |
| var organizerEmail = event.getCreators()[0]; | |
| if (isSlotFree(calendar, event)) { | |
| event.setMyStatus(CalendarApp.GuestStatus.YES); | |
| sendNotificationEmail(organizerEmail, "β Accepted", event.getTitle(), "confirmed."); | |
| } else { | |
| event.setMyStatus(CalendarApp.GuestStatus.NO); | |
| sendNotificationEmail(organizerEmail, "β Declined", event.getTitle(), "declined due to a conflict."); | |
| } | |
| } | |
| } | |
| refreshDiscordDashboard(calendar, tz, detectedName); | |
| } | |
| function refreshDiscordDashboard(calendar, tz, roomName) { | |
| const now = new Date(); | |
| const endOfDay = new Date(); | |
| endOfDay.setHours(23, 59, 59); | |
| const events = calendar.getEvents(now, endOfDay); | |
| let embed = { | |
| title: `π ${roomName} Schedule`, // Updated to include Room Name | |
| color: 3066993, | |
| description: "", | |
| footer: { text: "Last Updated: " + Utilities.formatDate(new Date(), tz, "hh:mm a") } | |
| }; | |
| let scheduleList = ""; | |
| events.forEach(event => { | |
| const status = event.getMyStatus(); | |
| if (status === CalendarApp.GuestStatus.YES || status === CalendarApp.GuestStatus.OWNER) { | |
| const start = Utilities.formatDate(event.getStartTime(), tz, "hh:mm a"); | |
| const end = Utilities.formatDate(event.getEndTime(), tz, "hh:mm a"); | |
| scheduleList += `**${start} - ${end}**\n${event.getTitle()}\n\n`; | |
| } | |
| }); | |
| embed.description = scheduleList || "β Room is currently free for the rest of the day."; | |
| const url = `${DISCORD_WEBHOOK_URL}/messages/${DISCORD_MESSAGE_ID}`; | |
| const options = { | |
| method: 'patch', | |
| contentType: 'application/json', | |
| payload: JSON.stringify({ | |
| content: "", // Removed "Live Schedule Update" | |
| embeds: [embed] | |
| }), | |
| muteHttpExceptions: true | |
| }; | |
| const response = UrlFetchApp.fetch(url, options); | |
| console.log("Update Status: " + response.getResponseCode()); | |
| } | |
| // Helper functions remain the same... | |
| function sendNotificationEmail(to, prefix, title, status) { | |
| if (to) { | |
| MailApp.sendEmail({ | |
| to: to, | |
| subject: prefix + ": " + title, | |
| body: "Your room booking for '" + title + "' has been " + status | |
| }); | |
| } | |
| } | |
| function isSlotFree(calendar, pendingEvent) { | |
| var start = pendingEvent.getStartTime(); | |
| var end = pendingEvent.getEndTime(); | |
| var conflicts = calendar.getEvents(start, end); | |
| for (var j = 0; j < conflicts.length; j++) { | |
| var checkEvent = conflicts[j]; | |
| if (checkEvent.getId() === pendingEvent.getId()) continue; | |
| var status = checkEvent.getMyStatus(); | |
| if (status === CalendarApp.GuestStatus.YES || status === CalendarApp.GuestStatus.OWNER) return false; | |
| } | |
| return true; | |
| } | |
| function sendWebhookAnchor() { | |
| const WEBHOOK_URL = DISCORD_WEBHOOK_URL; | |
| const payload = JSON.stringify({ | |
| content: "π **Room Schedule Dashboard Initializing...**", | |
| username: "Room Manager" | |
| }); | |
| const options = { | |
| method: 'post', | |
| contentType: 'application/json', | |
| payload: payload, | |
| muteHttpExceptions: true | |
| }; | |
| const response = UrlFetchApp.fetch(WEBHOOK_URL, options); | |
| Logger.log("Webhook Response: " + response.getContentText()); | |
| Logger.log("NOW: Go to Discord, right-click this new message, and 'Copy Message ID'."); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment