A testimonial collector on AWS for a few dollars a month
Every small business has happy customers it never quotes. The client who emailed “honestly the best decision we made this year” and got a thank-you and nothing else. The 5-star review that nobody turned into a line on the homepage. The project that wrapped beautifully and was forgotten the next Monday. Those moments are the cheapest marketing a business will ever have — and they evaporate because nobody had a system to catch them, ask nicely, and tidy the reply into something usable. This post walks through the design of a small collector that spots the good moment, asks once, tidies the reply, and never publishes a word without sign-off.
Key takeaways
- Three sources for happy moments: a Drive list, an inbox forwarding lane, and a ratings webhook lane.
- Every customer ends in one of four moves on each tick: wait, first ask, one reminder, or stop.
- Per-moment rules: a 5-star rating asks after 1 day, a finished project after 3, a renewal after 7.
- Asks respect quiet hours and a never-nag cool-down. Anyone who declines is left alone for a year.
- Designed on AWS for about $2/month at typical small-business volume.
The whole system on one page
Before any code, here’s the shape of what we’re designing.
What you set up once (the outside)
- Happy moments. A Google Sheet in a Drive folder, one row per customer worth asking: name, email, the moment that made them a candidate (5-star rating, glowing reply, finished project, renewal), the date of that moment, and a link to where it came from. You can fill it in once and keep adding by hand; new moments can also enter via two other lanes covered in Part 2 — an inbox-forwarding lane (forward a glowing email to a dedicated address and the collector proposes a row for one-tap approval) and a ratings webhook lane (a 5-star rating in your review tool pings a small endpoint and lands as a candidate automatically).
- A rules folder. Two short Google Docs in a Drive folder. The rules doc covers the timing for each moment — how many days after the moment to send the ask, and the cool-down windows. A 5-star rating might ask after 1 day; a finished project after 3; a renewal after 7. The doc also holds the never-nag policy (no second ask within 90 days, no ask at all for a year after someone declines), the quiet hours, and the holiday calendar. The voice doc holds one ask message template per moment — what the email actually says.
- Customers. The happy people themselves. The ask is one short, warm email with a single link to a reply form. The form has a text box for their words and one permission checkbox: “You may use my words on your website and marketing.” No login, no account, no ten-question survey. The whole point is that it takes thirty seconds.
What runs on every tick (the inside)
- The moment intake. Three sources feed the list. The Drive sheet itself is the canonical store. New moments can also be added via the inbox forwarding lane (forward a glowing email to
kudos@your-company.com, the collector uses Bedrock Haiku 4.5 to read the praise and pull out the customer name, email, and a one-line summary, then drops a one-tap approval card in the team’s Slack to confirm before the row is added) and the ratings webhook lane (a 5-star rating in your review tool calls a small Function URL that adds the customer as a candidate). - The collector. Runs once a day at 9am local. Reads the list. For each candidate, computes days-since-the-moment. Checks the never-nag cool-down. Picks one of four moves. Wait: the moment is too fresh, or a cool-down is active — do nothing. First ask: the timing window just opened and the customer hasn’t been asked — send one warm ask with the reply form. One reminder: the first ask got no reply after a set gap — send a single gentle nudge. Stop: the reminder also got no reply, or the customer declined — close the candidate quietly and never ask again this cycle. The collector itself doesn’t call a model on the daily tick — the move logic is plain Python.
- Sign-off. When a customer replies, a Bedrock Haiku 4.5 call tidies their words into a short clean quote — fixing typos and trimming filler, never changing the meaning. The quote is held until two gates pass: the customer ticked the permission box, and a human on the team reviewed the clean quote against the original reply and approved it. Only then does the quote land in an “approved” sheet, ready to drop on a page. A monthly summary writes a short paragraph: how many asks went out, how many replied, how many were approved, and the best new quotes.
In plain words
A client named Dev leaves a 5-star rating on Tuesday. The ratings lane adds him as a candidate. On Wednesday morning (1 day out, per the rule for ratings), the collector sends one short email: “Dev — thank you for the 5 stars. Would you be open to sharing a sentence or two about working with us? Here’s a 30-second form.” Dev is busy and doesn’t reply. Four days later he gets one gentle reminder. This time he clicks, writes “they turned our mess of a launch into something we’re actually proud of, couldnt recommend more,” and ticks the permission box. Bedrock tidies it to “They turned our mess of a launch into something we’re actually proud of — couldn’t recommend them more.” The team lead opens the approval card, sees the clean quote next to Dev’s original, agrees it’s faithful, and taps Approve. The quote lands in the approved sheet with Dev’s name and the date. If Dev had never ticked the box, the quote could never be used — full stop.
The cost of running this is about $2 a month at SMB volume. The cost of not running it is a year of happy moments that turned into nothing — the homepage with no quotes on it, the proposal that needed proof and didn’t have any.
Design rules that shaped every decision
- Ask at the moment of goodwill — right after a 5-star rating or a glowing reply, when the customer actually feels it.
- Four moves, always. Wait, first ask, one reminder, stop. There is no third ask.
- Never nag. A cool-down stops repeat asks; a decline buys a full year of silence.
- Permission is a hard gate. No checkbox, no use — ever, no exceptions.
- A human signs off every quote against the original words before it can be used.
- Every action is logged. Audit a published quote next year and you can see the consent and the approval.
Why this shape
Most teams “collect testimonials” in one of three ways: they mean to and never do, they send a clunky survey that nobody finishes, or they paste a customer’s private email onto the website without asking. The first one is the default and it costs the most — a steady drip of goodwill that turns into nothing. The survey is the false-effort version: it feels like a system but the response rate is near zero because it’s work. And the copy-paste-without-asking version is the dangerous one — it works right up until the customer sees their words used without consent and the goodwill flips to anger.
The setup above asks at the moment the customer is happiest, makes replying a thirty-second job, tidies the reply so a good thought isn’t lost to a typo, and refuses to publish anything without two clear yeses — the customer’s and a teammate’s. It is polite by default and silent the moment someone isn’t interested. The collector is invisible most days; visible only when there’s a genuinely good moment to act on.
The next four posts walk through each piece in turn: how a testimonial request goes out, how a reply becomes a clean quote, how a testimonial gets sign-off, and how an approved one gets published. One diagram per post. A cost breakdown and a final engineering reference at the end.
All posts