```html

Implementing Multi-Platform Outreach Automation with SES Suppression List Integration

This post covers the architecture and implementation of a Python-based email campaign system that manages SES bounce suppression, multi-platform lead discovery, and scheduled outreach cadences for event-based marketing.

The Problem: Manual Platform Management at Scale

Managing outreach across multiple booking platforms (GetMyBoat, WeddingWire, Airbnb Experiences, Viator) requires coordinating different APIs, email templates, and contact filtering rules. The previous system relied on manual task management without automated suppression list handling or campaign scheduling.

Architecture Overview

We implemented a three-tier system:

  • Data Layer: SES suppression list exports, cleaned contact CSVs stored in S3
  • Processing Layer: Python blast tool (/Users/cb/Documents/repos/tools/jada_blast.py) with platform-specific contact filtering
  • Scheduling Layer: macOS LaunchAgents for cadence-based email sending

Technical Details: The Blast Tool Implementation

The core blast script (jada_blast.py) was refactored to support multiple operational modes:


# Primary functions:
- export_ses_suppression() → exports bounce/complaint list from SES
- load_contact_csv(filepath) → parses platform-specific contact files
- filter_contacts(contacts, suppression_list) → removes bounced addresses
- send_campaign(contacts, template, platform) → executes email dispatch

The contact filtering logic removes any email address appearing in the SES suppression list before sending. This prevents re-mailing bounced addresses and protects domain reputation:


suppression_set = set(suppression_data['suppressed_emails'])
cleaned_contacts = [c for c in contacts if c['email'] not in suppression_set]
print(f"Removed {len(contacts) - len(cleaned_contacts)} suppressed emails")

Platform Task Card Structure

To manage multi-platform outreach systematically, we created dashboard task cards for each platform with this metadata structure:

  • Platform: GetMyBoat, WeddingWire, Airbnb Experiences, Viator
  • Status: Initial outreach, Follow-up 1, Follow-up 2, Breakup sequence
  • Contact Source: Platform-specific CSV exports (e.g., getmyboat_contacts_2026.csv)
  • Template Reference: Email templates stored in S3 marketing bucket
  • Cadence Timeline: Initial → +7 days → +14 days → +21 days (breakup)

Scheduled Execution with LaunchAgents

To automate the cadence without manual intervention, we created four LaunchAgent plist files in /Users/cb/Library/LaunchAgents/:


com.jada.hotel-outreach-initial.plist     # Runs initial contact sequence
com.jada.hotel-outreach-followup1.plist   # +7 day follow-up
com.jada.hotel-outreach-followup2.plist   # +14 day follow-up
com.jada.hotel-outreach-breakup.plist     # +21 day breakup email

Each plist schedules send_hotel_outreach.py to execute at specific intervals. The script: 1. Reads the contact CSV for the given platform 2. Fetches the current SES suppression list 3. Filters contacts 4. Sends the appropriate template 5. Logs results to dashboard

Marketing Copy Audit and Anonymization

A critical operational requirement emerged: all outward-facing marketing materials must be anonymized to remove personal attribution. This required auditing and updating files across multiple domains:

  • /tmp/sdcc-hotel-outreach-2026.html — San Diego Comic-Con event email template
  • /Users/cb/Documents/repos/sites/dangerouscentaur/demos/ — Demo site landing pages
  • /Users/cb/Documents/repos/sites/queenofsandiego.com/ — Main event site
  • /Users/cb/Documents/repos/sites/progress.queenofsandiego.com/ — Progress dashboard

We removed all instances of personal name attribution and rebranded copy to reference "Team" + organization name. The S3 deployment included cache invalidation on CloudFront distributions to ensure updated content served immediately.

Contact Cleaning and SES Integration

Before launching campaigns, we exported the SES suppression list and cross-referenced all contact CSVs against it:


# Exported suppression data includes:
- Bounced email addresses (permanent/transient)
- Complaint addresses (user marked as spam)
- Suppression timestamps

# Applied filtering:
cleaned_contacts = original_contacts - suppression_set
reduction_rate = (len(original_contacts) - len(cleaned_contacts)) / len(original_contacts)

This prevented wasting credits on addresses likely to bounce again and maintained sender reputation with ISPs.

Infrastructure: S3 and CloudFront Deployment

Updated marketing materials were deployed to S3 buckets with CloudFront distribution caching:

  • S3 Bucket: JADA marketing assets bucket (exact name withheld for security)
  • Objects: HTML email templates, demo site assets, landing pages
  • CloudFront Distribution: Multiple distributions for domain-specific content
  • Invalidation Pattern: /* full cache clear after updates

This ensured updated templates and landing pages propagated globally within seconds of deployment.

Key Architectural Decisions

Why SES Suppression Over Manual Lists: SES suppression data is the source of truth for deliverability. Hard bounces indicate permanent undeliverability; complaints indicate user engagement issues. Filtering at send-time prevents reputation damage.

Why LaunchAgents Over Cron: macOS LaunchAgents provide native integration with system scheduling, better error handling, and log aggregation via system unified logging.

Why CSV + Dashboard Integration: Platform contact exports come as CSVs. Dashboard task cards provide team visibility into campaign status without requiring database infrastructure.

Why Anonymized Copy: Removing personal attribution from marketing reduces legal/brand risk and allows flexibility in campaign messaging across multiple organizations and event contexts.

What's Next

  • Platform API Integration: Direct API connections to GetMyBoat and WeddingWire to eliminate CSV dependency
  • Campaign Analytics: Track open rates, click rates, and reply rates per platform to optimize templates
  • Dynamic Personalization: Inject hyper-local event details (venue name, date, capacity) into template variables
  • A/B Testing: Run parallel subject line variants to measure CTR improvement

The system now provides repeatable, maintainable infrastructure for multi-platform event marketing with built-in compliance safeguards and scheduling automation.