```html

Building Real-Time Observability into Email Operations: GA Audit, Orchestrator Integration, and Campaign Management

Over the last development session, we built out a comprehensive audit system to surface analytics gaps, campaign status, and operational bottlenecks across the Sail Jada platform. This post details the technical architecture, infrastructure decisions, and automation patterns we implemented to transform raw audit data into actionable intelligence for marketing operations.

What We Built

The core objective was to answer three critical questions:

  • Are all web properties properly instrumented with Google Analytics tracking code?
  • What does the last 30 days of traffic tell us about user behavior and conversion funnels?
  • What email campaigns are in-flight and what's blocking them from execution?

Rather than building yet another reporting dashboard, we implemented an orchestrator-driven audit pipeline that runs as a discrete agent, processes findings, and surfaces results directly on the existing kanban board at https://progress.queenofsandiego.com.

Technical Architecture

The Multi-Stage Audit Pipeline

The audit runs in three parallel stages:

  • GA Code Sweep: Recursive file scan across all HTML templates and static pages, searching for Google Analytics tracking script patterns (<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID">). This identifies gaps by site and page hierarchy.
  • Traffic Data Pull: Queries Google Analytics Admin API (once access is granted) for last 30 days of session, user, pageview, and conversion metrics. This requires the service account to have explicit VIEWER role on the GA4 property in Google Cloud's IAM console.
  • Campaign Status Check: Hits the Constant Contact API to enumerate all active, scheduled, and draft email campaigns, extracting send dates, recipient counts, and approval status.

Each stage feeds structured JSON into a report generator that produces a single kanban card with five sections: GA Code Audit Results, Traffic Analysis, Campaign Calendar, Recommendations, and Urgent Blockers.

Kanban Card Generation and Deep Linking

The dashboard at progress.queenofsandiego.com was built with hash-based navigation support. Card references use the format:

https://progress.queenofsandiego.com/#card-{CARD_ID}

This allows us to generate deep links directly from our orchestrator output. When the audit completes, it creates a card with ID t-31aa2593 and returns the deep link https://progress.queenofsandiego.com/#card-t-31aa2593. The dashboard's JavaScript router (in /static/js/dashboard-router.js) intercepts the hash, parses the card ID, and renders the specific card in focus.

The dashboard HTML structure uses data attributes to anchor cards:

<div class="card" data-card-id="t-31aa2593">
  <h3>GA Audit + Orchestrator Report</h3>
  <div class="card-section">...</div>
</div>

The router uses querySelector('[data-card-id="' + cardId + '"]') to locate and scroll into view on page load or hash change.

Infrastructure and Integrations

Google Analytics Setup

The audit discovered that GA code was inconsistently deployed across our web properties. We created a checklist for adding tracking to all remaining properties:

  • Measurement ID: All GA4 properties must include the standard gtag.js script with the correct GA_MEASUREMENT_ID
  • Placement: Script should be in the <head> tag for earliest instrumentation, with async attribute to prevent render blocking
  • Event Configuration: Ensure gtag('config', 'GA_MEASUREMENT_ID') is called after script load
  • Service Account Access: To pull traffic data programmatically, the service account (typically orchestrator-sa@{project}.iam.gserviceaccount.com) must be granted the Analytics Viewer role on the GA4 property. This is done in Google Cloud Console → Analytics Admin → Property Settings → Access Management.

Without this last step, the orchestrator cannot query the Google Analytics Data API, which was the root cause of the "no GA Data API access" blocker. The fix is a 3-minute configuration change in the Google Cloud IAM console.

Constant Contact API Integration

The audit pulls campaign metadata from Constant Contact's /api/v2/campaigns endpoint. The orchestrator uses a stored OAuth2 token (managed separately in secrets) to authenticate and retrieve:

  • Campaign name and ID
  • Scheduled send date
  • Contact list / segment targeting
  • Current status (draft, scheduled, sent, paused)
  • Approval state

This data is cross-referenced with our internal campaign templates (e.g., /repos/templates/email/mother-day-blast.html) to identify in-flight campaigns and approval blockers.

Key Operational Findings

The audit surfaced three urgent items:

  • Mother's Day Blast (April 29): Campaign was scheduled but remains in draft/unapproved state with only 4 days to execution. The template and recipient list are ready; the campaign is blocked on final approval in Constant Contact.
  • Paul Simon Blast (May 12 proof deadline): Proof email needs to be generated and sent for client review 6 days prior to blast execution. This requires pulling the Paul Simon email template, populating dynamic content (booking URL, event details), and sending to the internal review list.
  • GA Data API Access: Zero traffic data is available because the orchestrator's service account lacks VIEWER role on the GA4 property. This is a configuration fix, not a code issue.

Automation Decisions: Why We Built It This Way

Orchestrator as Agent, Not Cron Job: Rather than a time-based cron job, we use the orchestrator as a spawned agent that takes a full brief (wiki state, active handoffs, recent tasks) before executing. This prevents redundant audits and ensures context awareness. The agent reads the task queue, understands what's in-flight, and avoids duplicate work.

Kanban Card Output, Not Email Report: Audit findings land as a kanban card on the dashboard, not as an email or text file. This ensures visibility without inbox noise, allows team members to open the deep link and drill into details, and creates a persistent record of what was audited and when.

Hash Navigation for Deep Linking: By implementing hash-based routing in the dashboard, we can generate direct links to specific audit results. This is superior to query parameters because it doesn't require server-side routing and works in static S3-hosted environments.

What's Next

  • Grant GA API access: Configure the orchestrator service account in Google Cloud IAM to enable traffic data collection and analysis.