new-site/scripts/tests/fix_chat_blocks.py
justin f8cd37ac8c Initial commit — Performance West telecom compliance platform
Includes: API (Express/TypeScript), Astro site, Python workers,
document generators, FCC compliance tools, Canada CRTC formation,
Ansible infrastructure, and deployment scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 06:54:22 -05:00

74 lines
3.4 KiB
Python

"""Insert chat invitation + discount blocks into Listmonk campaigns."""
import json
import subprocess
API_USER = "api"
API_PASS = "6X1rKPea61N4rZ1S65Hx5zvqzbCj30F6nvEe9oVGH_Y"
LISTMONK = "http://localhost:9100"
DISCOUNT = '<tr><td style="padding:20px 40px 10px 40px;"><table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#eff6ff;border-radius:8px;border:1px solid #bfdbfe;"><tr><td style="padding:16px 20px;font-family:Arial,sans-serif;font-size:14px;color:#1e3a5f;line-height:1.5;"><strong>Split it into 4 payments:</strong> Pay ~$975/month with Klarna Pay&nbsp;in&nbsp;4. Start your Canadian carrier setup today &mdash; pay over time.</td></tr></table></td></tr>'
CHAT = '<tr><td style="padding:10px 40px 20px 40px;"><table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f0f4f8;border-radius:8px;border:1px solid #e2e8f0;"><tr><td style="padding:16px 20px;font-family:Arial,sans-serif;font-size:14px;color:#475569;line-height:1.5;"><strong style="color:#1e3a5f;">Questions? We\'re online.</strong><br>Chat with us live on <a href="https://performancewest.net/services/telecom/canada-crtc" style="color:#e63f2a;text-decoration:none;">our website</a> (look for the chat icon in the bottom-right), or call <strong>1-888-411-0383</strong>.</td></tr></table></td></tr>'
FOOTER_MARKER = 'style="display:block;margin:0 auto 10px;width:70px'
def api_get(path):
r = subprocess.run(["curl", "-s", "-u", f"{API_USER}:{API_PASS}", f"{LISTMONK}{path}"],
capture_output=True, text=True, timeout=10)
return json.loads(r.stdout)
def api_put(path, data):
r = subprocess.run(["curl", "-s", "-X", "PUT", "-u", f"{API_USER}:{API_PASS}",
"-H", "Content-Type: application/json", "-d", json.dumps(data),
f"{LISTMONK}{path}"], capture_output=True, text=True, timeout=10)
return json.loads(r.stdout) if r.stdout else {}
# Campaigns that need discount + chat (final close emails)
DISCOUNT_CAMPAIGNS = [12, 18]
# Campaigns that need only chat
CHAT_CAMPAIGNS = [9, 10, 11, 15, 16, 17, 22, 23]
for cid in DISCOUNT_CAMPAIGNS + CHAT_CAMPAIGNS:
d = api_get(f"/api/campaigns/{cid}")
body = d["data"]["body"]
name = d["data"]["name"]
add_discount = cid in DISCOUNT_CAMPAIGNS
if "We're online" in body or "We are online" in body:
print(f" SKIP {cid:3d} | {name[:55]} | already has chat block")
continue
if FOOTER_MARKER not in body:
print(f" SKIP {cid:3d} | {name[:55]} | no footer marker")
continue
idx = body.index(FOOTER_MARKER)
tr_start = body[:idx].rfind("<tr><td")
if tr_start < 0:
print(f" SKIP {cid:3d} | {name[:55]} | can't find insertion point")
continue
insert = ""
if add_discount:
insert += DISCOUNT
insert += CHAT
body = body[:tr_start] + insert + body[tr_start:]
# Listmonk requires lists + other fields in PUT
lists = [l["id"] for l in d["data"].get("lists", [])]
result = api_put(f"/api/campaigns/{cid}", {
"name": d["data"]["name"],
"subject": d["data"]["subject"],
"body": body,
"lists": lists,
"content_type": d["data"].get("content_type", "richtext"),
"type": d["data"].get("type", "regular"),
})
if "data" in result:
tag = "discount+chat" if add_discount else "chat"
print(f" OK {cid:3d} | {name[:55]} | +{tag}")
else:
print(f" FAIL {cid:3d} | {name[:55]}")
print("\nDone")