> ## 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.

# Response Template Generation

> Cluster review themes across locations and generate branded response templates for each theme

## Scenario

Your team responds to dozens of reviews weekly across locations. Instead of writing each from scratch, you identify common review themes, then generate branded response templates for each theme type. Staff select the matching template and personalize — consistent voice, faster response times.

**Flow:** Aggregate review themes across locations → Mavera `POST /mave/chat` (theme clustering) → `POST /generations` (per-theme templates) → Template library

## Code

<CodeGroup>
  ```python Python theme={"dark"}
  import os, requests, time

  GOOG = os.environ["GOOGLE_ACCESS_TOKEN"]
  ACCT = os.environ["GOOGLE_ACCOUNT_ID"]
  MV = os.environ["MAVERA_API_KEY"]
  GB_BASE = "https://mybusiness.googleapis.com/v4"
  MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
  GB_H = {"Authorization": f"Bearer {GOOG}"}
  STAR_MAP = {"ONE": 1, "TWO": 2, "THREE": 3, "FOUR": 4, "FIVE": 5}

  # 1. Aggregate reviews from all locations
  all_reviews = []
  locations = requests.get(f"{GB_BASE}/{ACCT}/locations",
      headers=GB_H, params={"pageSize": 50}).json().get("locations", [])

  for loc in locations[:10]:
      loc_id = loc.get("name", "")
      loc_name = loc.get("locationName", "Unknown")
      r = requests.get(f"{GB_BASE}/{loc_id}/reviews",
          headers=GB_H, params={"pageSize": 30})
      if r.status_code != 200:
          continue
      for rev in r.json().get("reviews", []):
          stars = STAR_MAP.get(rev.get("starRating"), 3)
          comment = rev.get("comment", "")
          if comment:
              all_reviews.append({"stars": stars, "text": comment[:300], "location": loc_name})
      time.sleep(0.5)

  # 2. Cluster into themes with Mave
  review_block = "\n".join(
      f"[{r['stars']}★ @ {r['location']}] {r['text'][:200]}"
      for r in all_reviews[:40]
  )

  themes = requests.post("https://app.mavera.io/api/v1/mave/chat", headers=MV_H,
      json={"message": f"""Cluster these {len(all_reviews)} Google Business reviews into theme categories.

  {review_block}

  For each theme:
  - Category name
  - Star range (which star levels this appears in)
  - Frequency
  - Representative quote
  - Emotional tone of the reviewer

  Return the top 8 themes."""}).json()

  print("=== Review Theme Clusters ===")
  print(themes.get("content", "")[:800])

  # 3. Generate response templates per theme
  gen = requests.post("https://app.mavera.io/api/v1/generations", headers=MV_H,
      json={"prompt": f"""Generate review response templates based on these review themes:

  {themes.get('content','')[:1200]}

  For EACH theme, generate TWO templates:
  1. One for 1-2 star reviews (empathetic, solution-oriented)
  2. One for 4-5 star reviews (grateful, relationship-building)

  Rules:
  - Include [CUSTOMER_NAME] and [LOCATION] placeholders
  - Under 80 words each
  - Never defensive or corporate
  - End with a specific next step or invitation
  - Each template should feel warm and human"""}).json()

  print("\n=== Response Templates ===")
  print(gen.get("output", gen.get("content", gen.get("text", "")))[:2000])
  ```

  ```javascript JavaScript theme={"dark"}
  const GOOG = process.env.GOOGLE_ACCESS_TOKEN;
  const ACCT = process.env.GOOGLE_ACCOUNT_ID;
  const MV = process.env.MAVERA_API_KEY;
  const GB_BASE = "https://mybusiness.googleapis.com/v4";
  const MV_H = { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" };
  const GB_H = { Authorization: `Bearer ${GOOG}` };
  const STAR_MAP = { ONE: 1, TWO: 2, THREE: 3, FOUR: 4, FIVE: 5 };

  // 1. Aggregate reviews
  const allReviews = [];
  const locations = (await fetch(`${GB_BASE}/${ACCT}/locations?pageSize=50`, { headers: GB_H })
    .then((r) => r.json())).locations || [];

  for (const loc of locations.slice(0, 10)) {
    const res = await fetch(`${GB_BASE}/${loc.name}/reviews?pageSize=30`, { headers: GB_H });
    if (!res.ok) continue;
    for (const rev of (await res.json()).reviews || []) {
      if (rev.comment) allReviews.push({
        stars: STAR_MAP[rev.starRating] || 3, text: rev.comment.slice(0, 300),
        location: loc.locationName || "Unknown",
      });
    }
    await new Promise((r) => setTimeout(r, 500));
  }

  // 2. Themes
  const reviewBlock = allReviews.slice(0, 40)
    .map((r) => `[${r.stars}★ @ ${r.location}] ${r.text.slice(0, 200)}`).join("\n");
  const themes = await fetch("https://app.mavera.io/api/v1/mave/chat", {
    method: "POST", headers: MV_H,
    body: JSON.stringify({ message: `Cluster themes from ${allReviews.length} reviews:\n\n${reviewBlock}\n\nTop 8 themes with name, star range, frequency, quote.` }),
  }).then((r) => r.json());

  // 3. Templates
  const gen = await fetch("https://app.mavera.io/api/v1/generations", {
    method: "POST", headers: MV_H,
    body: JSON.stringify({
      prompt: `Templates for themes:\n\n${(themes.content || "").slice(0, 1200)}\n\nPer theme: 1) 1-2★ template (empathetic) 2) 4-5★ template (grateful). Under 80 words. [CUSTOMER_NAME] and [LOCATION] placeholders. Warm and human.`,
    }),
  }).then((r) => r.json());

  console.log("=== Templates ===");
  console.log(gen.output || gen.content || gen.text || "");
  ```
</CodeGroup>

## Example Output

```text theme={"dark"}
=== Response Templates ===

## Theme: Service Speed
### 1-2★ Template
Hi [CUSTOMER_NAME], I'm sorry about the wait at our [LOCATION] store.
That's not the experience we want for you. We're adding staff during peak
hours this month to fix this. Next time you visit, ask for a manager —
I'd love to make it up to you with a complimentary drink.

### 4-5★ Template
[CUSTOMER_NAME], so glad our [LOCATION] team got you in and out quickly!
We know your time matters. Thanks for the kind words — we'll make sure
the team sees this. See you next time!

## Theme: Product Quality
### 1-2★ Template
Hi [CUSTOMER_NAME], that's not the quality standard we hold at [LOCATION].
Could you email us at feedback@company.com with your order details?
We'll replace it and investigate what went wrong. You deserve better.

### 4-5★ Template
Thank you, [CUSTOMER_NAME]! Our [LOCATION] team takes real pride in
every order. Comments like yours are exactly why they do what they do.
We hope to see you again soon!
```

## Error Handling

<AccordionGroup>
  <Accordion title="Reply posting via API">Google requires the Account Management API with OAuth for posting replies. Use `PATCH /accounts/{id}/locations/{id}/reviews/{id}/reply`.</Accordion>
  <Accordion title="Template personalization">Templates with `[CUSTOMER_NAME]` and `[LOCATION]` must be filled before posting. Build a simple UI or spreadsheet workflow for staff to personalize and approve.</Accordion>
  <Accordion title="Review response guidelines">Google's review policy prohibits incentivizing reviews or including promotional content in replies. Keep templates focused on acknowledgment and resolution.</Accordion>
</AccordionGroup>
