How an unanswered call-back gets escalated
Most text-backs do their job: the caller replies and books. But some don’t — the message lands, nobody answers, and without a nudge that caller is exactly the one who quietly drifts away. This post is about the safety net: the scheduled sweep that notices a text-back has gone unanswered and puts the caller in front of a person to follow up.
Key takeaways
- Some text-backs are never answered — and an unanswered text-back is a customer quietly slipping away, so the system watches for it.
- An EventBridge Scheduler rule runs a sweep on a fixed cadence, looking for calls that were texted but have had no reply within a set window.
- Each stale call is handed to a person to ring back, with the call time, the matched customer, and the text that went out attached.
- The sweep escalates a call exactly once, respects quiet hours, and never sends the caller a second automated text.
- It’s the difference between “we texted them” and “we got them back” — the net under the whole system.
The ones that go quiet
Most text-backs work: the caller reads it, taps the booking link or texts back, and Part 4 takes over. But some don’t. The text lands, the caller means to reply, and then the bus comes or the kettle boils and they forget. From the business’s side this looks identical to success — a text was sent — which is exactly why it’s dangerous. That caller had a need a few minutes ago and now they’re drifting, and nobody at the shop has any reason to notice. A system that only ever fires on incoming events would never see this, because the thing that needs acting on is an event that didn’t happen: a reply that never came.
Catching an absence needs something that runs on a clock rather than on a trigger. That’s the escalation sweep: a small scheduled job whose entire purpose is to find text-backs that have gone unanswered past a sensible window and put the caller in front of a person before they’re gone for good.
A job on a clock
The sweep is driven by EventBridge Scheduler — a managed cron that invokes a Lambda on a fixed cadence, with no always-on compute and effectively no cost. A sensible cadence is every 15 minutes during opening hours. Each run does the same simple thing: query the calls table for records that are texted but not replied, where the text-back went out longer ago than the no-reply window (say, 30 minutes) and which haven’t already been escalated. A short window catches people while their intent is still warm; making it configurable lets a business tune it — a restaurant taking bookings wants minutes, a tradesperson quoting jobs might be happy with a couple of hours.
For each call the sweep finds, it builds a handover and hands it to a person to ring back: the time of the missed call, the customer it was matched to (and their history, if any), the exact text-back that went out, and the fact that there’s been no reply. Then — and this is the important part — it marks the call escalated on the same record, so the next run 15 minutes later doesn’t flag the same call again. A call is escalated exactly once. The sweep raises a human, it does not send the caller a second automated text; the whole design rests on one text per missed call, and a chasing text would break that promise and read as nagging.
Why a sweep, and not a timer per call
You could imagine scheduling a one-off check for each individual text-back — set a 30-minute timer when the text goes out, fire it, see if there’s a reply. It works, but it means a scheduled entity per missed call, more moving parts to create and clean up, and a pile of near-simultaneous invocations on a busy morning. A single periodic sweep is simpler and cheaper: one rule, one function, one query that scales to whatever volume the day brings, and idempotent by design because the escalated flag means re-running it never double-notifies. At this scale the 15-minute granularity is plenty — the difference between a 30- and a 42-minute callback is nothing next to the difference between a callback and none.
The sweep also respects the same guardrails as everything else. It runs only during opening hours, so it doesn’t ping the owner’s phone overnight; a call missed at 11pm waits and is swept in the morning. It checks the opt-out list, so a number that texted STOP after the text-back is never escalated. And it touches only its own state — it reads calls and writes the escalated flag, nothing more — which keeps it safe to run unattended every quarter of an hour, forever.
Design rules that shaped escalation
- Watch for the event that didn’t happen. A reply that never came is the signal; only a scheduled sweep can see an absence.
- A clock, not a trigger. EventBridge Scheduler runs the sweep on a fixed cadence with no always-on compute.
- Escalate once. The escalated flag on the call record makes the sweep idempotent — no call is ever flagged twice.
- Raise a human, don’t chase the caller. The sweep notifies a person to ring back; it never sends a second automated text.
- The same guardrails apply. Opening hours and the opt-out list are honoured by the sweep exactly as by the live path.
- One sweep beats many timers. A single periodic query is simpler, cheaper, and idempotent than a scheduled entity per call.