Skip to main content
Back to Guides
Lead ManagementBeginnerPackage Available

Review & Referral Request System - Complete Implementation Guide

Automatically request reviews on Google/Yelp after sales, ask for referrals, and re-engage past customers for repeat business.

9 min read
Implementation: 1-2 weeks
reviewsreferralscustomer-retentionGoogle-Reviewsreputation

Technology Stack

CRM PlatformGoHighLevel
Automationn8n
MessagingTwilio SMS, SendGrid

Expected Results

3-5x increase in review volume
15-25% of customers provide referrals
20% increase in repeat purchases
Positive ROI within 2 weeks

Review & Referral Request System

Reviews and referrals are your most valuable marketing assets. This system automates the ask so you never miss an opportunity to grow your reputation and get new customers.

Why Automation Matters

Manual follow-up fails because:

  • Inconsistency - Some customers get asked, others don't
  • Timing - You forget or reach out too late
  • Awkwardness - Asking in person feels weird
  • Scale - Can't personally ask every customer

The right ask at the right time makes all the difference.

System Architecture

┌─────────────────────────────────────────────────────────────┐
│               Customer Transaction Completed                 │
│     Sale closed | Service delivered | Invoice paid          │
└───────────────────────┬─────────────────────────────────────┘
                        │
                        ↓
┌─────────────────────────────────────────────────────────────┐
│              Satisfaction Check (Day 1-3)                    │
│         "How was your experience?"                           │
└───────────────────────┬─────────────────────────────────────┘
                        │
              ┌─────────┴─────────┐
              ↓                   ↓
┌──────────────────┐    ┌──────────────────┐
│ Happy (Score 4-5)│    │ Unhappy (1-3)    │
└────────┬─────────┘    └────────┬─────────┘
         │                       │
         ↓                       ↓
┌──────────────────┐    ┌──────────────────┐
│ Review Request   │    │ Recovery         │
│ (Day 3-7)        │    │ Workflow         │
│ → Google         │    │ → Manager Alert  │
│ → Yelp           │    │ → Fix Issue      │
│ → Facebook       │    │ → Follow-up      │
└────────┬─────────┘    └──────────────────┘
         │
         ↓
┌──────────────────┐
│ Referral Request │
│ (Day 7-14)       │
│ → Ask for names  │
│ → Incentive offer│
└────────┬─────────┘
         │
         ↓
┌──────────────────┐
│ Re-engagement    │
│ (Ongoing)        │
│ → Seasonal       │
│ → Anniversary    │
│ → New services   │
└──────────────────┘

Step-by-Step Implementation

Step 1: Trigger Setup

Transaction Complete Trigger:

// Option 1: GHL Pipeline Stage Change
const triggers = {
  pipeline: "sales_pipeline",
  stage: "completed",
  conditions: {
    hasEmail: true,
    hasPhone: true,
    transactionValue: { $gt: 0 },
  },
};

// Option 2: Payment Received
const paymentTrigger = {
  event: "invoice_paid",
  delay: "24_hours", // Wait for delivery/service
};

// Option 3: Service Completed (manual or from field software)
const serviceCompleteTrigger = {
  event: "service_completed",
  customField: "service_date",
};

Step 2: Satisfaction Check

Initial Check Message:

const satisfactionCheck = {
  timing: "day_1_to_3", // After transaction
  channel: "sms",
  message: `Hi {{firstName}}! This is {{companyName}}. How was your experience with us? Reply with a number 1-5 (5 being excellent).`,

  followUp: {
    noResponse: {
      timing: "day_2",
      message: `Hi {{firstName}}, just checking in - we'd love to hear how things went! Reply 1-5.`,
    },
  },
};

// Process response
const processSatisfactionScore = async (contactId, score) => {
  const numScore = parseInt(score);

  if (numScore >= 4) {
    // Happy customer - proceed to review request
    await addTag(contactId, "satisfied_customer");
    await scheduleReviewRequest(contactId, "day_3");

    // Acknowledge
    await sendSMS(
      contactId,
      `Thank you so much! We're thrilled you had a great experience. 😊`,
    );
  } else {
    // Unhappy customer - recovery workflow
    await addTag(contactId, "needs_recovery");
    await triggerRecoveryWorkflow(contactId, numScore);

    // Acknowledge
    await sendSMS(
      contactId,
      `We're sorry to hear that. A manager will reach out shortly to make this right.`,
    );
  }
};

Step 3: Review Request Sequence

Request Messages:

