Building Real-Time Maintenance Task Notifications: Lambda, GAS, and CloudFront Integration
The maintenance.queenofsandiego.com tool needed a critical capability: surfacing newly-added tasks in real-time and notifying team members like Sergio without manual dashboard refreshes. This post details the architecture, implementation, and infrastructure decisions made to solve this problem.
The Problem
Previously, when maintenance tasks were added to the system, there was no mechanism to alert stakeholders. Team members had to manually check the maintenance dashboard to discover new work. For a fast-moving operation, this created visibility gaps and delayed response times.
Architecture Overview
The solution spans four components:
- Frontend HTML UI —
/tools/maintenance/staging-index.htmlwith task submission interface - Google Apps Script handlers — Route incoming maintenance requests and trigger notifications
- Lambda persistence layer — Store task metadata and manage notification logic
- Email notification system — Send alerts based on task criticality
This architecture separates concerns: the frontend captures user input, GAS acts as the orchestration layer, Lambda handles stateful persistence and business logic, and email provides the notification channel.
Technical Implementation
Frontend Changes: staging-index.html
The staging maintenance tool at /Users/cb/Documents/repos/sites/queenofsandiego.com/tools/maintenance/staging-index.html was modified to include task criticality classification. When a user submits a new task, the form now captures:
- Task description
- Assigned crew member
- Criticality level (Low, Medium, High, Critical)
- Timestamp of submission
The form submission posts to the BookingAutomation Apps Script endpoint, which routes the request to the maintenance handler.
Google Apps Script Layer: BookingAutomation.gs
Modified BookingAutomation.gs to add a new maintenance action route in the doPost handler:
if (action === 'log_maintenance') {
return handleMaintenanceLog(request);
}
This handler extracts the task data from the request and invokes the Lambda function, passing along the criticality level, task description, and timestamp.
New GAS File: MaintenancePersistence.gs
Created /Users/cb/Documents/repos/sites/queenofsandiego.com/MaintenancePersistence.gs to manage the notification workflow:
function handleMaintenanceLog(request) {
const data = JSON.parse(request.postData.contents);
const lambdaPayload = {
action: 'log_task',
task: data.task,
criticality: data.criticality,
assignee: data.assignee,
timestamp: new Date().toISOString()
};
const response = invokeMaintenanceLambda(lambdaPayload);
return response;
}
This file also contains the Lambda invocation logic and email formatting utilities.
New GAS File: MaintenanceCalendar.gs
Created /Users/cb/Documents/repos/sites/queenofsandiego.com/MaintenanceCalendar.gs to manage calendar integration with the existing "Jada Maintenance" calendar in jadasailing@gmail.com.
This ensures that Critical and High-priority tasks automatically populate the calendar, providing a secondary visibility mechanism for the team.
Infrastructure: Lambda Function
A Lambda function processes maintenance task metadata and decides notification timing and recipients. The function:
- Receives task data from GAS via HTTPS invocation
- Stores task metadata in DynamoDB with a TTL for automatic cleanup
- Evaluates criticality level against notification thresholds
- Triggers email notifications immediately for Critical tasks, or batches them for daily digest for Medium/Low
- Invokes SES to send emails to the appropriate distribution list
The Lambda is configured with an IAM execution role that permits:
- DynamoDB put/get operations on the maintenance tasks table
- SES send email permissions
- CloudWatch Logs write access for debugging
Email Notification Strategy
Drawing from industry practices used by high-performing ops teams (e.g., incident response frameworks), the notification cadence is based on task criticality:
- Critical — Immediate email notification to Sergio and the assigned crew member
- High — Immediate notification, tagged with escalation indicator
- Medium — Batched into hourly digest
- Low — Batched into end-of-day digest
This mirrors alert fatigue mitigation strategies used by Atlassian, PagerDuty, and similar platforms: critical alerts interrupt immediately, lower-severity items batch to reduce context switching.
Testing is currently configured to send all notifications to jadasailing@gmail.com to avoid polluting production email distribution lists during development.
CloudFront and S3 Deployment
The modified staging-index.html is deployed to S3 at the staging maintenance bucket. After deployment, the CloudFront distribution cache must be invalidated to ensure users receive the updated UI:
aws cloudfront create-invalidation \
--distribution-id [STAGING_DIST_ID] \
--paths "/index.html"
The staging CloudFront distribution points to the S3 bucket where the HTML, CSS, and JavaScript are hosted, ensuring low-latency delivery to crew members updating the maintenance tool.
Staging vs. Production Separation
Currently, both staging and production use the same maintenance.queenofsandiego.com endpoint. The separation strategy is:
- HTML environment flag — Staging HTML includes a dev banner and posts to a staging GAS endpoint
- GAS script routing — Development requests route to test Lambda and test email recipients
- Lambda environment variables — Different DynamoDB tables and email distribution lists for staging vs. production
A future migration will use DNS-based separation (e.g., staging-maintenance.queenofsandiego.com), but the current approach allows rapid iteration without separate infrastructure.
Key Decision Points
Why Lambda instead of pure GAS? Google Apps Script has limited built-in support for scheduled email digests and state management. Lambda provides a cleaner separation of concerns, easier testing, and better integration with AWS SES for email delivery at scale.
Why criticality-based notification batching? Research from incident command systems and on-call platforms shows that aggressive real-time notifications for low-priority items drive alert fatigue and desensitization. Batching non-critical tasks reduces cognitive load while maintaining rapid response for genuinely urgent work.
Why calendar integration? The team already relies on Google Calendar for scheduling. Adding maintenance tasks to a dedicated "Jada Maintenance" calendar creates a secondary visibility mechanism that integrates with existing workflows rather than requiring yet another tool.