Created
October 22, 2025 03:35
-
-
Save rhysawilliams2010/a86b40053d919d35793dfc0751212d8d to your computer and use it in GitHub Desktop.
Calendar Auto Accept
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
| /** | |
| * Event-Driven Auto-Accept Calendar Invitations | |
| * - Only accepts invites from same domain | |
| * - Checks for conflicts across ALL calendars | |
| * | |
| * Add to https://script.google.com/ | |
| * Run `setupEventTrigger` | |
| */ | |
| function autoAcceptEvents() { | |
| try { | |
| const userEmail = Session.getActiveUser().getEmail(); | |
| const userDomain = userEmail.split('@')[1]; // e.g., "company.com" | |
| const primaryCalendar = CalendarApp.getDefaultCalendar(); | |
| const allCalendars = CalendarApp.getAllCalendars(); // For conflict checking | |
| let totalAccepted = 0; | |
| let skippedDomain = 0; | |
| let skippedConflict = 0; | |
| let totalErrors = 0; | |
| try { | |
| const now = new Date(); | |
| const oneYearFromNow = new Date(now.getTime() + (365 * 24 * 60 * 60 * 1000)); | |
| const events = primaryCalendar.getEvents(now, oneYearFromNow); | |
| Logger.log(`Checking ${events.length} events in your primary calendar...`); | |
| Logger.log(`Your domain: ${userDomain}`); | |
| events.forEach(event => { | |
| try { | |
| const myStatus = event.getMyStatus(); | |
| // Only process pending invitations | |
| if (myStatus !== CalendarApp.GuestStatus.INVITED) { | |
| return; | |
| } | |
| const eventTitle = event.getTitle(); | |
| const eventStart = event.getStartTime(); | |
| const eventEnd = event.getEndTime(); | |
| // Check 1: Get the organizer's email | |
| const creator = event.getCreators()[0]; // Get first creator | |
| if (!creator) { | |
| Logger.log(`⚠ Skipping "${eventTitle}": No organizer found`); | |
| return; | |
| } | |
| const organizerDomain = creator.split('@')[1]; | |
| // Check if organizer is from same domain | |
| if (organizerDomain !== userDomain) { | |
| skippedDomain++; | |
| Logger.log(`⊘ Skipped "${eventTitle}": Different domain (${organizerDomain})`); | |
| return; | |
| } | |
| // Check 2: Look for conflicts across ALL calendars | |
| let hasConflict = false; | |
| for (let i = 0; i < allCalendars.length; i++) { | |
| const cal = allCalendars[i]; | |
| try { | |
| // Get events that overlap with this time slot | |
| const conflictingEvents = cal.getEvents(eventStart, eventEnd); | |
| // Check if any of these events are accepted (YES) or tentative (MAYBE) | |
| for (let j = 0; j < conflictingEvents.length; j++) { | |
| const conflictEvent = conflictingEvents[j]; | |
| // Skip if it's the same event we're checking | |
| if (conflictEvent.getId() === event.getId()) { | |
| continue; | |
| } | |
| const conflictStatus = conflictEvent.getMyStatus(); | |
| // If we've accepted or tentatively accepted another event at this time | |
| if (conflictStatus === CalendarApp.GuestStatus.YES || | |
| conflictStatus === CalendarApp.GuestStatus.MAYBE) { | |
| hasConflict = true; | |
| skippedConflict++; | |
| Logger.log(`⊘ Skipped "${eventTitle}": Conflicts with "${conflictEvent.getTitle()}" on ${cal.getName()}`); | |
| break; | |
| } | |
| } | |
| if (hasConflict) break; | |
| } catch (calError) { | |
| // Skip calendars we can't access | |
| } | |
| } | |
| if (hasConflict) { | |
| return; | |
| } | |
| // All checks passed - accept the invitation! | |
| event.setMyStatus(CalendarApp.GuestStatus.YES); | |
| totalAccepted++; | |
| Logger.log(`✓ Accepted: "${eventTitle}" from ${creator} on ${eventStart}`); | |
| } catch (eventError) { | |
| // Silently skip events we can't modify | |
| if (!eventError.message.includes('Action not allowed')) { | |
| totalErrors++; | |
| Logger.log(`⚠ Error processing event "${event.getTitle()}": ${eventError.message}`); | |
| } | |
| } | |
| }); | |
| } catch (calendarError) { | |
| Logger.log(`⚠ Error processing calendar: ${calendarError.message}`); | |
| } | |
| // Summary | |
| Logger.log('═════════════════════════════════════'); | |
| if (totalAccepted > 0) { | |
| Logger.log(`✓ Total invitations accepted: ${totalAccepted}`); | |
| } else { | |
| Logger.log('ℹ No pending invitations accepted.'); | |
| } | |
| if (skippedDomain > 0) { | |
| Logger.log(`⊘ Skipped ${skippedDomain} invite(s) from different domain(s)`); | |
| } | |
| if (skippedConflict > 0) { | |
| Logger.log(`⊘ Skipped ${skippedConflict} invite(s) due to conflicts`); | |
| } | |
| if (totalErrors > 0) { | |
| Logger.log(`⚠ ${totalErrors} error(s) occurred`); | |
| } | |
| Logger.log('═════════════════════════════════════'); | |
| } catch (error) { | |
| Logger.log(`✗ Fatal error: ${error.message}`); | |
| } | |
| } | |
| function onCalendarUpdate(e) { | |
| Logger.log('Calendar update detected, checking for pending invitations...'); | |
| autoAcceptEvents(); | |
| } | |
| function setupEventTrigger() { | |
| const triggers = ScriptApp.getProjectTriggers(); | |
| triggers.forEach(trigger => { | |
| if (trigger.getHandlerFunction() === 'onCalendarUpdate') { | |
| ScriptApp.deleteTrigger(trigger); | |
| } | |
| }); | |
| try { | |
| ScriptApp.newTrigger('onCalendarUpdate') | |
| .forUserCalendar(Session.getActiveUser().getEmail()) | |
| .onEventUpdated() | |
| .create(); | |
| Logger.log('✓ Event trigger successfully created!'); | |
| autoAcceptEvents(); | |
| } catch (error) { | |
| Logger.log(`✗ Error creating trigger: ${error.message}`); | |
| throw error; | |
| } | |
| } | |
| function setupHybridTriggers() { | |
| setupEventTrigger(); | |
| const triggers = ScriptApp.getProjectTriggers(); | |
| triggers.forEach(trigger => { | |
| if (trigger.getHandlerFunction() === 'autoAcceptEvents' && | |
| trigger.getEventType() === ScriptApp.EventType.CLOCK) { | |
| ScriptApp.deleteTrigger(trigger); | |
| } | |
| }); | |
| ScriptApp.newTrigger('autoAcceptEvents') | |
| .timeBased() | |
| .everyMinutes(5) | |
| .create(); | |
| Logger.log('✓ Hybrid triggers created (event-driven + every 5 minutes)!'); | |
| } | |
| function removeAllTriggers() { | |
| const triggers = ScriptApp.getProjectTriggers(); | |
| triggers.forEach(trigger => { | |
| ScriptApp.deleteTrigger(trigger); | |
| }); | |
| Logger.log('✓ All triggers removed.'); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment