From 1652a3b8bcb26e692f01f178b980f0a156c649fd Mon Sep 17 00:00:00 2001 From: justin Date: Tue, 16 Jun 2026 22:24:15 -0500 Subject: [PATCH] fix(campaigns): stop sending trucking blasts to mx_unreachable dead domains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause of zero conversions since Jun 9 + the Gmail/Outlook block storm: the send filter was '(email_verified IS TRUE OR result IN ...)'. The verifier sets email_verified=TRUE optimistically for mx_unreachable (domain exists but its mail server never answered the RCPT probe) — 438,163 such rows. Those HARD BOUNCE on send, producing ~1,100 bounces/day (~47% rate) and blocklisting half the 120k subscriber base, so real prospects never saw the offer. Fix: key the send filter ONLY off email_verify_result, never the broken boolean. Recovery mode (default): send only 'smtp_valid' to drive bounce rate to ~0 and rebuild reputation; set CAMPAIGN_INCLUDE_CATCH_ALL=1 to re-add catch-all domains once recovered. Mirrors the healthcare list-cleaning approach (HC bounces ~2-3%, which proves the fix). Note: only ~3k smtp_valid unsent remain — list growth via real-send bounce verification (separate burner domain) is the follow-up. --- scripts/build_trucking_campaigns.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/scripts/build_trucking_campaigns.py b/scripts/build_trucking_campaigns.py index 3dd896e..b255c1d 100644 --- a/scripts/build_trucking_campaigns.py +++ b/scripts/build_trucking_campaigns.py @@ -331,9 +331,25 @@ TEST_EMAIL = os.getenv("CAMPAIGN_TEST_EMAIL", "carrierone@gmx.com") REPLY_TO_EMAIL = os.getenv("CAMPAIGN_REPLY_TO", "info@performancewest.net") REPLY_TO_HEADERS = [{"name": "Reply-To", "value": REPLY_TO_EMAIL}] +# Which verification results are safe to SEND to. We key ONLY off +# email_verify_result, never the email_verified boolean: the verifier sets +# email_verified=TRUE optimistically for 'mx_unreachable' (domain exists but its +# mail server didn't answer the probe) — those addresses HARD-BOUNCE when we +# actually send, which is what tanked deliverability (≈47% bounce, half the list +# blocklisted). So 'mx_unreachable' and all error/reject results are excluded. +# +# Recovery mode (default ON while reputation is damaged): send ONLY 'smtp_valid' +# — addresses an MX explicitly accepted at RCPT time — to drive the bounce rate +# to near-zero and rebuild sender reputation. Once recovered, set +# CAMPAIGN_INCLUDE_CATCH_ALL=1 to re-add catch-all domains (which accept at SMTP +# time but can still bounce later, so they stay out during recovery). +_SENDABLE_RESULTS = ["smtp_valid"] +if os.getenv("CAMPAIGN_INCLUDE_CATCH_ALL", "0") not in ("0", "false", ""): + _SENDABLE_RESULTS += ["catch_all_domain", "catch_all_detected"] USABLE_FILTER = ( - "(email_verified IS TRUE OR email_verify_result IN " - "('smtp_valid','catch_all_domain','catch_all_detected'))" + "email_verify_result IN (" + + ", ".join(f"'{r}'" for r in _SENDABLE_RESULTS) + + ")" ) DB_URL = os.getenv("DATABASE_URL", "")