Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mavera.io/llms.txt

Use this file to discover all available pages before exploring further.

Scenario

Your #customer-support or #help channel captures raw customer frustrations in real time. This job pulls support messages, sends them to Mave for categorization by persona type (enterprise admin, SMB user, developer, end user), then produces a structured pain point map — which personas hurt most, what they complain about, and how to address each in marketing copy. Flow: Slack conversations.history (#support) → Mavera POST /mave/chat (categorize) → Pain point matrix by persona

Code

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 = "C0123SUPPORT"  # Replace with your #support channel ID
DAYS_BACK = 14

# 1. Fetch support channel
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)

tickets = [m for m in messages if m.get("type") == "message" and len(m.get("text","")) > 20]
print(f"Support input: {len(tickets)} (past {DAYS_BACK} days)")

# 2. Build corpus
corpus = "\n\n".join(
    f"[msg-{i}] {m.get('text','')[:400]}"
    for i, m in enumerate(tickets[-80:])
)

# 3. Mave categorization
analysis = requests.post(f"{MV_BASE}/mave/chat", headers=MV_H, json={
    "message": f"Customer support analyst. Categorize these {len(tickets)} support messages by PERSONA TYPE and PAIN POINT.\n\n"
        f"MESSAGES:\n{corpus[:8000]}\n\n"
        "PERSONA TYPES to identify:\n"
        "- Enterprise Admin (manages team accounts, SSO, billing)\n"
        "- SMB User (small team, price-sensitive, self-serve)\n"
        "- Developer (API, integrations, technical issues)\n"
        "- End User (uses the product daily, UX issues)\n\n"
        "For EACH persona:\n"
        "1. Pain points (ranked by frequency)\n"
        "2. Emotional intensity (1-10)\n"
        "3. Representative quotes (exact words from messages)\n"
        "4. Suggested marketing response (how to address in copy)\n"
        "5. Feature request signal (what product change would help)\n\n"
        "End with a PRIORITY MATRIX: persona × pain point × urgency."
}).json()

print(f"\n{'='*60}\nSUPPORT PAIN POINTS BY PERSONA\n{'='*60}")
print(analysis.get("content", "")[:3000])

Example Output

Support messages: 203 (past 14 days)

SUPPORT PAIN POINTS BY PERSONA
============================================================

## Enterprise Admin (34% of messages, intensity: 8/10)
1. SSO configuration failures (12 mentions)
   "We've been trying to set up SAML for two days. Our IT team is
   losing patience."
   → Marketing: Lead with "SSO in 15 minutes" in enterprise collateral
2. Billing confusion with seat-based pricing (9 mentions)
   → Marketing: Transparent pricing page with calculator

## Developer (28% of messages, intensity: 7/10)
1. API rate limit hitting without warning (8 mentions)
   "Getting 429s with no X-RateLimit headers. Can't build retry logic."
   → Marketing: "Developer-first API" only works if DX is actually good

PRIORITY MATRIX:
| Persona | Pain | Urgency | Marketing Action |
|---------|------|---------|-----------------|
| Enterprise Admin | SSO | 9/10 | Case study: "SSO in 15 min" |
| Developer | Rate limits | 8/10 | API docs overhaul |
| End User | Mobile UX | 7/10 | "Mobile-first" feature launch |
| SMB User | Pricing | 6/10 | Pricing page redesign |

Error Handling

Bot tokens need groups:history scope for private channels. User tokens access any channel the user is in.
Support channels can have 1000+ messages/day. Adjust DAYS_BACK to keep corpus manageable. Focus on messages with thread replies (indicates complex issues).
Support messages contain customer names, account IDs, and emails. Consider regex-stripping before sending to Mavera: replace emails with [EMAIL], IDs with [ID].