```html

Automating Service Coordination: Replacing FancyHands with Lambda-Driven Calendar Sync and Dispatch Scripts

What Was Done

After the FancyHands service was cancelled, we needed a rapid replacement for task coordination and booking management. This session implemented a three-tier automation system: (1) a Google Calendar API wrapper deployed as AWS Lambda, (2) Python dispatch scripts for operational tasks, and (3) a Google Apps Script calendar synchronization layer that bridges legacy systems with modern infrastructure.

Technical Architecture

The solution consists of three interconnected components:

  • Lambda Calendar API: Centralized endpoint for all calendar operations, handling authentication via token-based headers and supporting multiple action types including add-calendar-event, list-events, and date-range queries.
  • CalendarSync.gs: Google Apps Script deployed in the project at /Users/cb/Documents/repos/sites/queenofsandiego.com/rady-shell-events/apps-script-replacement/CalendarSync.gs, responsible for polling the Lambda API and syncing events to Google Calendar at configurable intervals.
  • Python Dispatch Scripts: Standalone tools including dispatch_boat_cleaner.py and platform_inbox_scraper.py for domain-specific task automation.

Infrastructure Setup

Lambda Function Configuration

The Lambda function (identified via Find Lambda function name for calendar API) exposes an HTTP endpoint through API Gateway v2. The function accepts POST requests with the following structure:

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

{
  "action": "add-calendar-event",
  "event": {
    "summary": "Event Title",
    "description": "Event details",
    "start": "2025-04-28T14:00:00Z",
    "end": "2025-04-28T15:00:00Z",
    "calendarId": "primary"
  }
}

The authentication token is stored in repos.env and retrieved during deployment. The Lambda function handles Google Calendar API credentials internally, eliminating the need to expose GCal service account keys to client code.

Google Apps Script Deployment

CalendarSync.gs is deployed via the Clasp toolchain. The script file location maps to a specific GAS project ID (confirmed via .clasp.json mappings in the repo). The script implements:

  • Configurable polling intervals (updated during this session to optimize request frequency)
  • Error handling with retry logic for transient API failures
  • Email notifications via GmailApp.sendEmail() for critical sync failures
  • Batch event processing to stay within Google Apps Script execution time limits

Key function signature:

function syncCalendarEvents() {
  const response = UrlFetchApp.fetch(LAMBDA_API_ENDPOINT, {
    method: "post",
    headers: {"Authorization": "Bearer " + DASHBOARD_TOKEN},
    payload: JSON.stringify({action: "list-events", dateRange: {...}}),
    muteHttpExceptions: true
  });
  // Process response and sync to calendar
}

Deployment and Version Control

CalendarSync.gs changes were committed to the replacement project and pushed via Clasp (clasp push). The script is bound to a Google Calendar that serves as the source of truth for all scheduled bookings.

Dispatch Automation: Boat Cleaning Service

To replace manual coordination, we created dispatch_boat_cleaner.py in /Users/cb/Documents/repos/tools/. This script:

  • Reads boat booking data from a configured source (GetMyBoat or Boatsetter credentials stored in environment)
  • Determines cleaning requirements based on booking intervals
  • Generates dispatch tasks and adds them to the calendar via the Lambda API
  • Logs all actions for audit purposes

Deployment wrapper deploy_inbox_scraper.sh handles environment variable injection and scheduled execution (likely via cron or EventBridge).

Email and Notification Coordination

Multiple systems were unified for outbound communication:

  • SES Integration: CalendarSync.gs and Python scripts send notifications via AWS SES, using templated messages stored in the dashboard backend.
  • Gmail API: Inbound mail parsing via Gmail API for carole.dangerouscentaur.com and other managed addresses, enabling reactive task creation.
  • Dashboard Backend: Centralized task tracking (cards on dashboard index, stored in /tmp/dashboard_index.html and the canonical repo location).

Key Architectural Decisions

Why Lambda Instead of Direct GCal Access?

Centralizing Google Calendar credentials in Lambda eliminates the need to distribute service account keys to multiple client applications. Client code (GAS, Python scripts, dashboard) authenticate with a single bearer token, reducing credential sprawl and simplifying key rotation.

Why Google Apps Script for Polling?

GAS provides built-in OAuth flows and tight integration with Google Calendar, avoiding additional service account setup. The polling model allows asynchronous updates without requiring webhook endpoints.

Why Separate Python Dispatch Scripts?

Domain-specific logic (boat cleaning dispatch, inbox scraping) is better isolated in focused Python modules. These can be tested independently, scheduled separately, and updated without touching the calendar sync layer.

Testing and Validation

During this session, the following integration tests were performed:

  • Lambda API test: Direct invocation confirmed the function retrieves current calendar events correctly.
  • Event creation: Added 7 Sea Scout Wednesday hold events (recurring) via the add-calendar-event action. Each request was validated before and after to ensure calendar state was consistent.
  • CalendarSync.gs dry-run: Verified script syntax and confirmed it can authenticate to both Lambda and Google Calendar without errors.

No changes were made to production Route53 DNS or CloudFront distributions during this session.

What's Next

  • Scaling dispatch: Extend dispatch_boat_cleaner.py to handle multiple boat platforms (GetMyBoat, Boatsetter, Airbnb) with a unified interface.
  • Webhook integration: Replace polling with webhooks from booking platforms to reduce latency and API calls.
  • Dashboard cards for dispatch: Surface pending dispatch tasks and sync status on the main dashboard, linking to CalendarSync.gs logs for troubleshooting.
  • SES template expansion: Create templated email responses for common booking and scheduling scenarios, driven by Lambda action handlers.

The current system provides reliable automation without external service dependencies (other than AWS and Google), and is structured for straightforward addition of new dispatch actions as operational needs evolve.

```