Stop Slacking “Who Came In?”: Build a Daily Qualified‑Lead Digest
This playbook shows how CartWizard built a daily qualified‑lead digest in Spreeflo using a Cyclic trigger, internal emails, and simple tagging, so your team stops asking “who came in?” and gets timely, actionable follow‑up lists automatically.
Industry
Niche
Pattern
Loading sequence...
At 9:12am, Elena opens Slack and types the same message she’s typed almost every weekday for the last year:
“Who signed up yesterday that we should talk to?”
She runs CartWizard, a Shopify cart‑recovery app doing around $70k MRR. Installs come in steadily from the App Store. Some of those stores are whales. Most are not.
Her teammate Nico opens Stripe, filters by “new customers,” cross‑checks a Google Sheet, eyeballs a custom report in their app, and replies with a short list. Half an hour later, someone remembers a big brand logo that installed but never made it into the thread.
By the time anyone reaches out, it’s the afternoon. Sometimes the next day. Sometimes never.
The sequence at the top of this page is the whole journey, end to end, that got Elena out of that loop. No more ad‑hoc “who came in?” pings. Every morning, qualified Shopify stores hit a single inbox in a tight, scannable format, ready for fast follow‑up.
This playbook walks through how to build that daily qualified‑lead digest in Spreeflo, how it works under the hood, and how to adapt it to your own app.
Why “who signed up yesterday?” is an ops bug, not a habit
If you’re building an e‑commerce app or Shopify integration, you already know where revenue leaks:
Stores that install but never activate.
High‑intent trials that never get a human touch.
Big brands that cancel before you even realise they were in trial.
Nine times out of ten, the root cause is simple: there’s no system that turns “this store looks promising” into a reliable, repeatable human follow‑up.
Instead, you get:
Slack threads that depend on whoever remembered to check.
One‑off screenshots from Stripe or your internal admin.
Heroic follow‑ups from the founder that don’t scale.
Founder‑led businesses win on leverage, not headcount. A daily qualified‑lead digest is one of those tiny pieces of infrastructure that pays rent every single day: you set it up once, and your team never has to ask “who should I talk to today?” again.
Let’s turn that idea into a working journey.
The architecture in one sentence
At a high level, the journey you see at the top of this page does three things:
Watches for leads who became qualified in the last 24 hours.
Once a day, enrolls those contacts through a Cyclic trigger.
Sends a Send Internal Email with the context your team needs to act.
Everything else is just wiring data into those three moves.
Before we touch the journey canvas, you need one upstream decision made: what “qualified” means in your world.
Step 0: Decide and track your “qualified lead” moment
CartWizard’s team uses a simple definition:
Installed the app (
app_installedevent).Recovered at least 1 cart (
cart_recoveredevent).Store revenue (pulled from Shopify API into a contact attribute) is above $20k/month.
When those three conditions are true, their backend calls the Spreeflo API to record a custom event, say lead_qualified, for that store’s primary contact. You’d do the same using the Spreeflo API or the JavaScript SDK, depending on your stack.
Why a dedicated lead_qualified event instead of trying to reconstruct qualification logic inside Spreeflo?
Your app already has the full context.
Qualification rules will evolve; you don’t want to edit three different journeys every time.
A single “moment” event is easy to reason about in the segment builder.
Once that event is flowing, you’re ready to build the digest.
Step 1: A Cyclic trigger that runs once a day
In Spreeflo, this flow is a journey, not a campaign. Journeys run continuously, react to triggers, and are where campaign and journey automation comes alive.
The first node in the sequence is a Cyclic trigger:
Repeat interval: every 1 day.
Time of day: whatever works for your team (CartWizard uses 08:30).
Timezone: where your sales or success team lives.
The magic is in the Cyclic trigger’s criteria. It embeds the full segment builder, so this is where you define “people we want in the digest today.”
A sensible starting point for an app like CartWizard:
Custom Events:
- Event:lead_qualified
- Operator: triggered at least 1 time
- Time window: in the last 1 dayEmail Subscription Status:
- is Subscribed (helps avoid ever sending outreach to someone who opted out, if you later re‑use this segment for marketing email)
Expressed in plain English: “Every day at 08:30, find every contact who fired lead_qualified at least once in the last 24 hours and is currently subscribed.”
A few design choices worth calling out:
Use “in the last 1 day,” not a fixed date range. That keeps the journey evergreen. There’s no “yesterday” operator for attributes, but activity rules (like custom events) support rolling windows.
Leave Re-enrollment off on the Cyclic trigger. You only ever want a given contact to flow through this digest once, even if they somehow retrigger
lead_qualified. With re‑enrollment off, once this journey has run for a contact, future ticks of the clock ignore them.
That one Cyclic node turns your blurry concept of “yesterday’s qualified leads” into a concrete, queryable set of contacts.
Step 2: Craft the internal email your team will actually use
Next in the sequence is Send Internal Email. This is where most of the value lives.
While a normal Send Email node goes to the contact, Send Internal Email goes to you and your team. Think of it as an automatic, structured Slack message in email form.
CartWizard configured their node roughly like this:
From: a neutral identity like
alerts@cartwizard.io(set up under your sending domains; see the guide on setting up your domain).Template: “New qualified store digest”.
The template itself lives in the same email builder you use for customer emails, so you can:
Drop in your logo and basic layout.
Insert contact attributes (store name, plan, country, app install date, etc.).
Add links straight into your internal admin, CRM, or support inbox.
A simple structure that works well:
SubjectNew qualified Shopify store: {{ store_name }} ({{ country }})
Body
Store:
{{ store_name }}URL:
{{ website }}App plan:
{{ current_plan }}Estimated store revenue:
{{ monthly_revenue }}Events: Installed on
{{ app_installed_at }}, first recovery on{{ first_recovery_at }}Fit notes:
{{ internal_fit_notes }}(optional attribute you can let reps update)
CTA links
View in admin (your internal URL)
Open last support ticket (if any)
Because this is an internal template, the “To” address is whomever should see these leads: maybe sales@, maybe a shared “growth” inbox, maybe directly into a helpdesk that routes work by tags.
Every time the Cyclic trigger enrolls a contact, this node sends one email. If five stores qualified yesterday, your team gets five emails in a tight burst around 08:30. It behaves digest‑like in practice, even though each lead has its own message.
A couple of configuration details matter:
Leave Send only once turned on. If you later reuse this internal template in other journeys, you still don’t want the same contact triggering duplicate internal alerts.
Keep the template focused on context, not instructions. Your team already knows how to do outreach. What they lack today is a reliable, timely list of who deserves it.
This is where you start to feel the benefit: instead of Slack fishing for data, Elena opens her inbox at 08:32, searches for “New qualified Shopify store,” and has her call list for the morning.
Step 3: Tagging or staging for pipeline visibility
Strictly speaking, the pattern only needs the two nodes above. In practice, it’s cheap to add one more node for future segmentation.
Right after Send Internal Email, add an Update Contact Attribute action that sets a simple pipeline flag. For example:
Attribute:
sales_status(TEXT custom attribute).Update type:
Update.Value:
queued_for_outreach.
Design intent:
Any contact with
sales_status = queued_for_outreachhas appeared in a digest but hasn’t yet been marked as contacted.Your team can later build a saved segment of “queued_for_outreach AND lead_qualified triggered at least 1 time over all time” to sanity‑check that nothing is aging out without touch.
Remember that Update Contact Attribute writes static literals you define at design time. It does not pull dynamic values out of events. That’s why it’s suited to stage labels like queued_for_outreach, contacted, won, not things like “amount of last invoice.”
If you prefer tags, a simple Add Tag node with a tag like digest_qualified_lead works just as well. Tags are easy to eyeball on a contact record, and they play nicely with the segment builder.
Now your journey looks like this:
Cyclic (daily) → Send Internal Email → Update Contact Attribute / Add Tag → End
Minimal, but enough.
Routing leads to the right person without overcomplicating it
If you have more than one person doing outreach, you can adapt the middle of the journey to route internal emails to the right owner.
The mechanics:
Keep the Cyclic trigger as is.
Insert an If/Else process node right after it.
Define the condition using the segment builder. Examples:
- Country is United States → route to your US‑focused rep.
- Contact attributelead_tierisenterprise→ route to the founder.Off each branch, place a separate Send Internal Email node using templates that send to different internal addresses or add different instructions.
Optionally recombine with a Merge node if you want a shared post‑processing step (like tagging everyone
queued_for_outreach).
You could achieve similar routing with multiple journeys, but keeping it inside one makes it easier to see the whole system on a single canvas.
The key principle: only add branching where it materially changes who acts or how they act. Don’t branch for cosmetic reasons.
How this changes your numbers
You’re not building this for fun. You’re doing it because certain metrics move when every qualified lead gets treated as a small event, not a vague count.
The three outcomes worth watching:
Lead‑response time
Before the digest, a promising store might wait a day or two for a human email, if they got one at all. After, your de‑facto SLA becomes “by lunch local time” because the list arrives every morning. You can instrument this by having your CRM or backend fire asales_outreach_sentcustom event and comparing its timestamp withlead_qualified.Team adoption
If your team ignores the digest, nothing improves. Pay attention to behavioural signals: are reps pinning these emails, forwarding them, adding notes back into contacts? Because the digest comes from the same automation engine as your customer messaging, you can refine it quickly when feedback comes in.Qualified trial conversion
This is the long game. Over a month or two, compare conversion rates for stores that firedlead_qualifiedbefore you had the digest, vs. after. As long as your qualification logic is stable, most improvements here are attributable to consistent follow‑up.
None of this requires heavy BI. It just requires that you’re already tracking the right events and segmenting off them, which is where Spreeflo’s platform overview and audiences and segments model earn their keep.
Adapting the pattern to your app
Every Shopify or e‑commerce app has its own idea of what “qualified” means, but the skeleton stays the same.
Some variations you might consider:
Different windows for different lead types
Enterprise‑looking stores might get a shorter window (you want to know within hours), while self‑serve trials can comfortably sit on the “last 1 day” cadence.Separate digests by intent source
One journey for App Store organic installs, another for installs that came from a partner integration, each with their ownlead_qualifiedevent. Same structure, different context in the internal email.Adding web behaviour into qualification
For higher‑touch products, you might require “visited pricing page at least 2 times in the last 7 days” or “total visits at least 5” inside the qualification logic that fires yourlead_qualifiedevent. The journey itself doesn’t need to know; it just listens for the event.
The important part is that you decide once what matters, encode it into events and attributes, and then let automation broadcast those moments to the humans who can act.
The quiet power of a boring, daily email
A daily qualified‑lead digest is not flashy. Nobody tweets screenshots of their internal alerts.
But for founder‑led SaaS businesses, especially in the Shopify ecosystem, it is exactly the kind of boring automation that compounds:
You stop wasting time chasing data across Stripe, your admin, and the App Store dashboard.
You react faster when a whale swims into your trial pool.
You build a habit around follow‑up that doesn’t depend on the founder’s memory.
You spend an hour in the journey editor wiring up a Cyclic trigger, a Send Internal Email, and a simple attribute update. After that, the system quietly nudges your team every morning, weekdays, weekends, through Black Friday and holiday season, without asking for more of your attention.
That’s what leverage looks like when you’re running a small crew.