import os, requests, time
from collections import defaultdict
TP_KEY = os.environ["TRUSTPILOT_API_KEY"]
MV = os.environ["MAVERA_API_KEY"]
BU_ID = os.environ["TRUSTPILOT_BU_ID"]
TP_BASE = "https://api.trustpilot.com/v1"
MV_BASE = "https://app.mavera.io/api/v1"
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
TIERS = {
"Detractor (1-2★)": [1, 2],
"Neutral (3★)": [3],
"Promoter (4-5★)": [4, 5],
}
# 1. Pull reviews per tier
tier_reviews = {}
for tier_name, star_list in TIERS.items():
all_revs = []
for stars in star_list:
r = requests.get(f"{TP_BASE}/business-units/{BU_ID}/reviews",
params={"apikey": TP_KEY, "stars": stars, "perPage": 50,
"orderBy": "createdat.desc"})
r.raise_for_status()
all_revs.extend(r.json().get("reviews", []))
time.sleep(0.2)
tier_reviews[tier_name] = all_revs
# 2. Extract themes per tier
tier_themes = {}
for tier_name, revs in tier_reviews.items():
texts = [r.get("text", "")[:300] for r in revs if r.get("text")]
themes = defaultdict(int)
keywords = {"shipping": 0, "quality": 0, "support": 0, "price": 0, "easy": 0,
"fast": 0, "broken": 0, "refund": 0, "love": 0, "recommend": 0}
for t in texts:
lower = t.lower()
for kw in keywords:
if kw in lower:
themes[kw] += 1
tier_themes[tier_name] = {"texts": texts, "themes": dict(themes), "count": len(revs)}
# 3. Create personas per tier
persona_ids = []
for tier_name, data in tier_themes.items():
top_themes = sorted(data["themes"].items(), key=lambda x: -x[1])[:5]
theme_str = ", ".join(f"{k} ({v})" for k, v in top_themes)
sample_texts = data["texts"][:3]
p = requests.post(f"{MV_BASE}/personas", headers=MV_H, json={
"name": f"TP: {tier_name}",
"description": (
f"Trustpilot reviewer in {tier_name} segment. N={data['count']}. "
f"Key themes: {theme_str}. "
f"Sample: \"{sample_texts[0][:100]}...\""
),
"psychographic": {
"satisfaction_tier": tier_name,
"top_themes": [k for k, _ in top_themes],
},
}).json()
persona_ids.append({"id": p["id"], "tier": tier_name, "n": data["count"]})
print(f"Persona: {p['id']} — {tier_name} ({data['count']} reviews)")
time.sleep(0.3)
# 4. Focus Group: "What moves you to 5 stars?"
fg = requests.post(f"{MV_BASE}/focus-groups", headers=MV_H, json={
"name": "TrustScore Improvement Strategy",
"persona_ids": [p["id"] for p in persona_ids],
"questions": [
"What would it take for you to give this company a 5-star review?",
"What's the #1 thing this company does well that they should never change?",
"If you could fix one thing about your experience, what would it be?",
{"type": "likert", "text": "How likely are you to update your review if the company resolves your issue? (1-5)", "scale": 5},
"Describe your ideal post-purchase experience in 2 sentences.",
],
"responses_per_persona": 3,
}).json()
for _ in range(20):
time.sleep(5)
data = requests.get(f"{MV_BASE}/focus-groups/{fg['id']}", headers=MV_H).json()
if data.get("status") == "completed":
break
for resp in data.get("responses", []):
tier = next((p["tier"] for p in persona_ids if p["id"] == resp.get("persona_id")), "?")
print(f"\n[{tier}] {resp.get('question','')[:60]}")
print(f" → {resp.get('answer','')[:250]}")