import os, requests, time
SL_TOKEN = os.environ["SLACK_BOT_TOKEN"]
SL_BASE = "https://slack.com/api"
SL_H = {"Authorization": f"Bearer {SL_TOKEN}"}
MV = os.environ["MAVERA_API_KEY"]
MV_BASE = "https://app.mavera.io/api/v1"
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
CHANNEL_ID = "C0123FEEDBACK"
DAYS_BACK = 60
# 1. Fetch feedback messages
oldest = str(int(time.time()) - DAYS_BACK * 86400)
messages = []
cursor = None
while True:
params = {"channel": CHANNEL_ID, "limit": 200, "oldest": oldest}
if cursor:
params["cursor"] = cursor
r = requests.get(f"{SL_BASE}/conversations.history", headers=SL_H, params=params)
data = r.json()
if not data.get("ok"):
break
messages.extend(data.get("messages", []))
cursor = data.get("response_metadata", {}).get("next_cursor")
if not cursor:
break
time.sleep(1)
feedback = [m for m in messages if m.get("type") == "message"
and not m.get("bot_id") and len(m.get("text","")) > 15]
print(f"Feedback input: {len(feedback)}")
# 2. Extract themes via Mave
corpus = "\n".join(f"- {m.get('text','')[:300]}" for m in feedback[-60:])
themes = requests.post(f"{MV_BASE}/mave/chat", headers=MV_H, json={
"message": f"Product analyst. Extract the top 6 feature themes from {len(feedback)} feedback messages.\n\n"
f"{corpus[:6000]}\n\n"
"For each theme: Name (3-5 words), frequency (count of mentions), "
"representative quote, user impact (1-10).\n"
"Return as a numbered list."
}).json()
themes_text = themes.get("content", "")
print(f"\nThemes:\n{themes_text[:1000]}")
# 3. Create user-segment personas
SEGMENTS = [
{"name": "Power User (Daily)", "desc": "Uses the product 4+ hours/day. Has workarounds for missing features. Values efficiency and keyboard shortcuts."},
{"name": "Casual User (Weekly)", "desc": "Uses the product 2-3 times per week. Needs simplicity. Gets frustrated by complexity. Values intuitive UX."},
{"name": "Team Admin", "desc": "Manages 20+ team members on the platform. Cares about permissions, reporting, onboarding new users. Values admin controls."},
{"name": "New User (< 30 days)", "desc": "Just started using the product. Still learning. Compares to previous tools. Values onboarding and documentation."},
]
persona_ids = []
for seg in SEGMENTS:
p = requests.post(f"{MV_BASE}/personas", headers=MV_H, json={
"name": f"Feedback: {seg['name']}", "description": seg["desc"],
}).json()
persona_ids.append(p["id"])
time.sleep(0.3)
# 4. Focus Group to validate themes
fg = requests.post(f"{MV_BASE}/focus-groups", headers=MV_H, json={
"name": "Product Feedback Validation",
"persona_ids": persona_ids,
"questions": [
f"Here are the top feature requests from our users:\n{themes_text[:1500]}\n\nWhich of these would make the biggest difference for YOU?",
"Is there a feature NOT on this list that you need more urgently?",
"If we could only ship ONE of these this quarter, which should it be and why?",
"Would any of these features make you upgrade to a higher plan?",
],
"responses_per_persona": 2,
}).json()
for _ in range(25):
time.sleep(5)
data = requests.get(f"{MV_BASE}/focus-groups/{fg['id']}", headers=MV_H).json()
if data.get("status") == "completed":
break
print(f"\n{'='*60}\nFOCUS GROUP VALIDATION\n{'='*60}")
for resp in data.get("responses", []):
idx = persona_ids.index(resp.get("persona_id")) if resp.get("persona_id") in persona_ids else -1
name = SEGMENTS[idx]["name"] if 0 <= idx < len(SEGMENTS) else "Unknown"
print(f"\n[{name}] Q: {resp.get('question','')[:80]}")
print(f" A: {resp.get('answer','')[:350]}")