Files
nur-muslim-companion/scripts/mautic_setup.py
T
Hermes Bot a440160249 Add sales automation stack: strategy docs, MCP scripts, PWA refinements
- SALES_STRATEGY.md: $1K/day plan (37 orders @ $27.50 AOV, 1,700 visits)
- TRIPWIRE_FUNNEL.md: 7-email Mautic sequence + lead scoring
- MONETIZATION.md: 9 monetization options for Nūr PWA (no ads, no registration)
- EXECUTABLE_PLAN.md: MCP-executable automation plan
- DAILY_OPS.md: daily KPI checklist (visits, orders, sends, recoveries)
- scripts/: automation.py, mautic_setup.py, gumroad_setup.py, scout_scrape.py, analytics.py, crontab
- quality_leads.json/.csv: 12 enriched Islamic-tech leads for Mautic import
- content_queue.json: 10 SEO blog posts for Ghost
- PWA: icons, sw.js, e2e + vitest coverage, generator scripts
2026-08-06 23:33:21 +08:00

213 lines
8.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""
One-time Mautic Setup: Create segment, import contacts, create 7 emails.
Run once: python scripts/mautic_setup.py
All operations in a single process to avoid session expiry.
"""
import os, sys, json, csv, re
from datetime import datetime
sys.path.insert(0, "/Users/wmj24/.hermes/mcp-servers/mautic-server")
from server import _web_login, _session, BASE, API_TIMEOUT
import requests as req
from bs4 import BeautifulSoup
from urllib.parse import urljoin
# ─── Login ──────────────────────────────────────────────────
print("Logging into Mautic...")
result = _web_login()
if not result.get("success"):
print(f"Login failed: {result}")
sys.exit(1)
print("Logged in.")
session = req.Session()
if _session.get("cookies"):
session.cookies.update(_session["cookies"])
csrf_token = _session.get("csrf", "")
# ─── 1. Create Segment ──────────────────────────────────────
print("\n--- Creating Segment ---")
def create_segment(name, alias, description):
r = session.get(urljoin(BASE, "/s/segments/new"), timeout=20, verify=False)
soup = BeautifulSoup(r.text, "lxml")
token_input = soup.find("input", {"name": "segment[_token]"})
if not token_input:
print(" ERROR: Could not find segment[_token]")
# Try to find mauticAjaxCsrf
m = re.search(r"mauticAjaxCsrf\s*=\s*['\"]([^'\"]+)['\"]", r.text)
csrf = m.group(1) if m else csrf_token
print(f" Got CSRF: {csrf[:20]}")
print(f" Page title check: {'login' in r.text.lower()}")
return None
form_token = token_input.get("value", "")
m = re.search(r"mauticAjaxCsrf\s*=\s*['\"]([^'\"]+)['\"]", r.text)
ajax_csrf = m.group(1) if m else csrf_token
r2 = session.post(
urljoin(BASE, "/s/segments/new"),
data={
"segment[name]": name,
"segment[alias]": alias,
"segment[description]": description,
"segment[isPublished]": "1",
"segment[_token]": form_token,
"segment[buttons][save]": "",
},
headers={
"User-Agent": "hermes-mautic-mcp/1.0",
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token": ajax_csrf,
},
timeout=API_TIMEOUT,
verify=False,
)
if r2.status_code == 200:
# Try to extract segment ID
m = re.search(r'/s/segment/(\d+)', r2.text)
seg_id = m.group(1) if m else "unknown"
print(f" Segment created: {name} (ID: {seg_id})")
return seg_id
else:
print(f" Segment creation failed: {r2.status_code}")
print(f" Response: {r2.text[:500]}")
return None
segment_id = create_segment(
"High-Value Islamic Tech Leads",
"high-value-islamic-tech-leads",
"Quality Muslim developers, founders, and builders in Islamic tech — scraped via Scout MCP"
)
# ─── 2. Import Contacts ─────────────────────────────────────
print("\n--- Importing Contacts ---")
leads_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "quality_leads.json")
if not os.path.exists(leads_path):
print(f" No leads file found at {leads_path}")
else:
with open(leads_path) as f:
leads = json.load(f)
imported = 0
for lead in leads:
email = lead.get("email", "")
if not email or "@" not in email:
# Try to guess email from patterns
name_parts = lead.get("full_name", lead.get("username", "")).split()
username = lead.get("username", "")
domain = lead.get("website", "").replace("https://", "").replace("http://", "").split("/")[0]
if domain and domain != "":
email = f"{username}@{domain}"
else:
continue
# Use Mautic API to create contact
# First get CSRF token for contact form
try:
r = session.get(urljoin(BASE, "/s/contacts/new"), timeout=20, verify=False)
soup = BeautifulSoup(r.text, "lxml")
token_input = soup.find("input", {"name": "contact[_token]"})
if token_input:
form_token = token_input.get("value", "")
m = re.search(r"mauticAjaxCsrf\s*=\s*['\"]([^'\"]+)['\"]", r.text)
ajax_csrf = m.group(1) if m else csrf_token
r2 = session.post(
urljoin(BASE, "/s/contacts/new"),
data={
"contact[firstname]": lead.get("firstname", ""),
"contact[lastname]": lead.get("lastname", ""),
"contact[email]": email,
"contact[company]": lead.get("company", ""),
"contact[position]": lead.get("position", ""),
"contact[website]": lead.get("website", ""),
"contact[points]": lead.get("lead_score", 0),
"contact[_token]": form_token,
"contact[buttons][save]": "",
},
headers={
"User-Agent": "hermes-mautic-mcp/1.0",
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token": ajax_csrf,
},
timeout=API_TIMEOUT,
verify=False,
)
if r2.status_code == 200:
imported += 1
print(f" Imported: {lead.get('username', email)}")
else:
print(f" Failed: {lead.get('username', email)} ({r2.status_code})")
except Exception as e:
print(f" Error importing {email}: {e}")
print(f" Total imported: {imported}/{len(leads)}")
# ─── 3. Create Email Sequence ───────────────────────────────
print("\n--- Creating Email Sequence ---")
def create_email(name, subject, body_html, segment_id=0):
r = session.get(urljoin(BASE, "/s/emails/new"), timeout=20, verify=False)
soup = BeautifulSoup(r.text, "lxml")
token_input = soup.find("input", {"name": "email[_token]"})
if not token_input:
print(f" ERROR: Could not find email[_token] for {name}")
return None
form_token = token_input.get("value", "")
m = re.search(r"mauticAjaxCsrf\s*=\s*['\"]([^'\"]+)['\"]", r.text)
ajax_csrf = m.group(1) if m else csrf_token
r2 = session.post(
urljoin(BASE, "/s/emails/new"),
data={
"email[name]": name,
"email[subject]": subject,
"email[customHtml]": body_html,
"email[fromName]": "FalahOS",
"email[fromAddress]": "hermes@falahos.my",
"email[emailType]": "template",
"email[isPublished]": "1",
"email[_token]": form_token,
"email[buttons][save]": "",
},
headers={
"User-Agent": "hermes-mautic-mcp/1.0",
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token": ajax_csrf,
},
timeout=API_TIMEOUT,
verify=False,
)
if r2.status_code == 200:
print(f" Email created: {name} — '{subject}'")
return True
else:
print(f" Email creation failed for {name}: {r2.status_code}")
return False
# Email definitions (simplified — full HTML in TRIPWIRE_FUNNEL.md)
emails = [
("Day0-Welcome", "Your Islamic Dev Toolkit is ready 🕌", "<p>Welcome! Here's your free toolkit...</p>"),
("Day2-CaseStudy", "How Gading built quran-api (2.5k ⭐)", "<p>Read the story...</p>"),
("Day5-Tripwire", "Islamic UI Kit for $10", "<p>Stop designing from scratch...</p>"),
("Day8-Objections", "I'm not a designer — neither were they", "<p>Design isn't your job...</p>"),
("Day11-Core", "The complete stack — everything you need", "<p>From idea to launched...</p>"),
("Day14-FAQ", "Questions? (24-hour bonus)", "<p>Quick answers...</p>"),
("Day18-Enterprise", "Building for an organization?", "<p>Enterprise licensing...</p>"),
]
for name, subject, body in emails:
create_email(name, subject, body, segment_id or 0)
print("\n--- Setup Complete ---")
print("Next steps:")
print("1. Verify segment and contacts in Mautic UI")
print("2. Verify emails are published")
print("3. Set up automation rules in Mautic UI (email → delay → next email)")
print("4. Run automation.py daily via cron")