The Email My App Never Sent

The Email My App Never Sent
More from Building MarrowMinded — the reading app I build with Claude Code. Start here: I built MarrowMinded.
MarrowMinded gives you one lesson a day from a book. The catch: you have to open the site to read it. I wanted it to come to me instead — land in my inbox each morning, no clicking.
I’d even written the send code once, months ago. It never sent a single email.
Why it never worked
The honest reason isn’t technical. The app had no users — just me. Real delivery meant a subscriber list, a scheduler, and a mailer, and that was more work than it was worth for an audience of one. So the send code just sat there, waiting for a reason to run.
What changed wasn’t motivation. It was friction. When I found n8n, delivery got cheap enough to build that I finally wired it up — just for myself.
The MVP: email myself
So I built the smallest version that would help me today: the lesson in one inbox — mine.
I built it in n8n. Three steps:
- A schedule that fires at 7am.
- An HTTP call to a small endpoint I added to the app, which returns today’s lesson.
- An email node that sends it to me.
That’s it. It’s live, and it runs every morning. Not multi-user, not clever. But it does the one thing the app never did: it shows up on its own.
Why n8n and not another cron script? Because I’d been here before, and I didn’t want to hand-write scheduling, an email client, and retry logic all over again. n8n gives me the schedule, the API call, and the email as three boxes I can see. When something breaks, it tells me which box.
The full version: email everyone
Sending to myself is easy. Sending to other people needs three things the MVP skips.
A list. Who wants the digest, and which book they’re on. New sign-ups have to land somewhere.
A record. What went out, and what failed. Without it I’d double-send, or silently drop people when a message bounces. I need “sent” versus “failed”, per person, per day, so I can retry just the failures.
A real sender. My personal Gmail is fine for one email a day. For a list I need a proper email service — I’m looking at Sender — that handles volume and deliverability.
Where the data lives
Here I have two options.
- n8n’s own data tables. Built in, nothing to set up. For a small list, this is plenty.
- A Postgres database on Render, where the app already runs. More control, and the app can read the same data.
I’ll start with n8n’s tables, because there’s less to wire up, and move to Postgres when the list grows or the app needs the data too.
The final flow
Then it’s one n8n workflow:
Schedule → read the list of subscribers → for each person, fetch their lesson → send it with Sender → write back “sent” or “failed” with a timestamp → next run, retry the ones that failed.
A small signup form on the site drops new addresses straight into the list. That’s the whole thing.
Takeaways
- Ship the version that helps you first. My own daily email was the part I could build today. The multi-user version can wait, and now it has a working base to grow from.
- Friction decides what gets built, not just difficulty. Delivery was never hard — it just wasn’t worth the setup for an audience of one. A tool that made it cheap changed the math, and I finally shipped it.
- Let the tool hold the plumbing. Schedule, API call, email, retries — n8n gives me those as parts I can see, instead of a script I have to babysit.
- Track what you send. For anything going to other people, “what was sent and what failed” is not optional. Design it in from the start.
What’s the boring half you keep not finishing? Mine was hitting send. → olekwrites.com/marrowminded
Thanks for reading! If you'd like to share your thoughts send me an email.