```html

Automating Boat Cleaning Dispatch and Calendar Integration for Event Venue Operations

This session focused on solving a critical operational gap: replacing a failed third-party service (FancyHands) with an internally-managed boat cleaning dispatch system, while integrating calendar-driven scheduling into our event management infrastructure. The challenge required bridging multiple systems—Google Calendar, AWS Lambda, email automation, and custom dispatch logic—to create a resilient workflow for venue cleanup between events.

The Problem: Third-Party Service Failure

FancyHands, our external service for coordinating boat cleaning and event logistics, was cancelled after proving unreliable for our Queen of San Diego event venue operations. With events scheduled densely (including Apr 28 bookings), we needed an immediate replacement that could:

  • Track boat cleaning needs between charter events
  • Dispatch cleaner crews based on calendar availability
  • Integrate with existing Google Calendar event data
  • Maintain audit trails of dispatch actions
  • Scale without external vendor dependencies

Architecture: Calendar-Driven Dispatch System

The solution uses Google Calendar as the source of truth for event scheduling, with Lambda functions acting as the dispatch orchestration layer.

Core Components

  • Google Apps Script (CalendarSync.gs): Located at /Users/cb/Documents/repos/sites/queenofsandiego.com/rady-shell-events/apps-script-replacement/CalendarSync.gs, this script polls Google Calendar for events and triggers dispatch workflows. The polling interval and email notification endpoints are configurable.
  • Python Dispatch Script: /Users/cb/Documents/repos/tools/dispatch_boat_cleaner.py handles the business logic—determining which boats need cleaning, calculating turnaround time windows, and generating crew assignments.
  • Lambda Calendar API: A serverless function exposes calendar operations via API Gateway v2, accepting actions like add-calendar-event, list-events, and get-event. This centralizes calendar access and provides authentication via dashboard tokens.
  • Email Integration: AWS SES sends dispatch notifications and confirmation emails. Templates are stored in /Users/cb/Documents/repos/tools/templates/ and /Users/cb/Documents/repos/sites/quickdumpnow.com/marketing/templates/.

Data Flow

Google Calendar Events
    ↓
CalendarSync.gs (polling trigger)
    ↓
Lambda Function (calendar-api)
    ↓
dispatch_boat_cleaner.py (business logic)
    ↓
Crew Assignment + Email Notifications (SES)
    ↓
Dashboard Status Card (audit log)

Implementation Details

Google Calendar Event Structure

Events are created with specific naming conventions to signal dispatch requirements. For example, "Sea Scout Wednesday Hold" entries create calendar blocks that the dispatch system recognizes as requiring crew availability. Seven such events were added via the Lambda API in this session:

POST /calendar-api
Content-Type: application/json
Authorization: Bearer {dashboard-token}

{
  "action": "add-calendar-event",
  "event": {
    "summary": "Sea Scout Wednesday Hold",
    "start": "2024-04-24T18:00:00Z",
    "end": "2024-04-24T22:00:00Z",
    "calendarId": "primary"
  }
}

The Lambda function verifies the token against repos.env configuration and uses cached Google Calendar API credentials to perform the operation atomically.

Dispatch Script Logic

The dispatch_boat_cleaner.py script implements the core dispatch algorithm:

  • Queries the calendar for events in the next 7 days
  • Identifies gaps between events where cleaning can occur (minimum 2-hour windows)
  • Assigns cleaning crews based on boat type and availability
  • Generates dispatch emails with crew assignments, boat locations, and priority flags
  • Logs all assignments to a JSON file for audit purposes

The script runs via cron (triggered by deployment script /Users/cb/Documents/repos/tools/deploy_boat_cleaner.sh) at 6 AM daily to prepare the day's dispatch schedule.

Campaign Scheduler Integration

A parallel system was built for marketing campaign coordination. The campaign_scheduler.py script reads from campaign_schedule.json and coordinates email blasts across multiple properties (Queen of San Diego, Quick Dump Now).

Configuration example from campaign_schedule.json:

{
  "campaigns": [
    {
      "id": "rady-shell-blast-1",
      "template": "/Users/cb/Documents/repos/tools/templates/rady_shell_blast1.html",
      "recipients": "mailing_list_1",
      "schedule": "2024-04-28T10:00:00Z",
      "region": "us-west-2"
    }
  ]
}

This centralized approach prevents duplicate sends and provides visibility into campaign timing across all event venues.

Infrastructure and Deployment

Lambda Configuration

The calendar API Lambda function:

  • Environment variables: GOOGLE_CALENDAR_API_KEY (from repos.env), DASHBOARD_TOKEN_HASH
  • Runtime: Python 3.11
  • Timeout: 30 seconds (for large calendar queries)
  • Memory: 512 MB (Google Sheets API operations can be memory-intensive)
  • VPC: None (calendar API is external, no internal resource access needed)

API Gateway Setup

Routes are configured in API Gateway v2 with CORS enabled for dashboard origin:

POST /calendar-api → Lambda function (calendar-api)
GET /calendar-api → Lambda function (calendar-api)
POST /dispatch → Lambda function (boat-dispatcher)

Token validation happens in Lambda before any calendar operation executes, preventing unauthorized access.

Deployment Pipeline

Shell scripts automate deployment across environments:

# Deploy boat cleaner dispatch
bash /Users/cb/Documents/repos/tools/deploy_boat_cleaner.sh

# Deploy campaign scheduler
bash /Users/cb/Documents/repos/tools/deploy_campaign_scheduler.sh

# Deploy inbox scraper (for email-driven dispatch)
bash /Users/cb/Documents/repos/tools/deploy_inbox_scraper.sh

Each deployment script:

  • Validates Python syntax
  • Checks for required environment variables
  • Uploads scripts to the appropriate Lambda layer or EC2 instance
  • Updates CloudWatch Log Groups for monitoring
  • Creates or updates cron job entries

Key Decisions and Rationale

Why Google Calendar as Source of Truth?

Calendar data is already being managed by venue staff and synced via iCal feeds from booking platforms (GetMyBoat, Boatsetter). Using it as the source of truth eliminates redundant data entry and keeps dispatch logic in sync with