fix(email): drop @TrackLink from per-subscriber CTAs (404 + collapse bug)
Listmonk @TrackLink registers ONE static URL per tracked link and points
every recipient's /link/<uuid> redirect at it. On per-subscriber hrefs
({{ lp_link }}, ?dot=, ?npi=, ?clia=) this is doubly broken:
- the registered links.url was captured before the {{ lp_link }} token
rendered, yielding /order/slug&utm_source=... (first &, no ?) -> 404
- even when valid it collapses every carrier/provider onto the first
subscriber's dot/npi/clia value
Real human clicks are already tracked via Umami campaign-click (bot
filtered), so Listmonk link tracking here is redundant and destructive.
Stripped @TrackLink from per-subscriber CTAs:
- scripts/create_deficiency_source_campaigns.py (_cta, _dot_check_cta)
- data/trucking_campaigns/{ucr,ifta}_*.html
- data/hc_campaigns/*.html (10 templates)
Static CTAs (e.g. CRTC ?code= order link) keep @TrackLink (safe).
Live fix to the 10 broken registered links.url rows applied separately
(first & -> ?), backup in listmonk.pw_links_dkim_fix_bak_20260622.
Docs: new runbook incident section + corrected the disproven
'use @TrackLink on all CTAs' guidance in fmcsa/hc plans.
This commit is contained in:
parent
1e9dcfcfd1
commit
3325259af7
16 changed files with 98 additions and 19 deletions
|
|
@ -58,7 +58,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">Let us take the CLIA renewal off your plate — the sooner we start, the better.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">We submit most filings within 1-2 business days, then track it through CMS processing to confirmation.</p>
|
||||
<a href="https://performancewest.net/order/clia-renewal?clia={{ .Subscriber.Attribs.clia }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-clia-renewal@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Renew my CLIA certificate →</a>
|
||||
<a href="https://performancewest.net/order/clia-renewal?clia={{ .Subscriber.Attribs.clia }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-clia-renewal" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Renew my CLIA certificate →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">One annual bundle covers your core CMS obligations.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">We watch the deadlines so you never miss one.</p>
|
||||
<a href="https://performancewest.net/order/provider-compliance-bundle?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-compliance-bundle@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Get the compliance bundle →</a>
|
||||
<a href="https://performancewest.net/order/provider-compliance-bundle?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-compliance-bundle" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Get the compliance bundle →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">We handle the CMS-855 reactivation end to end.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">We verify every field against current CMS requirements.</p>
|
||||
<a href="https://performancewest.net/order/npi-reactivation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-npi-reactivation@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Reactivate my enrollment →</a>
|
||||
<a href="https://performancewest.net/order/npi-reactivation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-npi-reactivation" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Reactivate my enrollment →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">Run your free compliance check — takes about 30 seconds.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">Your NPI is pre-filled. No signup, no cost — just your results.</p>
|
||||
<a href="https://performancewest.net/tools/npi-compliance-check?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-npi-check@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Run my free NPI check →</a>
|
||||
<a href="https://performancewest.net/tools/npi-compliance-check?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-npi-check" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Run my free NPI check →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">We run and document your OIG/SAM exclusion screening.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">Monthly checks with an audit-ready record — cancel anytime.</p>
|
||||
<a href="https://performancewest.net/order/oig-sam-screening?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-oig-screening@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Set up exclusion screening →</a>
|
||||
<a href="https://performancewest.net/order/oig-sam-screening?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-oig-screening" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Set up exclusion screening →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">We file your PECOS revalidation for you, well before the deadline.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">Most filings submitted within 1-2 business days.</p>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-due-soon@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Start my revalidation →</a>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-due-soon" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Start my revalidation →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">We file your PECOS revalidation for you, before the clock runs out.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">Most filings submitted within 1-2 business days.</p>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-overdue@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Start my revalidation →</a>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-overdue" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Start my revalidation →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">Let us get your past-due revalidation filed right away.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">We submit most filings within 1-2 business days, then track it through CMS processing to confirmation.</p>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-overdue-personal@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Handle my revalidation →</a>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-overdue-personal" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Handle my revalidation →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">Let us take revalidation off your plate — the sooner we start, the better.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">We submit most filings within 1-2 business days, then track it through CMS processing to confirmation.</p>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-personal@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Handle my revalidation →</a>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-personal" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Handle my revalidation →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:22px 0;"><tr><td style="background:#ecfdf5;border:2px solid #10b981;border-radius:10px;padding:18px;text-align:center;">
|
||||
<p style="font-size:14px;color:#065f46;margin:0 0 6px;font-weight:600;">Let us take revalidation off your plate — the sooner we start, the better.</p>
|
||||
<p style="font-size:12px;color:#047857;margin:0 0 14px;">We submit most filings within 1-2 business days, then track it through CMS processing to confirmation.</p>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-turnover@TrackLink" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Handle my revalidation →</a>
|
||||
<a href="https://performancewest.net/order/npi-revalidation?npi={{ .Subscriber.Attribs.npi }}&utm_source=listmonk&utm_medium=email&utm_campaign=hc-reval-turnover" style="display:inline-block;padding:14px 40px;background:#10b981;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:15px;">Handle my revalidation →</a>
|
||||
</td></tr></table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:18px 0;"><tr><td style="background:#f0f4f8;border-radius:8px;padding:16px;font-size:13px;color:#374151;line-height:1.6;">
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
<p style="font-size:13px;color:#64748b;margin:0;line-height:1.6">Send us your total miles and gallons by jurisdiction for the quarter. We calculate the tax owed for every state you ran in, prepare the return, and file it. You just review and we handle the rest - so you can get back to driving.</p>
|
||||
</div>
|
||||
<div style="text-align:center;margin:24px 0">
|
||||
<a href="{{ .Subscriber.Attribs.lp_link }}&utm_source=listmonk&utm_medium=email&utm_campaign=ifta-quarterly@TrackLink" style="display:inline-block;padding:14px 36px;background:#f97316;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:16px">10-4 - File My IFTA Return →</a>
|
||||
<a href="{{ .Subscriber.Attribs.lp_link }}&utm_source=listmonk&utm_medium=email&utm_campaign=ifta-quarterly" style="display:inline-block;padding:14px 36px;background:#f97316;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:16px">10-4 - File My IFTA Return →</a>
|
||||
</div>
|
||||
<p style="font-size:14px;color:#64748b;line-height:1.6">Or call us directly at <a href="tel:8884110383" style="color:#f97316;font-weight:600">(888) 411-0383</a>.</p>
|
||||
<div style="text-align:center;margin:18px 0 4px;padding-top:14px;border-top:1px solid #e5e7eb">
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
<p style="font-size:13px;color:#64748b;margin:0;line-height:1.6">UCR fees are based on your fleet size, and getting the tier wrong causes rejections and delays. Tell us your power-unit count and we file it correctly the first time, so you stay legal and on the road.</p>
|
||||
</div>
|
||||
<div style="text-align:center;margin:24px 0">
|
||||
<a href="{{ .Subscriber.Attribs.lp_link }}&utm_source=listmonk&utm_medium=email&utm_campaign=ucr-annual@TrackLink" style="display:inline-block;padding:14px 36px;background:#f97316;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:16px">10-4 - File My UCR Now →</a>
|
||||
<a href="{{ .Subscriber.Attribs.lp_link }}&utm_source=listmonk&utm_medium=email&utm_campaign=ucr-annual" style="display:inline-block;padding:14px 36px;background:#f97316;color:#fff;font-weight:700;border-radius:8px;text-decoration:none;font-size:16px">10-4 - File My UCR Now →</a>
|
||||
</div>
|
||||
<p style="font-size:14px;color:#64748b;line-height:1.6">Or call us directly at <a href="tel:8884110383" style="color:#f97316;font-weight:600">(888) 411-0383</a>.</p>
|
||||
<div style="text-align:center;margin:18px 0 4px;padding-top:14px;border-top:1px solid #e5e7eb">
|
||||
|
|
|
|||
|
|
@ -201,6 +201,65 @@ b.old_listmonk_sent_at FROM resend_dkim_backup_20260622 b WHERE c.dot_number =
|
|||
b.dot_number;`. To resume normal warmup exclusion later, unset
|
||||
`MAIN_EXCLUDE_OPERATORS` (reverts to Google+Microsoft+consumer-MX held to day 30).
|
||||
|
||||
### Incident: Jun 22 2026 — `@TrackLink` on per-subscriber CTAs = 404 + collapse
|
||||
|
||||
**Symptom.** The trucking "deficiency" CTA buttons (the primary order link and the
|
||||
secondary DOT-check link) rendered as Listmonk tracking redirects
|
||||
(`https://lists.performancewest.net/link/<uuid>/...`) that **404'd**. The redirect
|
||||
target (registered in `links.url`) was `https://performancewest.net/order/boc3-filing&utm_source=...`
|
||||
— note the `&` with **no `?`** — an invalid URL.
|
||||
|
||||
**Root cause.** Listmonk's `@TrackLink` marker registers **one static URL per
|
||||
tracked link** and points every recipient's `/link/<uuid>` redirect at that single
|
||||
row. This is fundamentally incompatible with a **per-subscriber** href such as
|
||||
`{{ .Subscriber.Attribs.lp_link }}&utm_source=...`:
|
||||
- The registered `links.url` was captured with the `{{ lp_link }}` token dropped,
|
||||
yielding `/order/slug&utm_source=...` (first `&`, no `?`) → **404 for everyone**.
|
||||
- Even if the URL had been valid, a static registration **collapses every carrier
|
||||
onto the first subscriber's** `?dot=` (or `?npi=`/`?clia=`) value — wrong order
|
||||
pre-fill for the entire blast.
|
||||
|
||||
By contrast, a **static** CTA (same URL for all recipients, e.g. the CRTC
|
||||
`?code=...` order link) tracks correctly — keep `@TrackLink` there.
|
||||
|
||||
**Why removing tracking loses nothing.** Real human clicks are already attributed
|
||||
via Umami's `campaign-click` event (bot-filtered by `pw-bot-filter.js`). Listmonk's
|
||||
own click counters were already established as unreliable for this stream. So
|
||||
Listmonk link tracking on per-subscriber CTAs is both redundant and destructive.
|
||||
|
||||
**Fix — live (already-sent + in-flight mail).** Rewrote the 10 broken registered
|
||||
rows in place (replace the first `&` with `?`) so the baked `/link/<uuid>` redirects
|
||||
resolve. Backup table `listmonk.pw_links_dkim_fix_bak_20260622` holds the old urls.
|
||||
Verified the exact redirect that 404'd now returns 200 → lands on the (generic,
|
||||
DOT-not-prefilled but fully functional) order page. To revert:
|
||||
```sql
|
||||
UPDATE links l SET url = b.url
|
||||
FROM pw_links_dkim_fix_bak_20260622 b WHERE l.id = b.id; -- in the `listmonk` DB
|
||||
```
|
||||
|
||||
**Fix — source (future builds, the real fix).** Stripped `@TrackLink` from every
|
||||
**per-subscriber / per-provider** CTA so each row renders its own direct link (no
|
||||
redirect, no collapse). Files changed:
|
||||
- `scripts/create_deficiency_source_campaigns.py` — `_cta()` (lp_link order button)
|
||||
and `_dot_check_cta()` (per-DOT tools link).
|
||||
- `data/trucking_campaigns/{ucr_annual_reminder,ifta_quarterly_reminder}.html`
|
||||
(per-carrier `lp_link`).
|
||||
- `data/hc_campaigns/*.html` (10 templates, per-provider `?npi=`/`?clia=`).
|
||||
`lp_link` already starts its query with `?dot=` (see `lp_link_with_coupon()`), so
|
||||
`{{ lp_link }}&utm...` renders to a valid per-carrier URL once the redirect is gone.
|
||||
|
||||
**Healthcare note.** The HC Listmonk DB (`listmonk_hc`) had **0 registered links**
|
||||
despite 13,425 sent — `@TrackLink` was not being stripped there at all, so the
|
||||
literal `@TrackLink` shipped as harmless trailing text in `utm_campaign` and the
|
||||
hrefs still 200'd (per-provider `?npi=` was present literally in the template, not
|
||||
via lp_link). No live HC breakage; source templates cleaned anyway to remove the
|
||||
collapse risk on the next send.
|
||||
|
||||
**Guardrail.** Never put `@TrackLink` on an href containing a `{{ .Subscriber... }}`
|
||||
token. Per-subscriber links must render directly; rely on Umami `campaign-click`
|
||||
for human-click attribution.
|
||||
|
||||
|
||||
### Follow-up hardening — DONE (Jun 17-18 2026)
|
||||
|
||||
All discovered during the post-incident technical audit; each fix is codified.
|
||||
|
|
|
|||
|
|
@ -137,7 +137,11 @@
|
|||
- Same Listmonk infrastructure as FCC campaigns
|
||||
- Warmup schedule (200/day → ramp up)
|
||||
- Link to DOT compliance checker with `?dot={DOT#}&email={email}` pre-filled
|
||||
- Use `@TrackLink` on all CTAs (learned from FCC campaign mistake)
|
||||
- Use `@TrackLink` ONLY on **static** CTAs (same URL for all recipients). NEVER on
|
||||
a per-subscriber href such as `{{ lp_link }}` / `?dot={DOT#}` — Listmonk registers
|
||||
one static URL per tracked link and would 404 + collapse every carrier onto one
|
||||
DOT (see runbook "Jun 22 2026 — @TrackLink on per-subscriber CTAs"). Per-subscriber
|
||||
links render directly; human clicks are tracked via Umami `campaign-click`.
|
||||
- Free compliance check as the CTA (not direct sell)
|
||||
|
||||
## Phase 5: Automation (Future)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,13 @@ click tracking, and de-risking unsubstantiated status claims.
|
|||
1. **Removed all service prices** from the emails (price is now revealed on the
|
||||
order page, after value is established). Catalog (`api/src/service-catalog.ts`)
|
||||
remains the source of truth.
|
||||
2. **Fixed click tracking** — appended `@TrackLink` + UTM to every conversion CTA
|
||||
(root cause of clicks=0; Listmonk only registers links with that marker).
|
||||
2. **Click tracking** — originally appended `@TrackLink` + UTM to every conversion
|
||||
CTA. **SUPERSEDED (Jun 22 2026):** `@TrackLink` must NOT be used on per-provider
|
||||
hrefs (`?npi=`/`?clia=`/`{{ lp_link }}`) — Listmonk registers one static URL per
|
||||
tracked link, which 404s and collapses every provider onto one NPI. `@TrackLink`
|
||||
removed from all HC templates; per-provider links render directly and human clicks
|
||||
are tracked via Umami `campaign-click`. See runbook "Jun 22 2026 — @TrackLink on
|
||||
per-subscriber CTAs."
|
||||
3. **Reframed unsubstantiated per-record status assertions** to honest, hedged,
|
||||
generally-true statements (defamation / FTC-deception risk).
|
||||
4. This compliance review.
|
||||
|
|
@ -84,8 +89,9 @@ These are factual compliance claims and must be **literally true**:
|
|||
|
||||
## HTML / deliverability QA — PASS
|
||||
- All 10 templates render with **0 JS errors** headless, each has **exactly one
|
||||
tracked `/order/...@TrackLink` CTA**, and **no price leaks** (only the $20,000
|
||||
OIG penalty stat remains, intentionally).
|
||||
per-provider `/order/...` CTA** (direct link, `@TrackLink` removed Jun 22 2026 —
|
||||
see item 2), and **no price leaks** (only the $20,000 OIG penalty stat remains,
|
||||
intentionally).
|
||||
- External self-verify links (oig.hhs.gov, sam.gov, npiregistry, data.cms.gov) left
|
||||
**untracked** on purpose (they're trust links, not conversions).
|
||||
|
||||
|
|
|
|||
|
|
@ -128,10 +128,20 @@ def _cta(label):
|
|||
# so the template appends its own params with a leading `&` — correct whether
|
||||
# or not the coupon is on. (Previously this used `?dot=`, which double-`?`d
|
||||
# the URL once the coupon added its own query.)
|
||||
#
|
||||
# NO `@TrackLink` here: Listmonk registers a *single static URL per tracked
|
||||
# link* and points every recipient's /link/<uuid> redirect at it. For a
|
||||
# per-subscriber URL like lp_link that is doubly broken — (1) the registered
|
||||
# URL was captured before the `{{ lp_link }}` token rendered, dropping the
|
||||
# `?dot=` and producing `/order/slug&utm_source=...` (no `?`) which 404s, and
|
||||
# (2) even when valid it collapses EVERY carrier onto the first subscriber's
|
||||
# DOT. Real human clicks are tracked via Umami's `campaign-click` event
|
||||
# (bot-filtered), so Listmonk link tracking is redundant here. Rendering the
|
||||
# link directly gives each carrier their own correct `?dot=` URL, no redirect.
|
||||
return (
|
||||
'<div style="text-align:center;margin:24px 0">'
|
||||
'<a href="{{ .Subscriber.Attribs.lp_link }}'
|
||||
'&utm_source=listmonk&utm_medium=email&utm_campaign=deficiency@TrackLink" '
|
||||
'&utm_source=listmonk&utm_medium=email&utm_campaign=deficiency" '
|
||||
'style="display:inline-block;padding:14px 36px;background:#f97316;color:#fff;'
|
||||
f'font-weight:700;border-radius:8px;text-decoration:none;font-size:16px">{label} →</a></div>'
|
||||
)
|
||||
|
|
@ -149,7 +159,7 @@ def _dot_check_cta():
|
|||
'<p style="font-size:13px;color:#64748b;line-height:1.5;margin:0 0 10px">'
|
||||
'Want to verify everything else on your DOT profile first?</p>'
|
||||
f'<a href="{b.SITE_DOMAIN}/tools/dot-compliance-check?dot={{{{ .Subscriber.Attribs.dot_number }}}}'
|
||||
'&utm_source=listmonk&utm_medium=email&utm_campaign=deficiency_dot_check@TrackLink" '
|
||||
'&utm_source=listmonk&utm_medium=email&utm_campaign=deficiency_dot_check" '
|
||||
'style="display:inline-block;padding:13px 30px;background:#f97316;color:#fff;'
|
||||
'font-weight:700;border-radius:8px;text-decoration:none;font-size:15px">'
|
||||
'Run Free DOT Compliance Check →</a></div>'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue