Google Review Requests Without Review Gating
BrightFlow asks once when a completed service case closes. Every eligible customer gets the same review link and the same path to a person.
39/39 TESTS PASSED · INITIAL + ONE REMINDER DELIVERED · CLICK + RECOVERY PATH RECORDED


The problem
A completed service job does not automatically turn into a review request. Manual follow-up is easy to miss, and a fixed delay ignores the difference between a drain cleaning and a larger installation.
The system also has to ask fairly. Rating, sentiment, job value, technician, complaint status, and the expected review cannot decide who receives the link.
What I built
I built the demo for BrightFlow, the same fictional Austin plumbing company used in the speed-to-lead project. Eligibility checks completion, contactability, consent, duplication, case closure, and a uniform 90-day frequency limit.
PostgreSQL owns timing, leases, caps, sends, suppressions, replies, and idempotency. The longest service line sets the delay. Gmail is live for the controlled test, while SMS stays disabled until an approved A2P campaign exists.
The email copy is deterministic. Every eligible message includes the review link and a human reply path. The Cloudflare redirect uses an opaque token and stores no IP address or user agent.
How I tested it
All 39 automated checks passed. They cover the timing matrix, Austin quiet hours and daylight-saving boundaries, the weekly cap, duplicate intake, exactly one reminder, provider ambiguity, STOP, redaction, classifier failure, and the absence of sentiment gating.
The controlled allowlisted run delivered the initial request and one final reminder. The tracked click redirected to the fictional-demo page and produced one acknowledged PostgreSQL click event.
A token-rotation bug surfaced during the live click test. I fixed the D1 upsert, added a regression test, and deployed the repaired Worker before repeating the click.
Controlled results
The initial request and one final reminder each arrived once.
PostgreSQL recorded one click and one redacted problem-reply event.
The owner alert and static recovery acknowledgement both arrived.
All four permanent n8n workflows remained inactive after testing.
Temporary workflows were removed and the temporary n8n API key was revoked.
Limits and next steps
The Gmail credential can send but cannot read the inbox. Automatic reply ingestion returned 403, so the recovery test used a provider-confirmed delivered fixture. A real inbox-read run still needs the Gmail read scope.
I did not perform a service restart, and n8n cannot yet reach the private Baserow service from its container. SMS, Google Business Profile OAuth, and review totals remain staged. The dashboard totals are synthetic and labeled that way.
BrightFlow is fictional. The emails, click, and recovery records are controlled test evidence, not a client result or conversion claim. No Google Business Profile was created, and the displayed review totals are synthetic.
Want this for your business?