Building a Daily Artist Celebration Feature for Event Pages: Architecture and Implementation
Overview
We implemented a dynamic artist celebration system for the Queen of San Diego Rady Shell Events website that injects fresh artist spotlights into event pages three times daily until concert day. This feature was inspired by Nike's brand philosophy of celebrating athletes rather than commodities—in this case, celebrating world-class musicians to create emotional connection with attendees.
The implementation spans three primary layers: Google Apps Script for dynamic content generation, a Python-based static site renderer for template management, and AWS infrastructure (S3 + CloudFront) for content delivery and cache invalidation.
Architecture Overview
The system works as follows:
- Content Generation: A new Google Apps Script service (
ArtistCelebrationsService.gs) queries artist data and generates spotlight HTML using the Anthropic API - Template Injection: Python tooling (
inject_artist_spotlight.py) injects placeholder sections into static event HTML files - Runtime Rendering: The GAS HTTP endpoint serves dynamic content via
Code.gsrouter, which calls the celebration service - Static Site Updates: Updated HTML files are deployed to event-specific S3 buckets and cached via CloudFront distributions
- Cache Management: CloudFront invalidations ensure fresh content appears immediately across all event subdomains
Technical Implementation
Google Apps Script Services
We created ArtistCelebrationsService.gs to handle artist spotlight generation. This service:
- Queries the backing Google Sheet for artist metadata (name, biography, notable works)
- Calls the Anthropic API with a carefully crafted prompt to generate compelling, concise celebration copy
- Returns formatted HTML ready for injection into event pages
- Includes error handling for API failures and rate limiting
The service is invoked via a new HTTP endpoint registered in the main Code.gs router. The router pattern was extended to support:
GET /artist-celebration?eventId={id} → returns HTML section
This endpoint is called via client-side JavaScript on each event page, ensuring the spotlight is fetched fresh on every page load.
Python Template Injection
The inject_artist_spotlight.py script handles bulk modification of existing event HTML files. Key responsibilities:
- Parses the events manifest from
events.jsonto iterate over all upcoming events - Locates the appropriate insertion point in each event's HTML template (typically after the main event description, before ticket links)
- Injects a standardized
<div id="artist-spotlight">placeholder - Includes inline JavaScript to fetch and render the dynamic spotlight via the GAS endpoint
The injection is idempotent—running the script multiple times won't create duplicate sections. This was critical for the iterative development process.
Static Site Renderer Enhancement
We modified render_event_sites.py to incorporate the artist spotlight injection as part of the standard build pipeline. This ensures:
- All newly generated event pages include the spotlight placeholder automatically
- The renderer serves as the single source of truth for page structure
- Manual edits to individual HTML files are overwritten on the next render, preventing drift
Infrastructure and Deployment
Google Apps Script Deployment
We created a new GAS deployment specifically for the artist celebration endpoint:
gapps deploy --create "Artist Celebration Service"
This generates a unique execution URL of the form: https://script.google.com/macros/s/{DEPLOYMENT_ID}/usercurrent
The deployment ID is stored in project configuration and referenced by the client-side JavaScript on event pages. This separation from the main GAS deployment provides:
- Independent scaling and version management
- Ability to rotate or update the endpoint without affecting other GAS functionality
- Clear separation of concerns for monitoring and debugging
S3 and CloudFront Strategy
Event content is distributed across multiple S3 buckets, one per event subdomain:
s3://qos-event-subdomain-{eventId}/pattern- Each bucket serves as the origin for a corresponding CloudFront distribution
- CloudFront distributions are named
qos-event-{eventId}-cf
We discovered several CloudFront distributions that weren't yet tracked in configuration, requiring a comprehensive audit via:
aws cloudfront list-distributions --query 'DistributionList.Items[?contains(Comment, `qos-event`)]'
This enumeration was essential for ensuring cache invalidations reached all live event pages.
Cache Invalidation Pattern
After uploading updated HTML files to S3, we trigger CloudFront invalidations for each distribution:
aws cloudfront create-invalidation --distribution-id {DIST_ID} --paths "/*"
The wildcard path ensures all cached assets—including newly injected sections—are refreshed within seconds. This was critical for the three-daily update schedule.
Key Architectural Decisions
Why Dynamic Content via GAS Instead of Static Generation
We chose a hybrid approach: static HTML shells with dynamic content injection via JavaScript callbacks to GAS. This decision was driven by:
- Update Frequency: Three daily updates would require re-rendering and re-deploying all event pages to S3 if done statically. The hybrid approach keeps static assets mostly stable.
- Cost: GAS HTTP invocations are cheaper than re-deploying gigabytes of HTML to S3 three times daily.
- Simplicity: The GAS endpoint can be updated independently without coordinating with the static site build pipeline.
Why Anthropic API for Content Generation
Rather than storing pre-written spotlights for each artist, we generate them dynamically using Claude. This enables:
- Variation across the three daily spotlights—different angles on the same artist
- Consistency in tone and length across all artists
- Easy experimentation with different prompts and styles without schema changes
Idempotent Injection Script
The inject_artist_spotlight.py script uses a marker-based approach to detect whether a spotlight section already exists in a file before injecting. This prevents accumulation of duplicate sections and allows the script to be safely re-run across large event catalogs.
Deployment Workflow
- Update
ArtistCelebrationsService.gsand push to GAS project - Create new GAS deployment and note the execution URL
- Update GAS router (
Code.gs) with new endpoint URL - Run
inject_artist_spotlight.pyto update all event HTML files locally