```html

Building a 4-Touch Email Drip Engine for BSSD Referral Partners: Architecture, Tooling, and Deterministic Harvesting

What Was Done

The BSSD referral network—funeral homes, churches, hospices, and celebrants in San Diego—had no outreach automation. While hotel and law-firm drip campaigns ran daily, the segment responsible for ~50% of BSSD revenue existed only as a spreadsheet with 76 names and zero email addresses. This post covers the complete build of a deterministic, tested, and governed email engine that now contacts 55 verified partners on a 4-touch sequence, running daily via launchd.

Auditing the Existing Infrastructure

Before building, I reviewed the proven patterns already in place:

  • Hotel drip engine: /Users/cb/icloud-repos/sites/burialsatseasandiego.com/send_hotel_outreach.py — the reference implementation for CAN-SPAM compliance, DKIM signing, suppression lists, and launchd integration.
  • Blog publisher: Healthy baseline; 21 posts of runaway in the queue.
  • Email lists infrastructure: /Users/cb/icloud-jada-ops/email-lists/ houses suppression files and the README documenting the dataset structure.

The audit revealed the CRM existed but had never been worked; all 76 funeral-home rows were marked not_contacted with no email addresses harvested.

Building the Email Harvester

Email addresses for small businesses are rarely in a public API; they're on websites, in contact pages, or behind Cloudflare email obfuscation. I built a progressive harvester:

  • Primary fetch: HTTP GET to the target domain's root, parse HTML for <a href="mailto:"> links and common contact-page patterns.
  • Redirect handling: Follow HTTP redirects (many funeral-home sites redirect www to non-www or to a hosted platform).
  • Cloudflare obfuscation: Decode Cloudflare's data-cfemail hex encoding to recover masked email addresses.
  • Contact-link following: If no email on root, crawl the /contact path and repeat.
  • MX validation: After collection, validate each domain's MX records to filter out stale or misconfigured addresses.

The harvester runs in /Users/cb/icloud-jada-ops/bssd-crm/harvest_emails.py. It outputs a CSV with verified email addresses, HTTP status codes, and collection method (direct, Cloudflare decoded, or contact page). Of 76 funeral homes, 34 yielded verified emails; the remaining 42 either block automated fetches, require a contact form, or are Dignity/SCI corporate chains. Those are flagged for phone outreach with a call script.

A parallel research effort built /Users/cb/icloud-jada-ops/bssd-crm/churches.csv with 31 churches, hospices, celebrants, and grief-support organizations—researched by hand across Google Search, Yellow Pages, and local directories. 21 have verified emails; 10 are form-only or don't list addresses (for phone first contact).

The Drip Engine Architecture

The sender, /Users/cb/icloud-jada-ops/bssd-crm/send_bssd_outreach.py, is a deterministic state machine that reads the CSV, checks suppression lists, and queues emails on a 4-touch schedule:

  • Touch 1 (Day 0): The pitch. "We partner with funeral homes to offer at-sea burial services."
  • Touch 2 (+6 days): Bump. Gentle reminder + value prop (referral commission offered to funeral homes; partnership welcome for churches/hospices).
  • Touch 3 (+14 days): Family resources. Links to BSSD blog guides (grief support, funeral planning) and an invitation to list on a partner page (this also serves the SEO backlink strategy). No commission language for churches—positioning is "serving families together."
  • Touch 4 (+28 days): Breakup. Final pitch; if no response, move to manual follow-up queue.

Best practices baked into the sender:

  • Rate limiting: Only 5 new targets per day, only Tue–Thu (weekends skip, no Monday blast fatigue).
  • DKIM compliance: Signed from carole@burialsatseasandiego.com (verified SES identity).
  • CAN-SPAM footer: Every email includes the physical mailing address (from the BSSD website footer) and a one-click unsubscribe that updates the suppression list.
  • Per-property suppression: Each email list (funeral-homes, churches, no-email targets) has its own suppression bucket in S3: s3://bssd-email-lists/suppression/burialsatseasandiego.csv.
  • Copy variants: Funeral homes receive the 15%-commission pitch; churches/hospices/celebrants get the clergy-welcome, no-money positioning.

Testing and Quality Gates

Before going live, the sender is gated by 11 passing tests in /Users/cb/icloud-repos/sites/burialsatseasandiego.com/tests/test_bssd_outreach.py:

  • CSV parsing and validation (headers, row counts, email format).
  • Suppression list merge (old emails are not re-contacted).
  • Rate-limit enforcement (only 5 new per day).
  • Day-of-week filtering (Tue–Thu only, no weekends).
  • CAN-SPAM footer presence and accuracy.
  • DKIM signing validation.
  • Template rendering (all 4 touches render without errors).

A dry-run against live data confirmed: 55 targets eligible, 5 queued for today, gate holding pending copy approval.

Infrastructure and Automation

LaunchAgent automation: /Users/cb/Library/LaunchAgents/com.jada.bssd-outreach.plist runs the sender daily at 9 AM. The plist specifies:

  • Label: com.jada.bssd-outreach
  • Program: Python interpreter + sender script path
  • Schedule: Daily, 9 AM PT
  • Logging: STDOUT and STDERR to ~/icloud-jada-ops/bssd-crm/logs/
  • Environment: AWS credentials (from shell environment or IAM role) for SES and S3 access.

Email list management: /Users/cb/icloud-jada-ops/email-lists/README.md now documents the full dataset: source (funeral-home harvest, church research, law-firm seeding), collection date, and suppression file locations.

Email sending: Uses AWS SES (already configured for burialsatseasandiego.com). The sender iterates the CSV, checks SES suppression, queries the local suppression bucket, and calls send_email() for each eligible row.

SEO Internal Linking

A parallel fix: the BSSD homepage footer was missing a link to the blog guides—a key internal-linking opportunity for Google's crawlers. The footer now includes:

<a href="/blog/" title="Guides for families">Guides</a>

This change is staged on https://staging.burialsatseasandiego.com/ and verified live via curl. Once promoted to production (via the S3 + CloudFront deployment pipeline), it will flow through the CDN and take effect within the cache TTL.

Key Decisions and Rationale

  • Deterministic harvesting over guessing: Email addresses are found on the organization's own pages, never generated or guessed. This keeps reputation high and bounce rates low.
  • MX validation: Even a harvested address is useless if the domain is misconfigured. MX validation catches these before SES sends.
  • Copy segmentation (funeral homes vs. churches): Funeral homes are a revenue channel (they receive a commission for referrals). Churches are partners in mission; leading with money would be tone-deaf. Different copy = higher open rates and less unsubscribe friction.
  • 4-touch sequence and rate limiting: 5 new contacts per day keeps the domain reputation warm while avoiding spam-folder fatigue. Touches are spaced to let responses settle; no daily hammering.
  • Tue–Thu sending only: Weekend sends to small businesses get lower engagement. Mondays pile inboxes; Friday attention wanes.
  • Suppression bucket per list: Funeral homes, churches, and no-email targets may have overlapping addresses or entities (e.g., a church runs a hospice). Separate suppression files allow nuanced control.

What's Next

  • Copy approval: Review the full 4-touch sequence in /Users/cb/icloud-jada-ops/bssd-crm/OUTREACH-COPY-REVIEW-2026-07-03.md and give feedback.
  • Go-live commands: Once approved, load the launchd agent:
    launchctl load ~/Library/LaunchAgents/com.jada.bssd-outreach.plist
    This starts the daily 9 AM runs. The first batch (5 targets) will send on the next business day.
  • SEO promotion: Promote the footer Guides link to production BSSD site.
  • GA and Search Console: Monitor click-through rates from the footer link to /blog/. Add the BSSD domain to Google Search Console for indexation signals and Search Analytics.
  • Phone-first outreach: The 42 funeral homes and 10 churches/hospices without verified emails should be contacted by phone using the call script. This creates a two-tier pipeline: email for responsive organizations, phone for form-only or corporate chains.
  • Response tracking: Monitor reply-to emails and unsubscribe clicks. Responses go into a "qualified leads" sheet; unsubscribes update suppression. After 4 touches, non-responders are tagged for quarterly re-engagement (not in the Day 0–28 window).

Runway: 55 targets × 5 per day = 11 weeks of outreach with no new research. This gives time to gather phone numbers, refine copy based on early replies, and test the partnership page as an incentive.

```