const reviewRequestSequence = {
  day3: {
    channel: "sms",
    message: `{{firstName}}, glad you had a great experience! Would you mind leaving us a quick Google review? It really helps small businesses like ours: {{googleReviewLink}}`,
  },

  day5: {
    channel: "email",
    subject: `Quick favor, {{firstName}}?`,
    body: `Hi {{firstName}},

Thanks again for choosing {{companyName}}!

If you have 2 minutes, we'd really appreciate a Google review. It helps other customers find us and lets our team know they're doing great work.

👉 Leave a review: {{googleReviewLink}}

Thanks so much!
{{senderName}}`,
  },

  day7: {
    channel: "sms",
    condition: "no_review_yet",
    message: `Last reminder, {{firstName}}! If you haven't had a chance to leave a review, here's the link again: {{googleReviewLink}} - Thanks!`,
  },
};

Smart Review Routing:

const getReviewLink = (customer) => {
  // Route to platform based on customer source/preference
  const reviewLinks = {
    google: `https://g.page/r/YOUR_PLACE_ID/review`,
    yelp: `https://www.yelp.com/writeareview/biz/YOUR_BIZ_ID`,
    facebook: `https://www.facebook.com/YOUR_PAGE/reviews`,
  };

  // Default to Google (most valuable for SEO)
  let platform = "google";

  // If they found you on Yelp, ask for Yelp review
  if (customer.source === "yelp") {
    platform = "yelp";
  }

  // Rotate to spread reviews across platforms
  if (customer.reviewCount % 5 === 0) {
    platform = "facebook";
  }

  return reviewLinks[platform];
};

Step 4: Review Tracking

// Monitor new reviews via Google API
const checkForNewReviews = async () => {
  const response = await fetch(
    `https://mybusiness.googleapis.com/v4/accounts/${ACCOUNT_ID}/locations/${LOCATION_ID}/reviews`,
    { headers: { Authorization: `Bearer ${GOOGLE_ACCESS_TOKEN}` } },
  );

  const reviews = await response.json();

  // Find new reviews since last check
  const newReviews = reviews.filter(
    (r) => new Date(r.createTime) > lastCheckTime,
  );

  for (const review of newReviews) {
    // Match to customer if possible
    const customer = await matchReviewToCustomer(review);

    if (customer) {
      await updateContact(customer.id, {
        left_review: true,
        review_platform: "google",
        review_rating: review.starRating,
        review_date: review.createTime,
      });

      // Remove from review request sequence
      await removeFromSequence(customer.id, "review_request");
    }

    // Respond to review if negative
    if (review.starRating <= 3) {
      await alertManager(review);
    }
  }
};

Step 5: Referral Request

Referral Ask Sequence:

const referralSequence = {
  timing: "day_7_to_14", // After review request
  condition: "satisfied_customer",

  sms: {
    message: `{{firstName}}, since you had a great experience with us, do you know anyone else who could use our services? We'd love to help them too!`,
  },

  email: {
    subject: `Know someone who needs {{serviceType}}?`,
    body: `Hi {{firstName}},

We loved working with you on {{projectDescription}}!

If you know anyone else who could use our help, we'd really appreciate the referral. As a thank you, we offer:

🎁 {{referralIncentive}}

Just reply with their name and number, or forward them this email.

Thanks for thinking of us!
{{senderName}}`,
  },
};

// Referral incentive options
const referralIncentives = {
  discount: "$50 off your next service",
  giftCard: "$25 Amazon gift card",
  donation: "We'll donate $25 to your favorite charity",
  service: "Free inspection/consultation",
};

Process Referral Response:

const processReferralResponse = async (fromContactId, message) => {
  // Try to extract referral info
  const referralInfo = await extractReferralInfo(message);

  if (referralInfo.name || referralInfo.phone) {
    // Create new lead
    const newLead = await createContact({
      firstName: referralInfo.name?.split(" ")[0],
      lastName: referralInfo.name?.split(" ").slice(1).join(" "),
      phone: referralInfo.phone,
      email: referralInfo.email,
      source: "referral",
      referredBy: fromContactId,
      tags: ["referral_lead"],
    });

    // Thank the referrer
    await sendSMS(
      fromContactId,
      `Thanks so much for the referral! We'll take great care of them. Don't forget - you get {{referralIncentive}} when they become a customer!`,
    );

    // Reach out to the referral
    await triggerWorkflow("referral_outreach", newLead.id);

    // Track for referral credit
    await updateContact(fromContactId, {
      referrals_given: (contact.referrals_given || 0) + 1,
      pending_referral_credit: true,
    });
  } else {
    // Couldn't extract info - ask for clarification
    await sendSMS(
      fromContactId,
      `Thanks! Could you send me their name and phone number so I can reach out?`,
    );
  }
};

