Automating Venue Operations: Building a Distributed Task Coordination System for Event Management
This session involved architecting and deploying a multi-service coordination system to handle venue event logistics, calendar synchronization, and external platform integrations. The work demonstrates patterns for managing distributed dependencies across Google Apps Script, AWS Lambda, and third-party booking platforms.
What Was Done
- Replaced manual Google Apps Script calendar workflows with Lambda-based event synchronization
- Integrated external booking platform calendars (GetMyBoat, Boatsetter) via iCal feeds
- Built Python-based task dispatch system for venue cleaning and operational tasks
- Implemented email campaign scheduling with templated HTML notifications
- Created dashboard coordination layer for task tracking and manual approvals
Technical Details
Calendar Synchronization Architecture
The core infrastructure relies on a modified Google Apps Script file at /Users/cb/Documents/repos/sites/queenofsandiego.com/rady-shell-events/apps-script-replacement/CalendarSync.gs. This replaced the original event management workflow that was tightly coupled to manual processes.
Why this mattered: The previous system required manual event entry across multiple calendar systems. The new CalendarSync.gs acts as an orchestration layer that:
- Polls external iCal feeds (GetMyBoat, Boatsetter) at regular intervals
- Transforms booking data into Google Calendar events with proper metadata
- Triggers Lambda functions via API Gateway for programmatic event creation
- Maintains idempotency to prevent duplicate entries on re-runs
The deployment flow uses .clasp.json files to map script directories to Google Apps Script project IDs. We verified the CalendarSync.gs file exists in the correct replacement project before pushing updates:
clasp push --force
The --force flag was necessary because we were restoring functionality from a prior implementation rather than building from scratch.
Lambda-Based Event API
Rather than relying entirely on Apps Script (which has execution time and quota limitations), we routed calendar operations through an existing Lambda function. The function exposes multiple actions through environment-based dispatch:
add-calendar-event: Creates single or batch events in Google Calendarlist-events: Queries calendar for specific date ranges with filteringupdate-event: Modifies existing events with new details
API Gateway routes these through v2 endpoints. Authentication uses a dashboard token stored in repos.env, validated before any calendar mutation occurs. This separation of concerns allows:
- Horizontal scaling of event operations independent of Apps Script limits
- Atomic transaction handling for bulk event creation (e.g., recurring Scout holds)
- Centralized audit logging of calendar changes
- Easy credential rotation without touching multiple GAS files
Task Dispatch System
Created a new Python-based dispatch system for operational tasks like venue cleaning. The primary components:
/Users/cb/Documents/repos/tools/dispatch_boat_cleaner.py: Task creation and state management/Users/cb/Documents/repos/tools/deploy_inbox_scraper.sh: Deployment wrapper for Lambda-based task polling/Users/cb/Documents/repos/tools/platform_inbox_scraper.py: Monitors external booking platforms for new reservations
Design rationale: Venue cleaning must be scheduled independently from event marketing, yet tied to actual bookings. The system:
- Polls external platforms via their public APIs or iCal feeds
- Transforms booking events into cleaning task payloads
- Creates or updates cleaning tasks with proper timing offsets (e.g., clean 1 day before event)
- Sends notifications to operations staff
Email Campaign Scheduling
Implemented a templated email campaign system with the following structure:
/Users/cb/Documents/repos/tools/campaign_scheduler.py: Orchestrates email sends based on event schedules/Users/cb/Documents/repos/tools/campaign_schedule.json: Defines campaign timing, templates, and recipient lists/Users/cb/Documents/repos/tools/templates/: HTML email templates for different campaign types
The scheduler reads JSON configuration and uses AWS SES for actual delivery. Templates are versioned (e.g., rady_shell_blast1.html, rady_shell_blast2.html) to enable A/B testing or progressive rollouts.
Infrastructure Changes
Google Apps Script Project Configuration
Multiple GAS projects are managed through a single repo structure with .clasp.json identity files. Key directories:
queenofsandiego.com/rady-shell-events/apps-script-replacement/: Main calendar sync project- CalendarSync.gs deployed with trigger-based polling vs time-based triggers (for reliability)
Lambda Function Configuration
The calendar API Lambda reads:
- Google Calendar service account credentials from environment variables
- Calendar ID for the Rady Shell events calendar
- Dashboard authentication token for request validation
No changes to Lambda IAM roles were needed—the function already had CloudWatch Logs permissions and Calendar API access through its execution role.
S3 and CloudFront Integration
Static site files for carole.dangerouscentaur.com are stored in S3 with CloudFront distribution caching. Recent updates involved:
- Modifying HTML templates at
carole_index.htmland birthday event sites - Invalidating CloudFront cache for affected paths after deployment
- Verifying changes propagated within ~2 minutes globally
Key Architectural Decisions
Why Lambda Instead of Pure Apps Script
Google Apps Script has strict quotas: 6-minute execution limit, 500MB storage, and rate limits on Calendar API calls. For bulk operations (creating 7 recurring events), Lambda provided:
- Parallel event creation without timeout risk
- Better error handling and retry logic
- Isolated scaling from the Apps Script quota pool
Idempotency in Calendar Sync
Calendar events are identified by external booking platform IDs stored as custom properties in Google Calendar. This prevents duplicate events if:
- The sync script runs multiple times
- Network failures cause partial updates
- Manual event creation happens concurrently
Separation of Concerns: Email, Calendars, Tasks
Rather than monolithic event handlers, we built separate systems:
- CalendarSync.gs: Handles calendar-to-calendar synchronization only