Part 1 of 7 · Review request sender series ~11 min read

A review request sender on AWS for a few dollars a month

The best time to ask for a review is a small window that most small businesses miss entirely: too soon and it feels grabby, too late and the customer has forgotten you, and asking someone who had a bad day just hands them a public megaphone. This post walks through the design of a small serverless system that catches that window — one warm, well-timed ask per finished job — while quietly steering unhappy customers to private feedback instead of a one-star.

Key takeaways

  • When a job or order is marked complete, a webhook fires; the system schedules exactly one review request for a sensible later moment.
  • Just before it sends, it reads whatever signal the customer left — a rating, a reply, past sentiment — and grades it happy, unhappy, or unclear.
  • Happy customers get a warm, personalised ask with a direct review link. Anyone who looks unhappy is diverted to a private feedback form.
  • Two small Bedrock calls do the soft work — one grades the signal, one writes the ask. Every real decision is plain Python.
  • Designed on AWS for about $1.90/month at roughly 150 completed jobs. It asks each customer once, honours opt-out, and never nags.

The whole system on one page

Before any code, here’s the shape of what we’re designing. Every small business that finishes work for people is sitting on reviews it will never get — not because customers are unwilling, but because nobody asked at the right moment, in the right words. The valeter drives off, the physio waves the patient out, the boiler engineer packs up the van, and the thought “I should ask them for a review” either never comes or comes three weeks too late. The system below catches the finish of a job and turns it into one warm, well-timed ask — but only for the customers who seem glad, and quietly routes the rest somewhere private.

System architecture: a completed job in from the booking tool, customer records and your team around it, four pieces inside AWS At the top, three external boxes in a row. Far left, “Booking / jobs tool” — the system that fires a completion webhook when a job or order is marked done, and carries any rating or reply the customer leaves. Centre, “Customer records & links” — a sheet with one row per customer (name, contact, past jobs, prior sentiment) mirrored into AWS, plus the public review link and the private feedback-form link the asks point to. Far right, “Your team” — the owner who reads the private feedback and puts a real complaint right. Each connects by an arrow to the AWS account container below. The booking tool sends the completion event in; customer records ground every ask; your team receives escalations. Inside the AWS account are four components. Left, Catch and schedule — receives the webhook, verifies it, guards against asking twice, checks opt-out, captures the signal, and schedules one ask for the right moment. Next, Time the ask — a per-request schedule that fires at a sensible delay inside opening hours and re-checks eligibility before anything is sent. Next, Grade and split — one Bedrock call grades the signal happy or unhappy, and the road forks. Below the middle sits Send — the happy branch gets a warm personalised ask with a direct review link, written by a second Bedrock call; the unhappy branch gets a gentle note pointing to a private feedback form, and a genuine complaint escalates to a person. Arrows flow left to right through catch, time, and grade, with branches down into send and escalate. A note at the bottom reads: it asks each customer once, honours opt-out and quiet hours, and a bad experience is caught in private, never aired as a one-star. Booking / jobs tool completion webhook Records & links review + feedback links Your team reads private feedback job done in grounds complaint with context AWS account Catch & schedule verify, guard once, opt-out, capture the signal Time the ask sensible delay, inside opening hours Grade & split one Bedrock grade, happy or unhappy at time read Send the ask review link, one message Private feedback to a person, not public happy → ask write ask unhappy → divert It asks each customer once, honours opt-out and quiet hours, and a bad experience is caught in private, never a one-star.
Fig 1. Three things outside, four pieces inside AWS. A completed job comes in from the booking tool; Catch & schedule decides an ask is warranted and books it for later, Time the ask fires it inside opening hours, and Grade & split reads the signal — happy customers get a warm ask with a review link, unhappy ones are diverted to private feedback and, if it’s a real complaint, to a person.

What you set up once (the outside)

  • Booking or jobs tool. Whatever already tells you a job is done — a booking system, a field-service app, a shop’s order status, or a simple “mark complete” button. It needs to do one thing: fire a webhook when a job or order is marked complete, carrying the customer, the job, and any rating or reply they left. You point that webhook at one AWS URL and store its key in Secrets Manager. This is the trigger for everything, and it’s covered in Part 2.
  • Customer records and two links. A sheet with one row per customer: name, contact (email or mobile), the jobs they’ve had, and any prior sentiment you’ve captured. You already keep most of this; the system just mirrors it so an ask can open with the customer’s name and know their history. Alongside it sit the two links every ask points to — your public review link (Google, Trustpilot, wherever you want stars) and a private feedback form that comes straight to you — plus a small settings doc for the voice, the delay, the opening hours, and the escalation rules.
  • Your team. The owner or manager who reads the private feedback and fixes a real problem. When an unhappy customer fills in the private form — or a signal is bad enough to skip the ask entirely — they get a message with the customer, the job, the rating, and what was said, so they can ring and put it right before it festers. The system never argues, never apologises on the business’s behalf, and never publishes anything; it opens a quiet conversation and a human handles it.

What runs on every finished job (the inside)

  • Catch and schedule. The booking tool posts a completion event to one Lambda Function URL. The function verifies the signature, guards against making a second request for a job it has already handled, checks the customer against the opt-out list, captures whatever signal is already attached, and schedules one ask for a sensible later moment. Only then does a request exist. This is Part 2.
  • Time the ask. Each request gets its own one-off schedule — a day or so after the job, snapped inside opening hours — so the ask lands when it’s welcome, not the second the van pulls away. At fire time the system re-checks that the customer hasn’t opted out or already been asked, and reschedules rather than sends if the moment has drifted into quiet hours. This is Part 3.
  • Grade and write the ask. The first Bedrock Haiku 4.5 call grades the signal — happy, unhappy, or unclear. For a happy customer, a second call writes one short, warm ask in the business’s voice, and code injects the direct review link. The model grades and phrases; it never decides whether or when to send, or which link to use. This is Parts 4 and 5.
  • Divert the unhappy. Anyone the gate reads as unhappy never sees the public review link. They get a gentle note pointing to a private feedback form, and a genuine complaint is handed to a person to put right — so the public star rating is only ever offered to customers who already seem glad. This is Part 5.

In plain words

It’s Tuesday and Dan finishes a full valet on a customer’s car — Marta, who booked through his online form. He taps “job complete” in the app and drives to the next street. Nothing happens straight away, which is the point. The next afternoon, about the time Marta’s back at her desk and the gleaming car is fresh in her mind, her phone buzzes: “Hi Marta — thanks for having Dan’s Mobile Valeting round yesterday, hope the car’s still looking sharp! If you’ve two minutes, a quick review really helps a small business: dansvaleting.uk/review.” She taps it, leaves five stars, and Dan never had to have the awkward “could you review me?” conversation at the kerb.

Across town a physio clinic finishes a course of treatment for a patient, Tom, who left a lukewarm three-star rating in the booking app on his way out. When his request comes due the next day, the gate reads that signal and does not send him to the public review page. Instead he gets a quieter note: “Hi Tom — we’d love to hear how your treatment went; anything we could have done better? A minute here goes straight to the clinic: meadowphysio.uk/feedback.” His reply — the exercises were never really explained — lands in the practice manager’s inbox, not on Google. She rings him, books a follow-up to walk through them properly, and a three-star drift becomes a fixed problem and a kept patient. One customer earned a public star; the other was caught in private, exactly as designed.

Design rules that shaped every decision

  • One job, one ask. A job marked complete twice, or a retried webhook, still makes a single request — it never double-asks or nags.
  • Protect the public rating. Only customers who look happy are ever pointed at the public review link; the unhappy go to private feedback.
  • Timing is deliberate. The ask waits a sensible delay and lands inside opening hours — never the instant the job ends, never at 2am.
  • The model grades and phrases. It reads the signal and writes the words; whether, when, and which link are all deterministic.
  • Opt-out is sacred. Anyone who has opted out is suppressed for good, checked again the instant before every send.
  • A real complaint reaches a person. Bad feedback isn’t filed and forgotten — it’s handed to the owner with the job and the words attached.

Why this shape

Most small businesses handle reviews one of three ways: they don’t ask at all, they ask everyone the same blunt way at the wrong moment, or they buy a bulk review-request tool that fires the same template at every customer regardless of how the job went. The first leaves a good reputation invisible — happy customers rarely review unprompted. The second feels grabby and gets ignored. And the third is actively dangerous: blast the same “leave us a review” text at everyone and you hand your unhappy customers a public stage, turning private grumbles into permanent one-stars. The gap is a single well-timed, well-judged ask that knows the difference between a glad customer and an unhappy one.

The shape above fills exactly that gap and nothing more. It leans on the booking tool you already use as the trigger, keeps the customer sheet you already maintain as the source of names and history, and adds a small system that asks one good question at the right time — but only of the people who seem pleased. The happy case turns into a tap on a review link with no human involved. The unhappy case is pulled aside quietly, sent somewhere private, and, when it matters, put in front of a person with the whole story already gathered.

The next four posts walk through each piece in turn: how a completed job becomes a scheduled request, how that request gets timed, how the ask gets written, and how unhappy customers get filtered to private feedback. One diagram per post. A cost breakdown and a final engineering reference at the end.

All posts