Part 4 of 7 · Quote follow-up series ~5 min read

How a quote nudge reaches the buyer

The timer picked a move — first nudge, follow-up, or last call. Now the sender Lambda has to figure out who owns the quote, write a draft in your voice, get a person to approve it, and send it at a decent time of day. Get any of those wrong and the nudge is worse than no nudge: a generic “just checking in” with the wrong amount, an email at 11pm on a Saturday, a third message to someone who already said no. Four small guardrails sit between the move and the email landing.

Key takeaways

  • Owner resolution: per-quote owner beats per-rep default beats fallback to the configured admin.
  • Bedrock Haiku 4.5 drafts the nudge in your voice; the rep approves it with one tap before anything sends.
  • Quiet hours and weekends defer the send to the next reasonable business hour.
  • Every nudge ships with the quote name, amount, days since sent, a link to the quote PDF, and a clear reply path.
  • Nothing auto-sends. A person approves every draft, so the customer never gets a robotic message.

Four guardrails on every nudge

Four guardrails between the timer's chosen move and the sent nudge A horizontal flow diagram. On the far left, a "Move chosen" box: the timer emitted an event with the quote, the amount, and one of three sending moves — first nudge, follow-up, or last call. Four guardrail gates sit in a row to the right, each drawn as a vertical bar. Gate 1: Resolve owner — looks up the per-quote owner column first; if blank, falls back to the per-rep default from the rules doc; if still blank, falls back to the configured admin. Returns the rep's email so drafts and replies route to the right person. Gate 2: Draft and approve — calls Bedrock Haiku 4.5 to write the nudge in your voice from the voice-doc template for the chosen move, then emails the draft to the rep with one-tap Approve, Edit, or Skip; nothing sends until a person approves. Gate 3: Quiet hours and weekends — once approved, checks the local time against the rules-doc quiet-hours window and the skip-weekends setting; if outside business hours, defers the send to the next available business minute via an EventBridge Scheduler one-off rule. Gate 4: Final compose and send — fills the approved draft with the quote context (customer, amount, days since sent, link to the quote PDF), sets the reply-to so the customer's answer comes back through SES inbound, and sends via SES outbound. After all four gates pass, the nudge ships to the customer's email. A note at the bottom: every send is logged to DynamoDB so the next check knows the step has fired and won't repeat it. Move chosen first nudge, follow-up, or last call Gate 1 Resolve owner quote owner? rep default? admin fallback? drafts route to the right rep Gate 2 Draft + approve Haiku 4.5 writes it in your voice rep taps Approve, Edit, or Skip Gate 3 Quiet hours + weekends in business window? if not, defer via Scheduler Gate 4 Compose + send approved draft + quote context amount, days, link, reply-to, SES outbound Send — SES outbound email to the customer, reply-to routed back to SES inbound SES SendRawEmail · reply-to quotes-address for the watcher to catch the answer every send logged to DDB qf-nudges — the next check won’t repeat the step A person approves every draft — the customer never gets a message nobody chose to send.
Fig 4. Four guardrails between the move and the sent nudge. Resolve the owner. Draft in your voice and get it approved. Honor quiet hours and weekends. Compose with full context and send. Then log the send so the next check doesn’t repeat the step.

Gate 1: resolve the owner

Three places the sender Lambda looks for the owner of a quote, in order. First, the quote sheet’s per-quote owner column — if a row names a specific rep, that rep owns it. Second, the per-rep default in the rules doc (“quotes from the catering team default to Priya”). Third, the configured admin fallback — the person who set up the system and gets every unowned quote. The fallback should never fire in steady state; if it does, the weekly digest names every quote that hit the fallback so the sheet can be corrected.

The owner matters because the draft goes to them for approval, and because the customer’s eventual reply needs to land with the right person. Getting this wrong sends the approval to someone who doesn’t know the deal, which is how a quote ends up with no follow-up at all.

Gate 2: draft in your voice, then approve

This is the gate that keeps the system from feeling robotic. The voice doc holds one short template per move — first nudge, follow-up, last call — with the tone you want and placeholders for the customer name, amount, and quote link. The sender calls Bedrock Haiku 4.5 with that template plus the quote details and asks for a short, warm draft that doesn’t repeat itself across the chain. The prompt is strict: “Keep it under five sentences. Reference the quote by name and amount. Do not invent terms, discounts, or dates. Sound like a helpful person, not a sales bot.”

The draft is then emailed to the rep with three one-tap options: Approve sends it (subject to Gate 3), Edit opens it in a short form to tweak the wording, and Skip drops this nudge for this quote without affecting the rest of the chain. Nothing reaches the customer until the rep approves. Because the draft is already written, approving takes a couple of seconds — the rep is reviewing, not writing.

Gate 3: quiet hours and weekends

The timer runs at 9am local, but approvals can come back at any hour. A nudge approved at 8pm shouldn’t land in a customer’s inbox at 8pm, and a nudge approved Saturday morning shouldn’t go out on the weekend if the rules doc says to skip weekends.

Gate 3 reads the rules doc’s quiet-hours setting (default 6pm to 8am) and the skip-weekends flag. If the approved nudge falls in a quiet window or on a skipped day, the sender creates a one-off EventBridge Scheduler rule that fires at the next business-hour minute and exits without sending. The Scheduler re-invokes the sender with the same approved draft at the deferred time, where Gate 3 lets it through. Good timing is part of not being pushy: the same message lands very differently at 9am Tuesday than at 9pm Sunday.

Gate 4: compose with full context, then send

The sender fills the approved draft with the final quote context — customer name, amount, days since you sent it, and a link to the quote PDF — and wraps it in a clean email. Crucially, it sets the reply-to address to the dedicated quotes@your-company.com inbox, so when the customer answers, the reply comes straight back through SES inbound where the watcher can catch it (that’s the whole of Part 5). The email itself sends via SES SendRawEmail from the rep’s verified sender identity, so to the customer it looks like it came from the person they’ve been dealing with.

A last-call nudge is slightly different in wording — it names the expiry date and offers to extend — but it goes through the exact same four gates. There is no “urgent” path that skips approval.

Every send — first nudge, follow-up, or last call — writes a row to qf-nudges in DynamoDB. The next day’s check reads that row and knows not to fire the same step again.

Why the guardrails exist

None of these gates are exotic. They’re the kind of small care a thoughtful salesperson would take if they were sending the nudges themselves — check who actually owns this deal, write something human, don’t email at midnight, include enough context that the customer doesn’t have to ask “which quote?” Putting them in code as four small sequential gates makes them part of the design, not something you’re trusting a busy rep to remember on a Friday afternoon.

Next post: how a reply stops the follow-ups — how the system reads the customer’s answer, sorts it into accept, decline, question, or out-of-office, and hands every real reply to a person.

All posts