Building Real-Time Task Notification for Maintenance Operations: Lambda + Google Apps Script + CloudFront Architecture
What Was Done
We implemented a comprehensive task notification system for maintenance.queenofsandiego.com that surfaces newly-added maintenance tasks to operations staff with intelligent notification pacing based on task criticality. The system spans three layers: a serverless Lambda function for persistence, Google Apps Script handlers for email dispatch, and frontend modifications to the staging maintenance tool UI.
The Problem Statement
The maintenance tool at /Users/cb/Documents/repos/sites/queenofsandiego.com/tools/maintenance/staging-index.html had no visibility mechanism when new tasks were added by crew members like Travis. Without this, operations staff (Sergio, etc.) couldn't respond to emerging maintenance needs in a timely manner. We needed:
- Real-time surface of new tasks in the UI
- Intelligent notification delivery to operations email
- Separation between staging (test) and production notification flows
- Task criticality as a signal for notification frequency
- A Google Calendar integration ("Jada Maintenance") for persistence visibility
Architecture Overview
The solution follows a serverless-first pattern with three primary components:
- Frontend (staging HTML): Client-side task submission + local UI updates
- Backend Persistence (Lambda): Receives task submissions, stores state, triggers notifications
- Notification Handler (Google Apps Script): Evaluates criticality, determines notification cadence, sends email digests
Technical Implementation
1. Lambda Persistence Layer
Created a new Lambda function to handle maintenance task submissions. This function:
- Receives POST requests from the staging maintenance tool frontend
- Validates task payload (task name, description, criticality level)
- Stores tasks in DynamoDB with timestamp and submitter metadata
- Invokes the GAS notification handler asynchronously
The Lambda follows the existing deployment pattern established in the codebase (referenced from tips-box Lambda configuration). The IAM role includes permissions for DynamoDB PutItem and SNS Publish to trigger the GAS handler.
2. Google Apps Script Notification Handler
Created /Users/cb/Documents/repos/sites/queenofsandiego.com/MaintenancePersistence.gs with the following responsibilities:
// Receives task events from Lambda
function handleMaintenanceTaskNotification(taskEvent) {
const criticality = taskEvent.criticality; // 'low', 'medium', 'high', 'critical'
const shouldNotifyImmediately = criticality === 'critical' || criticality === 'high';
if (shouldNotifyImmediately) {
sendImmediateNotification(taskEvent);
} else {
queueForDailyDigest(taskEvent);
}
}
This function integrates with BookingAutomation.gs via the existing doPost routing mechanism. We added a new action handler:
// In BookingAutomation.gs doPost handler
if (action === 'log_maintenance_task') {
MaintenancePersistence.handleMaintenanceTaskNotification(parsedPayload);
return ContentService.createTextOutput(JSON.stringify({status: 'queued'}));
}
For testing/staging, notifications are sent to jadasailing@gmail.com. The system evaluates:
- Critical/High Priority: Immediate email notification
- Medium Priority: Batched in end-of-day digest (sent at 18:00 UTC)
- Low Priority: Included in next-day consolidated report
This follows industry best practices used by high-performing ops teams (Datadog, PagerDuty, etc.) where notification fatigue is minimized through intelligent batching while critical issues maintain alert velocity.
3. Google Calendar Integration
Created /Users/cb/Documents/repos/sites/queenofsandiego.com/MaintenanceCalendar.gs to:
- Create a "Jada Maintenance" calendar in the
jadasailing@gmail.comaccount (if not present) - Add maintenance tasks as calendar events with color coding by criticality
- Enable at-a-glance visibility and calendar-based workflow integration
Tasks are created as all-day events with description payloads containing task metadata. This provides a secondary persistence layer and integrates with existing calendar-based operations workflows.
4. Staging Frontend Changes
Modified /Users/cb/Documents/repos/sites/queenofsandiego.com/tools/maintenance/staging-index.html to:
- Add a "New Task" form with fields: Task Name, Description, Criticality (radio buttons: Low/Medium/High/Critical)
- Implement client-side validation and optimistic UI updates
- Submit tasks to the Lambda backend via fetch API
- Display submission status feedback to users
Key JavaScript addition to staging HTML:
async function submitMaintenanceTask(formData) {
const payload = {
action: 'log_maintenance_task',
taskName: formData.get('taskName'),
description: formData.get('description'),
criticality: formData.get('criticality'),
submittedBy: formData.get('submittedBy'),
timestamp: new Date().toISOString()
};
try {
const response = await fetch('/api/maintenance/task', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (response.ok) {
updateLocalTaskList(payload);
showSuccessMessage('Task submitted successfully');
}
} catch (error) {
console.error('Task submission failed:', error);
showErrorMessage('Failed to submit task');
}
}
Infrastructure Changes
S3 Bucket Structure
Staging HTML deployed to: s3://jada-maintenance-staging/tools/maintenance/staging-index.html
Lambda function stores tasks with DynamoDB table: jada-maintenance-tasks-staging (for staging environment)
CloudFront Distribution
Invalidated the CloudFront distribution cache for maintenance.queenofsandiego.com after HTML deployment to ensure staging changes propagate immediately:
aws cloudfront create-invalidation \
--distribution-id [DIST_ID] \
--paths "/tools/maintenance/staging-index.html"
GAS Deployment
Used clasp to deploy new GAS files to the existing Apps Script project:
cd /Users/cb/Documents/repos/sites/queenofsandiego.com
clasp push
This added MaintenancePersistence.gs and