● system status: available for new workflows

Project

Agent · review response · live

Review AI Agent

A fully deployed review response agent built for a fictional restaurant, "The Olive & Oak." It takes a Tally review submission, routes it by star rating into three distinct paths, uses AI only where actual reasoning is needed, logs every review to Google Sheets, and sends the right email to the right person automatically. Built with Make.com, Tally, Google Gemini AI, Google Sheets, and Gmail.

← back to projects
Live — Automated 3-Branch Review Response Pipeline
Type: AI Agent + Sentiment Routing + Conditional AI Use Tools: Make.com · Tally · Google Gemini AI · Google Sheets · Gmail Steps: 10 Platform: Tally Form → Make.com Status: Live · Fully Deployed
✓ Fully deployed end-to-end. Every review submitted through the Tally form is validated, routed by rating into one of three branches, handled with the right mix of AI and templated logic for that branch, logged to Google Sheets, and followed up by email — 24/7, zero manual triage.

// overview

A complete review-response agent built on Make.com for a fictional restaurant, "The Olive & Oak." Instead of a single generic auto-reply for every review, this agent treats a 2-star complaint, a 3-star mixed review, and a 5-star rave completely differently — because they need different handling.

A Router splits every submission into three branches by rating. Negative reviews get a Google Gemini AI-drafted, context-aware apology with a discount code — but that draft goes to the restaurant owner for approval first, never straight to the customer. Neutral reviews get a lighter AI-drafted acknowledgment sent directly to the customer. Positive reviews skip AI entirely and get a simple templated thank-you, since there's nothing to reason about.

AI only where it's actually needed. Deterministic logic everywhere else.

// system diagram

TRIGGER 1. Tally — Watch New Responses VALIDATE 2. Filter — email, text, rating 1–5 DECISION 3. Router — by star rating RATING ≤ 2 RATING = 3 RATING ≥ 4 4a. Gemini AI — draft apology 5a. Parse JSON — subject/body 6a. Gmail — alert OWNER (not sent to customer) 7a. Sheets — Needs Owner Review 4b. Gemini AI — light reply 5b. Parse JSON — subject/body 6b. Gmail — direct to customer 7b. Sheets — Auto-Responded 4c. Gmail — templated thank-you (no AI needed) 5c. Sheets — Auto-Thanked LEGEND Negative — AI draft, owner-gated Neutral — AI draft, sent direct Positive — templated, no AI

// proof of work — live scenario

This is the actual Make.com scenario running live. Every module visible here is active and deployed.

Live Make.com scenario — Review AI Agent full pipeline with three branches

// live scenario — Tally trigger → filter → router → negative/neutral/positive branches → Gemini + Parse JSON where needed → Gmail → Sheets

// screenshots

Owner alert email for a negative review, showing the AI-drafted apology awaiting approval
// negative branch — owner alert email with the AI-drafted apology, held for approval before it ever reaches the customer
Direct customer email for a neutral review, warm and light in tone
// neutral branch — AI-drafted reply sent straight to the customer, warm but not over-apologetic
Templated thank-you email for a positive review
// positive branch — simple templated thank-you, no AI call made
Google Sheets log with one row per branch — negative, neutral, positive
// Google Sheets log — one row per branch, sentiment, status, and owner-notified tracked per review

// step breakdown

#StepToolStatus
1 Customer submits a review through the Tally form — name, email, star rating, review text, visit date, branch Tally ✓ Live
2 Filter blocks any submission missing an email or review text, or with a rating outside 1–5 Make.com — Filter ✓ Live
3 Router splits the flow into three branches purely on the numeric rating value Make.com Router ✓ Live
4a Rating ≤ 2: Gemini drafts a specific apology referencing the actual complaint, plus a discount code Google Gemini AI ✓ Live
5a Raw Gemini output parsed into clean subject / body fields Make.com — Parse JSON ✓ Live
6a Draft emailed to the restaurant owner for approval — never sent straight to the customer Gmail — Send an Email ✓ Live
7a Logged to Google Sheets with Status = Needs Owner Review, Owner Notified = Yes Google Sheets — Add a Row ✓ Live
4b Rating = 3: Gemini drafts a lighter, warm acknowledgment — no apology, no discount Google Gemini AI ✓ Live
5b–6b Parsed and sent directly to the customer, since a neutral review carries lower risk than a negative one Parse JSON → Gmail ✓ Live
7b Logged with Status = Auto-Responded, Owner Notified = No Google Sheets — Add a Row ✓ Live
4c–5c Rating ≥ 4: simple templated thank-you sent directly to the customer — no AI call, nothing to reason about Gmail → Google Sheets ✓ Live

// current status

✓ Fully Working

  • Validated input before it ever reaches AI or logging
  • Three-way routing purely on numeric rating
  • Context-aware AI replies, not generic templates
  • Negative drafts gated behind owner approval
  • Every review logged with sentiment and status
  • Zero manual triage of incoming reviews

✓ Full Pipeline Live

  • Tally form trigger — live
  • Validation filter — live
  • All three router branches — live
  • Gemini + Parse JSON on negative and neutral — live
  • Templated positive path — live
  • Sheets logging on all three branches — live

// build story — the nested JSON bug

The routing logic and prompts worked on the first pass. What didn't work — for a while — was getting Gemini's response to actually reach the email. The AI-DRAFTED RESPONSE section of every owner alert kept arriving completely blank, even though every upstream step reported success.

First symptom

Owner alert email arrives with an empty AI response

Gmail sent successfully, the customer details section was fully populated, but the "AI-DRAFTED RESPONSE" section at the bottom was blank every time — despite the Gemini module reporting a completed run.

First wrong turn

Suspected markdown fencing

Gemini's raw output was wrapped in a ```json ... ``` code fence, which looked like the obvious culprit for a broken JSON parse. The system prompt was updated to explicitly forbid markdown fencing and re-tested — the field was still empty.

Root cause found

Parse JSON was pointed at the wrong nesting level

Inspecting the Parse JSON module's own execution output showed the real issue: the JSON string input was mapped to Candidates[].Content — an object containing a parts array and a role, not plain text. The parser was trying to read subject/body out of a wrapper object that didn't contain them at the top level.

Second attempt, still wrong

Drilling into Content.Parts[].Text

The next attempt mapped the field one level deeper, into Candidates[].Content.Parts[].Text — the actual string. This would have worked, but it turned out the Gemini module already exposed a simpler, flattened field.

Fixed

Mapped to the module's flattened Result field instead

The Gemini module output included a top-level Result field — the same JSON string, already unwrapped from the Candidates/Content/Parts structure. Pointing Parse JSON at Result instead of the nested path fixed it immediately: subject and body populated correctly in the owner alert, the customer emails, and the Sheets log on every subsequent test.

// what makes it different

→ Not just one AI reply for every review

  • Three distinct branches, each handled the way that rating actually deserves
  • AI only called where language and reasoning genuinely add value
  • Negative drafts are human-gated, never auto-sent to an upset customer
  • Positive reviews skip the AI call entirely — cheaper and just as effective
  • Validation filter runs before any review reaches AI or storage
  • Every review logged with sentiment, status, and owner-notified tracking

// tools used

Make.com Tally Google Gemini AI Google Sheets Gmail