```html

Automating Boat Cleaning Dispatch and Calendar Synchronization for Event Operations

This session focused on bridging a critical gap in our event operations infrastructure: connecting multiple boat rental platforms (GetMyBoat, Boatsetter) to our internal dispatch system and Google Calendar. The work involved creating an autonomous dispatch script, implementing platform credential management, and resolving calendar synchronization issues across our event booking ecosystem.

The Problem: Fragmented Booking Systems

Our events operation (Queen of San Diego) manages vessel bookings across multiple platforms—GetMyBoat, Boatsetter, and direct reservations through the Rady Shell Events calendar system. Each platform operated in isolation, requiring manual cross-referencing to assign cleaning crews between events. With events scheduled weeks in advance, we needed an automated system to:

  • Scrape booking data from external platforms
  • Parse event requirements and vessel assignments
  • Dispatch cleaning crew notifications automatically
  • Sync all bookings back to Google Calendar for unified visibility

Technical Implementation: The Dispatch Pipeline

Step 1: Credential Management and Platform Integration

We discovered GetMyBoat and Boatsetter credentials already existed in our secure configuration. Rather than building separate integrations for each platform, we created a unified scraper pattern:


File: /Users/cb/Documents/repos/tools/platform_inbox_scraper.py
Purpose: Unified email-based booking data extraction

This script leverages Gmail API to monitor booking confirmation emails from both platforms. Why email-based? Because it's resilient—platforms change APIs, but email confirmations are guaranteed and contain the canonical booking data (vessel, date, time, customer, special requests).

Step 2: The Boat Cleaner Dispatch System


File: /Users/cb/Documents/repos/tools/dispatch_boat_cleaner.py
Deployment: /Users/cb/Documents/repos/tools/deploy_boat_cleaner.sh

This script implements a three-stage dispatch workflow:

  1. Extraction: Parse booking emails for vessel ID, event timestamp, and cleaning requirements
  2. Matching: Cross-reference vessel against our internal database to find assigned crew
  3. Notification: Send SMS/email to assigned cleaners with event details and timing

The script runs on a configurable schedule (via cron or Lambda triggers) and maintains idempotency—re-running against the same booking email won't send duplicate notifications because we track processed message IDs in DynamoDB.

Campaign Scheduling Infrastructure

Beyond immediate dispatch, we needed to schedule pre-event communications to customers:


Files created:
- /Users/cb/Documents/repos/tools/campaign_scheduler.py
- /Users/cb/Documents/repos/tools/campaign_schedule.json
- /Users/cb/Documents/repos/tools/deploy_campaign_scheduler.sh

The campaign scheduler reads a JSON manifest that defines email blasts tied to specific event templates:


{
  "campaigns": [
    {
      "id": "rady_shell_blast1",
      "trigger": "booking_confirmed",
      "delay_hours": 2,
      "template": "templates/rady_shell_blast1.html",
      "recipients": "booking_email"
    }
  ]
}

This decouples campaign timing from the dispatch system—campaigns run independently and look up recent bookings from the same DynamoDB table the dispatcher populates.

Quick Dump Now Integration and Analytics

We also standardized the same pattern across our sister property (quickdumpnow.com):


Files:
- /Users/cb/Documents/repos/sites/quickdumpnow.com/tools/qdn_consumer_blast.py
- /Users/cb/Documents/repos/sites/quickdumpnow.com/tools/qdn_stats.py
- /Users/cb/Documents/repos/sites/quickdumpnow.com/unsubscribe/index.html

The analytics script (qdn_stats.py) aggregates send/open/click data from SES webhooks and provides operational dashboards. The unsubscribe page implements a double-opt-out flow that respects both SES suppression lists and our local database, preventing accidental re-engagement of opted-out customers.

Google Calendar Synchronization: The Missing Link

The biggest infrastructure gap was bi-directional calendar sync. Our dispatch and campaign systems needed read/write access to Google Calendar, but the original implementation used Google Apps Script (GAS) with deprecated APIs.

What existed:


File: /Users/cb/Documents/repos/sites/queenofsandiego.com/rady-shell-events/apps-script-replacement/CalendarSync.gs
Status: Legacy polling-based sync with 1-minute interval

What we fixed:

  • Migrated from Apps Script email triggers to direct Lambda invocation via API Gateway
  • Replaced polling intervals with event-driven architecture (Pub/Sub via SNS)
  • Implemented retry logic and exponential backoff for transient GCal API failures
  • Added structured logging to CloudWatch for debugging sync failures

The Lambda function (/Users/cb/Documents/repos/sites/queenofsandiego.com/tools/shipcaptaincrew/lambda_function.py) now supports multiple calendar actions via routing:


Supported actions:
- add-calendar-event: Insert booking into GCal with vessel, crew, and cleaning notes
- sync-from-platforms: Pull external platform bookings into master calendar
- list-events: Query date range for operational dashboards
- update-event: Modify event details (crew changes, time adjustments)

We tested the API endpoint by invoking it directly to populate 7 consecutive Wednesday holds for Sea Scout bookings—validating both the add-event action and the underlying Google Calendar API authentication.

Deployment and Operational Workflow

Environment Management:


secrets stored in: /Users/cb/Documents/repos/repos.env
loaded by: deployment scripts via `source repos.env`
includes: GCal API credentials, SES configuration, SNS topics

Deployment Pattern:

Each subsystem follows an identical deployment model:

  1. Python script in /tools/ directory
  2. Companion deploy_*.sh script that zips code, uploads to Lambda, updates environment variables
  3. Optional: CloudFormation template for infrastructure (not shown here, but referenced in CI/CD)
  4. Local testing via direct invocation before pushing to staging

Event Flow and Architecture Diagram

Booking → Dispatch → Calendar → Customer Communication:

  1. Customer books via GetMyBoat or Boatsetter
  2. Confirmation email arrives in monitored inbox
  3. platform_inbox_scraper.py extracts booking data, stores in DynamoDB
  4. dispatch_boat_cleaner.py looks up crew assignment, sends SMS/Slack notification
  5. shipcaptaincrew Lambda adds event to Google Calendar with crew