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.