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 community asks the same questions repeatedly across #help, #general, and #support. This job mines question messages (identified by ? marks and question patterns), clusters them by topic via Mave, then generates polished FAQ entries with your brand voice — ready for docs, help centers, or pinned messages. Flow: Discord GET /channels/{id}/messages → Filter questions → Mavera POST /mave/chat (cluster) → POST /generations (FAQ entries)

Code

import os, requests, time, re

DC_TOKEN = os.environ["DISCORD_BOT_TOKEN"]
DC_BASE = "https://discord.com/api/v10"
DC_H = {"Authorization": f"Bot {DC_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"}

HELP_CHANNELS = ["CHANNEL_ID_1", "CHANNEL_ID_2"]
QUESTION_PATTERNS = re.compile(r"\?|how do|how can|is there|can i|does anyone|why does|where is|what is", re.I)

# 1. Collect questions from channels
all_questions = []
for channel_id in HELP_CHANNELS:
    after = "0"
    while True:
        r = requests.get(f"{DC_BASE}/channels/{channel_id}/messages", headers=DC_H,
            params={"limit": 100, "after": after})
        if r.status_code == 429:
            time.sleep(r.json().get("retry_after", 1))
            continue
        if not r.ok:
            break
        batch = r.json()
        if not batch:
            break
        for m in batch:
            content = m.get("content", "")
            if (not m.get("author",{}).get("bot",False)
                and QUESTION_PATTERNS.search(content)
                and 15 < len(content) < 500):
                all_questions.append(content)
        after = batch[0]["id"]
        if len(all_questions) >= 200:
            break
        time.sleep(0.5)

print(f"Collected {len(all_questions)} questions")

# 2. Cluster via Mave
clustering = requests.post(f"{MV_BASE}/mave/chat", headers=MV_H, json={
    "message": f"FAQ analyst. Cluster these {len(all_questions)} community questions into 10-15 FAQ topics.\n\n"
        + "\n".join(f"- {q[:200]}" for q in all_questions[:100])
        + "\n\nFor each cluster:\n- Topic name (clear, concise)\n- Frequency (how many questions)\n- Representative question (best phrased example)\n- Key details needed in the answer\n\nRank by frequency."
}).json()
clusters_text = clustering.get("content", "")
print(f"\nClusters:\n{clusters_text[:1500]}")

# 3. Generate FAQ entries
faq = requests.post(f"{MV_BASE}/generations", headers=MV_H, json={
    "prompt": f"Generate a complete FAQ page from these clustered community questions.\n\n"
        f"CLUSTERS:\n{clusters_text[:4000]}\n\n"
        "For each FAQ entry:\n"
        "- Question (phrased clearly, search-friendly)\n"
        "- Answer (2-4 sentences, helpful, specific)\n"
        "- Related: link suggestions to other FAQ entries\n\n"
        "Tone: friendly, direct, knowledgeable. Use 'you' not 'the user'.\n"
        "Format as markdown with ## headers per question.",
}).json()

print(f"\n{'='*60}\nGENERATED FAQ ({len(all_questions)} questions → clustered)\n{'='*60}")
print(faq.get("output", faq.get("content", ""))[:2500])

Example Output

Collected 187 questions

Clusters:
1. Pricing & Plans (32 questions) — "What's the difference between free and pro?"
2. API Rate Limits (24 questions) — "How do I increase my API rate limit?"
3. Mobile App Issues (21 questions) — "Why does the app crash on Android?"
4. SSO / Team Setup (18 questions) — "How do I set up SSO for my org?"
5. Integrations (15 questions) — "Can I connect this to Zapier?"

GENERATED FAQ
============================================================

## What's the difference between the Free and Pro plans?

Free gives you up to 5 team members, 1,000 API calls/day, and access
to core features. Pro unlocks unlimited team members, 50,000 API
calls/day, SSO, custom dashboards, and priority support. You can
compare plans side-by-side on our [pricing page](/pricing).

**Related:** How do I upgrade? | What happens when I hit the API limit?

## How do I increase my API rate limit?

Your rate limit depends on your plan — Free is 100 req/min, Pro is
1,000 req/min. If you need more, contact sales for an Enterprise plan
with custom limits. In the meantime, implement client-side caching
and exponential backoff to maximize your current allocation.

Error Handling

The regex pattern catches most questions but may miss imperative-style questions (“Tell me how to…”). Add patterns for your community’s question style.
Community channels contain memes, off-topic chat, and reactions. The length filter (15-500 chars) removes most noise. For cleaner results, only process messages from specific roles.
Regenerate monthly. Pin the latest FAQ in your Discord channels and update help center docs via webhook.