// Extract referral info using AI
const extractReferralInfo = async (message) => {
  const response = await openai.chat.completions.create({
    model: "gpt-4o",
    messages: [
      {
        role: "system",
        content:
          "Extract referral information from this message. Return JSON with: name, phone, email, relationship. Return null for missing fields.",
      },
      {
        role: "user",
        content: message,
      },
    ],
    response_format: { type: "json_object" },
  });

  return JSON.parse(response.choices[0].message.content);
};

Step 6: Re-engagement Campaigns

Seasonal Re-engagement:

const seasonalCampaigns = {
  spring: {
    months: [3, 4, 5],
    services: ["HVAC tune-up", "landscaping", "pest control"],
    message: `Hey {{firstName}}! Spring is here - time for {{seasonalService}}. As a past customer, you get {{discount}}. Want to schedule?`,
  },
  summer: {
    months: [6, 7, 8],
    services: ["AC maintenance", "pool service", "roofing inspection"],
    message: `{{firstName}}, summer's heating up! Time for {{seasonalService}}. Book this week and get {{discount}}.`,
  },
  fall: {
    months: [9, 10, 11],
    services: ["furnace check", "gutter cleaning", "winterization"],
    message: `Hey {{firstName}}, getting ready for winter? Schedule your {{seasonalService}} now before the rush!`,
  },
  winter: {
    months: [12, 1, 2],
    services: ["heating repair", "insulation", "snow removal"],
    message: `{{firstName}}, staying warm? Let us know if you need any {{seasonalService}} this winter!`,
  },
};

// Run seasonal campaigns
const runSeasonalCampaign = async () => {
  const currentMonth = new Date().getMonth() + 1;
  const season = Object.entries(seasonalCampaigns).find(([_, config]) =>
    config.months.includes(currentMonth),
  );

  if (!season) return;

  const [seasonName, config] = season;

  // Find past customers who used related services
  const eligibleCustomers = await findCustomers({
    status: "customer",
    serviceType: { $in: config.services },
    lastContact: { $lt: daysAgo(90) }, // Haven't heard from us in 90 days
    notInCampaign: "seasonal_reengagement",
  });

  for (const customer of eligibleCustomers) {
    await addToCampaign(customer.id, "seasonal_reengagement", {
      season: seasonName,
      service: customer.serviceType,
    });
  }
};

Anniversary Re-engagement:

const anniversaryReengagement = async () => {
  // Find customers whose service was 1 year ago
  const anniversaryCustomers = await findCustomers({
    serviceDate: daysAgo(365, 7), // 1 year ago, +/- 7 days
  });

  for (const customer of anniversaryCustomers) {
    await sendSMS(
      customer.phone,
      `Hey {{firstName}}! It's been a year since we {{serviceType}} for you. Time for an annual checkup? Reply YES and I'll get you on the schedule.`,
    );
  }
};

Negative Review Recovery

const recoveryWorkflow = {
  trigger: "satisfaction_score_low",

  steps: [
    {
      timing: "immediate",
      action: "alert_manager",
      message: `🚨 Unhappy customer alert: {{firstName}} rated us {{score}}/5 for {{serviceType}}. Contact: {{phone}}`,
    },
    {
      timing: "immediate",
      action: "send_customer",
      channel: "sms",
      message: `{{firstName}}, we're really sorry to hear you weren't satisfied. Our manager {{managerName}} will call you within the hour to make this right.`,
    },
    {
      timing: "1_hour",
      action: "manager_call_reminder",
      message: `Reminder: Call {{firstName}} at {{phone}} about their service issue.`,
    },
    {
      timing: "24_hours",
      condition: "issue_not_resolved",
      action: "escalate",
      message: `{{firstName}}'s issue hasn't been resolved. Escalating to {{ownerName}}.`,
    },
  ],
};

Metrics to Track

MetricTargetHow to Improve
Satisfaction Response Rate> 50%Better timing, incentives
Review Conversion> 20%Simpler ask, direct links
Average Rating> 4.5Service quality + recovery
Referral Rate> 15%Better incentives, right timing
Repeat Customer Rate> 30%Stay in touch, add value

Ready to grow your reviews and referrals? Get the implementation package or let us set this up for you.

Get the Complete Implementation Package

Includes n8n workflow templates, TypeScript integrations, message templates, and step-by-step setup guides. Everything you need to deploy this system.

Request Access

Ready to Transform Your Lead Generation?

Let's discuss how we can implement this system for your business with expert optimization.

Book Strategy Call