Series · 7 parts Published May 14, 2026

Testimonial collector

A serverless collector that asks happy customers for a testimonial at the right moment, collects their reply, tidies it into a clean quote with their permission, and files approved ones ready to use on your site. It never nags, and it never publishes a word without the customer’s yes and your sign-off. Seven posts on the same system — one diagram at a time — with an engineering reference at the end.

  1. 01

    A testimonial collector on AWS for a few dollars a month

    The whole system on one page — a moment finder, a tidier, and a publishing gate, plus the two permissions every testimonial must clear before it goes live.

  2. 02

    How a testimonial request goes out

    Three sources feed the moment finder — new 5-star reviews, glowing email replies, and closed jobs marked happy — and one short ask goes out with a one-tap link, at most one gentle follow-up, then it stops.

  3. 03

    How a testimonial reply becomes a quote

    The customer’s reply comes in, Haiku 4.5 trims it into a short clean quote without changing the meaning, and the exact quote is shown back to the customer to confirm. The model never invents words.

  4. 04

    How a testimonial gets sign-off

    Two gates, both required: the customer ticks a permission box and picks how to be credited, then you approve from a card with Approve, Edit, or Skip. No yes, no approval — no publish.

  5. 05

    How a testimonial gets published

    An approved testimonial is written to a clean JSON file in S3 that your site reads, with credit set exactly how the customer chose. A customer can withdraw later and it disappears on the next build. Every change is logged.

  6. 06

    What the testimonial collector costs

    Pennies a month at SMB volume. The collector scans once a day and only fires Bedrock once per reply to tidy it into a quote.

  7. 07

    Engineering reference: the testimonial collector architecture

    Same system, drawn purely for engineers. Service names, resource identifiers, region, Bedrock model IDs, Lambda inventory, IAM scopes, the SES inbound rule set, EventBridge Scheduler config, and the DynamoDB schemas.

What is a testimonial collector?
A small serverless system that asks happy customers for a testimonial at the right moment — right after a 5-star review, a glowing reply, or a smooth job close — collects their reply, tidies it into a clean quote with their permission, and files approved ones ready to use on your site. It never nags, and it never publishes anything without the customer ticking a box that says yes.
How much does it cost to run?
About $1.40/month at typical small-business volume (around 60 happy moments a month). The fixed cost is essentially zero. The variable cost is dominated by the daily check that scans for happy moments and the small AI call that tidies each reply into a quote; everything else is fractions of a cent. At 600 happy moments a month the bill lands around $9.
Which AWS services does it use?
Lambda (Python 3.14, arm64) with Function URLs for the customer permission page and the owner approve buttons, EventBridge Scheduler for the daily scan and deferred follow-ups, DynamoDB on-demand, S3 (with versioning), SES inbound + outbound, Secrets Manager, CloudWatch Logs (7-day retention), AWS Budgets, and Bedrock (Claude Haiku 4.5 via Global cross-Region inference) to tidy each reply into a clean quote. No API Gateway, no NAT Gateway, no always-on compute, no Knowledge Base.
Where do the testimonials live?
In a Google Sheet in a Drive folder. One row per request with the customer name, source moment, contact, raw reply, tidied quote, permission state, and publish state. A small drive-sync Lambda mirrors the sheet to S3 every 15 minutes; the collector reads from S3 to keep Drive API calls predictable and to get S3 versioning for free.
Does the collector use AI?
Sparingly. The daily scan that finds happy moments uses no AI — it’s plain Python that reads ratings and reply text against simple rules. Bedrock Haiku 4.5 fires only once per reply, to tidy the customer’s words into a short clean quote without changing the meaning. The customer still sees the exact quote and approves it before anything is published. Most of the system is deterministic by design.
How does it ask without being annoying?
It asks once, at the right moment, then stops. After a happy moment is spotted, the customer gets one short message with a one-tap link. If they don’t reply, the collector sends at most one gentle follow-up after a set wait (default 5 days), then closes the request quietly. Requests respect quiet hours and a per-customer cooldown so the same person is never asked twice in a short window. No reply is treated as a no.
What stops a testimonial from being published by mistake?
Two gates, both required. First, the customer must tick a permission box on a simple page that shows the exact quote and asks how they want to be credited (full name, first name, initials, or anonymous). Second, you approve it from a card with Approve, Edit, or Skip buttons. Only a row that has both the customer’s yes and the owner’s approval ever reaches the published file. Every action is recorded in the tc-audit DynamoDB table, so the trail is auditable for years.
All posts