Follow-ups that can wait and branch

Part of a coaching CRM for a group of clinics.

The old follow-ups were fixed sequences. When a lead's status changed, the app scheduled every email right away: day 1, day 3, day 7. It couldn't wait to see whether the person booked, send something different if they didn't, or hold a text until morning.

The app is the CRM a group of exercise clinics uses to keep track of everyone who has shown interest. Someone who fills in a form on the website becomes a lead, and the CRM sends the emails and texts until they sign up.

Now staff draw a journey, a bit like a flowchart. Send this email. Wait two days. Did they book? If yes, stop. If not, send a text, but only during the clinic's hours, in that clinic's time zone. People join a journey automatically when they match a group staff have defined, like "missed their first appointment".

Each message once

The hard part is making sure each person gets each message once. Many people can be partway through a journey at once, and several workers, copies of the program running side by side, process them at the same time. Five rules keep that safe:

One plan didn't survive. I meant to reuse the old system's sending code so journeys would get its safety checks for free. Then I found the old tables couldn't hold a message that wasn't part of an old-style sequence. Journeys got their own record of sends instead, and I copied over the few checks they needed. Big decisions get a short written record of what we decided and why, including the ones I later reversed. This one still shows the first plan next to the correction.

To switch over, staff can turn an old sequence into a draft journey in one click, then retire the old one. Email templates are checked before a journey can go live, so a typo in a placeholder like {{ frist_name }} gets caught before it reaches anyone.

Bring your own AI

Staff can use an AI assistant to build journeys, groups and email templates, without the CRM calling an AI at all. The CRM writes a set of instructions from its own current setup: the kinds of steps, the statuses, the existing templates. Staff paste that into whatever assistant they already use and paste the reply back. The CRM checks the reply exactly the way it checks a normal save. Since the instructions come from the code, they stay accurate when the code changes.

Where it stands

The first journeys went live at the end of July. Since then, 322 people have gone through them and they've sent about 1,500 emails and texts.

Rails 8.1, Postgres, Sidekiq, React Flow, Twilio, SendGrid.