import os, requests, time
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"}
# 1. Pull negative reviews without replies
negative = []
for stars in [1, 2, 3]:
r = requests.get(f"{TP_BASE}/business-units/{BU_ID}/reviews",
params={"apikey": TP_KEY, "stars": stars, "perPage": 20,
"orderBy": "createdat.desc"})
r.raise_for_status()
for rev in r.json().get("reviews", []):
if not rev.get("companyReply"):
negative.append(rev)
time.sleep(0.2)
print(f"Found {len(negative)} unreplied negative reviews")
# 2. Create or load customer service brand voice
CS_VOICE_SAMPLES = [
"We're sorry to hear about your experience. This isn't the standard we hold ourselves to.",
"Thank you for taking the time to share this feedback. We take every review seriously.",
"We'd love to make this right. Please reach out to support@company.com with your order number.",
"Your satisfaction matters to us, and we're actively working on improving this.",
]
bv = requests.post(f"{MV_BASE}/brand-voices", headers=MV_H, json={
"name": "Customer Service Voice",
"samples": ["\n\n---\n\n".join(CS_VOICE_SAMPLES)],
"preferred_terms": ["we appreciate", "make this right", "your experience matters"],
"avoid_terms": ["unfortunately", "per our policy", "as stated in our terms"],
}).json()
bv_id = bv["id"]
print(f"Brand Voice: {bv_id}")
time.sleep(2)
# 3. Generate responses per review
responses = []
for rev in negative[:10]:
stars = rev.get("stars", 0)
title = rev.get("title", "No title")
text = rev.get("text", "")[:500]
reviewer = rev.get("consumer", {}).get("displayName", "Customer")
review_id = rev.get("id", "")
gen = requests.post(f"{MV_BASE}/generations", headers=MV_H, json={
"brand_voice_id": bv_id,
"prompt": (
f"Write a response to this {stars}-star Trustpilot review.\n\n"
f"Reviewer: {reviewer}\n"
f"Title: {title}\n"
f"Review: {text}\n\n"
f"Rules:\n"
f"- Acknowledge the SPECIFIC issue (not generic)\n"
f"- Offer a concrete next step\n"
f"- Keep under 80 words\n"
f"- Never be defensive\n"
f"- Use the customer's name\n"
f"- End with a way to reach your team"
),
}).json()
response_text = gen.get("output", gen.get("content", gen.get("text", "")))
responses.append({
"review_id": review_id,
"stars": stars,
"title": title,
"response": response_text,
})
print(f"\n[{stars}★] {title}")
print(f" Review: {text[:100]}...")
print(f" Response: {response_text[:200]}")
time.sleep(0.5)
# 4. Post responses (requires OAuth — uncomment in production)
# TP_OAUTH_TOKEN = os.environ["TRUSTPILOT_OAUTH_TOKEN"]
# for resp in responses:
# requests.post(
# f"{TP_BASE}/private/reviews/{resp['review_id']}/reply",
# headers={"Authorization": f"Bearer {TP_OAUTH_TOKEN}", "Content-Type": "application/json"},
# json={"message": resp["response"]})