diff --git a/infra/systemd/pw-hc-bounce-watcher.service b/infra/systemd/pw-hc-bounce-watcher.service new file mode 100644 index 0000000..8992ddd --- /dev/null +++ b/infra/systemd/pw-hc-bounce-watcher.service @@ -0,0 +1,13 @@ +[Unit] +Description=Healthcare Postfix bounce watcher -> listmonk-hc webhook +After=network.target docker.service + +[Service] +Type=simple +ExecStart=/usr/local/bin/postfix-hc-bounce-notify.sh +Restart=always +RestartSec=5 +User=root + +[Install] +WantedBy=multi-user.target diff --git a/scripts/build_healthcare_campaigns.py b/scripts/build_healthcare_campaigns.py index d85e5b4..eba5163 100644 --- a/scripts/build_healthcare_campaigns.py +++ b/scripts/build_healthcare_campaigns.py @@ -184,12 +184,12 @@ def render(seg_key: str, *, test: bool = False) -> tuple[str, str]:
|
- No logins. No portals. No headaches. +No 2FA. No government portals. No headaches. - You do not need to remember a PECOS password, pass identity - verification, fight a government website, or sit on hold with Medicare. We do - the work for you — all you have to do is say yes. We keep your filing on - track and confirm when it’s accepted. + You do not need to remember a PECOS password, pass CMS identity + verification or two-factor codes, fight a government website, or sit on hold with + Medicare. We do the work for you — all you have to do is say yes. We keep + your filing on track and confirm when it’s accepted.
About Performance West. We’re a regulatory compliance
diff --git a/scripts/build_healthcare_campaigns_cron.py b/scripts/build_healthcare_campaigns_cron.py
index c078fa6..d0d09aa 100644
--- a/scripts/build_healthcare_campaigns_cron.py
+++ b/scripts/build_healthcare_campaigns_cron.py
@@ -144,13 +144,20 @@ def add_subscriber(list_id: int, email: str, name: str, attribs: dict) -> bool:
def ensure_campaign(list_id: int) -> int:
+ # Reuse an existing HC warmup campaign only if it's still ACTIVE (draft /
+ # running / paused / scheduled). A finished/cancelled campaign can't accept
+ # new subscribers or be restarted, so we create a fresh dated one — that also
+ # picks up the latest email template (e.g. copy/colour tweaks).
+ from datetime import date
+ ACTIVE = {"draft", "running", "paused", "scheduled"}
res = lm("/campaigns?per_page=100")
for c in res.get("data", {}).get("results", []):
- if c["name"] == CAMPAIGN_NAME:
+ if c["name"].startswith(CAMPAIGN_NAME) and c.get("status") in ACTIVE:
return c["id"]
body = open(EMAIL_HTML).read()
+ dated = f"{CAMPAIGN_NAME} - {date.today():%b %d %Y}"
payload = {
- "name": CAMPAIGN_NAME, "subject": SUBJECT, "lists": [list_id],
+ "name": dated, "subject": SUBJECT, "lists": [list_id],
"from_email": FROM_EMAIL, "type": "regular", "content_type": "richtext",
"body": body, "messenger": "email",
"tags": ["healthcare", "warmup"],
diff --git a/scripts/hc-bounce-watcher.sh b/scripts/hc-bounce-watcher.sh
new file mode 100644
index 0000000..27415de
--- /dev/null
+++ b/scripts/hc-bounce-watcher.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+# Healthcare Postfix bounce watcher -> listmonk-hc webhook.
+# Parallel to the trucking pw-bounce-watcher, but scoped to the HEALTHCARE HOT
+# stream: it tracks the hc sender (compliance@performancewest.net) and the
+# hcout1/2/3 transports, and reports bounces to listmonk-hc (:9101).
+#
+# Install: /usr/local/bin/postfix-hc-bounce-notify.sh
+# Service: /etc/systemd/system/pw-hc-bounce-watcher.service
+#
+# Bounce policy is set in listmonk-hc settings (bounce.actions): a single hard
+# bounce or complaint -> blocklist; soft bounces tracked. This keeps the warming
+# hc IPs clean by suppressing dead/complaining addresses immediately.
+
+LOG=/var/log/mail.log
+API="http://localhost:9101"
+TOKEN_FILE=/opt/performancewest/.secrets/hc-listmonk-token
+TOKEN="$(cat "$TOKEN_FILE" 2>/dev/null)"
+AUTHHDR="Authorization: token api:${TOKEN}"
+
+# hc campaign senders
+HC_SENDER1="from= |