campaigns: exclude full Yahoo/Verizon-Media domain family from cold email
Yahoo operates a large family of consumer domains (AOL, AT&T, Verizon, Frontier, sbcglobal, bellsouth, etc.) that aggressively defer cold senders with 421 'unexpected volume / user complaints', which poisons our self-hosted sending IP for every other provider. Previously we only excluded aol.com/yahoo.com/ymail.com/rocketmail.com. Centralize the authoritative block list in scripts/_email_exclusions.py and import it from both audience builders so they stay in sync.
This commit is contained in:
parent
4010103531
commit
344300ebd4
3 changed files with 49 additions and 8 deletions
45
scripts/_email_exclusions.py
Normal file
45
scripts/_email_exclusions.py
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
"""Shared recipient-domain exclusions for outbound cold-email campaigns.
|
||||||
|
|
||||||
|
We self-host our MTA (transactional relays like SES forbid cold email), so we
|
||||||
|
must protect our sending-IP reputation manually. The single biggest lever is
|
||||||
|
NOT mailing the Yahoo/Verizon-Media family: those providers aggressively defer
|
||||||
|
cold senders with "unexpected volume / user complaints" 421 responses, which
|
||||||
|
poisons the IP for every other provider too.
|
||||||
|
|
||||||
|
Keep this list authoritative and import it everywhere we build audiences.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
# Yahoo / Verizon Media operates ALL of these consumer domains. Legacy AT&T and
|
||||||
|
# Frontier consumer mail was handed off to Yahoo's infrastructure as well.
|
||||||
|
YAHOO_FAMILY_DOMAINS: frozenset[str] = frozenset({
|
||||||
|
# Yahoo / AOL core
|
||||||
|
"yahoo.com", "yahoo.com.mx", "yahoo.es", "yahoo.it", "yahoo.ca",
|
||||||
|
"myyahoo.com", "ymail.com", "rocketmail.com",
|
||||||
|
"aol.com", "aol.com.mx", "aim.com", "love.com", "games.com", "wow.com",
|
||||||
|
"netscape.net", "netscape.com", "cs.com", "compuserve.com",
|
||||||
|
# AT&T family (Yahoo-hosted)
|
||||||
|
"att.net", "sbcglobal.net", "bellsouth.net", "pacbell.net",
|
||||||
|
"ameritech.net", "swbell.net", "snet.net", "flash.net", "prodigy.net",
|
||||||
|
"wans.net", "nvbell.net",
|
||||||
|
# Verizon family (Yahoo-hosted)
|
||||||
|
"verizon.net", "verizongni.com", "bellatlantic.net",
|
||||||
|
# Frontier (Yahoo-hosted)
|
||||||
|
"frontier.com", "frontiernet.net",
|
||||||
|
})
|
||||||
|
|
||||||
|
# The full set of consumer domains we refuse to cold-mail. Extend here as we
|
||||||
|
# discover other reputation-sensitive providers.
|
||||||
|
BLOCKED_EMAIL_DOMAINS: frozenset[str] = YAHOO_FAMILY_DOMAINS
|
||||||
|
|
||||||
|
|
||||||
|
def domain_of(email: str) -> str:
|
||||||
|
"""Return the lowercased domain part of an email, or '' if malformed."""
|
||||||
|
if "@" not in email:
|
||||||
|
return ""
|
||||||
|
return email.rsplit("@", 1)[-1].strip().lower()
|
||||||
|
|
||||||
|
|
||||||
|
def is_blocked(email: str) -> bool:
|
||||||
|
return domain_of(email) in BLOCKED_EMAIL_DOMAINS
|
||||||
|
|
@ -31,6 +31,8 @@ from datetime import date, datetime, timedelta, timezone
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
|
|
||||||
|
from scripts._email_exclusions import BLOCKED_EMAIL_DOMAINS
|
||||||
|
|
||||||
LOG = logging.getLogger("build_trucking_campaigns")
|
LOG = logging.getLogger("build_trucking_campaigns")
|
||||||
|
|
||||||
# ── Listmonk ──────────────────────────────────────────────────────────────────
|
# ── Listmonk ──────────────────────────────────────────────────────────────────
|
||||||
|
|
@ -155,13 +157,6 @@ USABLE_FILTER = (
|
||||||
"('smtp_valid','catch_all_domain','catch_all_detected'))"
|
"('smtp_valid','catch_all_domain','catch_all_detected'))"
|
||||||
)
|
)
|
||||||
|
|
||||||
BLOCKED_EMAIL_DOMAINS = (
|
|
||||||
"aol.com",
|
|
||||||
"yahoo.com",
|
|
||||||
"ymail.com",
|
|
||||||
"rocketmail.com",
|
|
||||||
)
|
|
||||||
|
|
||||||
DB_URL = os.getenv("DATABASE_URL", "")
|
DB_URL = os.getenv("DATABASE_URL", "")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ from typing import Any
|
||||||
import psycopg2
|
import psycopg2
|
||||||
import psycopg2.extras
|
import psycopg2.extras
|
||||||
|
|
||||||
|
from scripts._email_exclusions import BLOCKED_EMAIL_DOMAINS
|
||||||
|
|
||||||
LOG = logging.getLogger("populate_new_carrier_startup_campaign")
|
LOG = logging.getLogger("populate_new_carrier_startup_campaign")
|
||||||
|
|
||||||
LISTMONK_URL = os.getenv("LISTMONK_URL", "https://lists.performancewest.net").rstrip("/")
|
LISTMONK_URL = os.getenv("LISTMONK_URL", "https://lists.performancewest.net").rstrip("/")
|
||||||
|
|
@ -39,7 +41,6 @@ LISTMONK_PASS = os.getenv("LISTMONK_PASS", "6X1rKPea61N4rZ1S65Hx5zvqzbCj30F6nvEe
|
||||||
LIST_NAME = os.getenv("NEW_CARRIER_LIST_NAME", "FMCSA Trucking - New Carrier Missing Startup Items")
|
LIST_NAME = os.getenv("NEW_CARRIER_LIST_NAME", "FMCSA Trucking - New Carrier Missing Startup Items")
|
||||||
DATABASE_URL = os.getenv("DATABASE_URL", "")
|
DATABASE_URL = os.getenv("DATABASE_URL", "")
|
||||||
|
|
||||||
BLOCKED_EMAIL_DOMAINS = {"aol.com", "yahoo.com", "ymail.com", "rocketmail.com"}
|
|
||||||
STARTUP_SERVICE_SLUGS = {
|
STARTUP_SERVICE_SLUGS = {
|
||||||
"boc3-filing",
|
"boc3-filing",
|
||||||
"ucr-registration",
|
"ucr-registration",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue