How I Automated My Entire Email Funnel in One Weekend (You Can Too)11
How I Automated My Entire Email Funnel in One Weekend (You Can Too)
By Dr. Elara Voss, Ph.D. in Artificial Intelligence
There is a particular kind of silence that settles over a developer's desk when a complex system finally clicks into place. It isn't the silence of a broken screen or a frozen cursor. It is the quiet, humming stillness of watching a machine do the work you used to do by hand. Last weekend, I experienced that exact silence. By Saturday evening, I had decommissioned three manual email sequences, retired a spreadsheet that had governed my outreach for two years, and replaced the whole thing with a set of prompt-driven workflows that now run without me. This article is not a sales pitch for a specific platform. It is a technical and practical account of how I rebuilt my email funnel in roughly eleven hours, what the architecture looked like, what I got wrong on the first pass, and what I would tell anyone who wants to do the same thing.
If you work in marketing, content, or any role where email is a primary channel, you already know the pain. You know the drift. You know the version that went out to a segment that should have received a different version. You know the follow-up that never went because you forgot. You know the welcome email that is the same for the enterprise lead and the free-tier trial user. You know the pain of a funnel that was designed in a spreadsheet and maintained by memory. I want to walk you through how I replaced all of that with a system that is, in the technical sense, an agent: a model that reads context, decides what to write, and sends it.
The Problem With the Classic Funnel
Before I explain what I built, it helps to explain what I was trying to fix. A classic email funnel is a state machine. You have a user in state A, and you want them to transition to state B. You write the transition logic by hand. You write email one for state A, email two for state B, email three for state C. You write the timing. You write the branching: if they opened email one, go to branch X; if they didn't, go to branch Y. You write the conditions. You maintain all of it. And the moment your offer changes, or your audience shifts, or you want to personalize for a new segment, you have to open the editor, rewrite the copy, re-wire the branches, and test the whole thing.
The core inefficiency is that the copy is decoupled from the context. The email is a static artifact. It was written once, in a moment of time, and then it is frozen. The user, on the other hand, is dynamic. They are reading, clicking, hesiding, returning, comparing. The classic funnel treats the user as a node in a graph, but the user is actually a stream of signals. My goal over the weekend was to close that gap. I wanted the email to be generated at the moment of sending, from the most current knowledge I could assemble about that specific user at that specific moment.
A small note on terminology, because I think it matters. When I say "AI-automated," I do not mean I trained a large language model on my customer base. I did not fine-tune a transformer on my CRM. I did not build a vector database and a retrieval pipeline and a ranking model. I used an off-the-shelf large language model, wrapped in a few hundred lines of orchestration code, fed with structured context, and constrained with a careful prompt. That is a meaningful distinction. I did not build an AI. I built a system that uses an AI. And that is exactly what most of you can do.
The Architecture: Four Layers
Let me sketch the system I built. It has four layers, and understanding them will help you build your own.
Layer one: the context assembler. This is a lightweight service that, given a user ID, pulls together everything I want the model to know about that user. It reads from my CRM, my product analytics, my support tickets, my billing system. It produces a structured document: who this person is, what they bought, what they opened in the last thirty days, what support issues they have, what their company does, how big it is, what their role is. The output is a single JSON blob. I call it the user dossier. It is maybe two kilobytes per user. It is the raw material.
Layer two: the prompt compiler. This is where the craft is. I wrote a system prompt that explains the goal, the audience, the brand voice, the constraints (word count, no exclamation marks, no fake urgency, specific words to avoid), the structure of the email (opening, body, single call to action, sign-off), and the decision rules (what to emphasize if the user is a new lead, a trial user, a customer, a lapsed customer, a supporter). The prompt compiler takes the user dossier and the current "stage" of the funnel and produces a complete, ready-to-send prompt. The key insight: the prompt is not a template with blanks. It is a document that explains the situation and asks the model to write the email. The model is doing the writing. I am doing the directing.
Layer three: the writer. This is the large language model. I used a mid-tier model, not the most expensive one, because I wanted quality without latency. I ask for one email per call. I pass the compiled prompt. I get back a clean, formatted email. I do a light post-processing pass: fix any HTML entities, ensure the CTA button is present, trim any trailing whitespace.
Layer four: the dispatcher. This is a simple queue and a mail-sending API. It takes the generated email, attaches the user's address, sends it, logs the result, and updates the user's state in the CRM. If the user opens, the context assembler picks up the new signal, and the next email in the sequence is regenerated with that new signal in the dossier.
That is the whole system. Four layers. A few hundred lines of code. A weekend of work. And it runs every day without me.
The Prompt: Where the Real Work Lives
I want to spend a moment on the prompt, because this is where most people get it wrong. A weak prompt says, "Write an email to [NAME] about [PRODUCT]." That is a recipe for a generic, interchangeable, forgettable email. A strong prompt does several things at once. It establishes the persona of the writer. It establishes the persona of the reader, including what the reader is likely to be doing right now. It establishes the single goal of this email. It gives structural constraints. It gives stylistic constraints. It gives examples of good and bad. And it gives the model permission to be specific.
Here is a fragment of my prompt, lightly edited:
You are writing a follow-up email to a marketing director at a mid-size SaaS company. She opened our last two emails but has not clicked through to the pricing page. She works at a company of about 120 people. Her team has been evaluating competitors for three weeks. Your goal in this email is to make her feel that we understand the specific comparison she is doing, and to give her a low-friction reason to look at our pricing page. Keep it under 150 words. No exclamation marks. One call to action. Write in a calm, peer-to-peer tone. Do not use the words "delve," "leverage," or "synergy."
Do you see what is happening? The model is not being told what to say. It is being told the situation, the person, the goal, and the constraints. And then it writes. The result is an email that reads like a human wrote it, because in a meaningful sense, it did. The human provided the context and the intent. The model provided the words.
The Weekend, Hour by Hour
I want to be honest about the process, because I think the realism is part of the lesson.
Friday, 9am to noon: I audited my existing funnel. I found 11 emails, 4 sequences, and about 30 branching conditions. I wrote them all down in a flat document. This turned out to be the most important hour of the weekend. I had to understand what I was trying to do before I could automate it.
Friday, noon to 5pm: I built the context assembler. I wrote the JSON schema for the user dossier. I wired up the CRM, the analytics, the support, and the billing APIs. Most of this was glue code. Not glamorous, but necessary.
Friday, 5pm to 9pm: I wrote the prompt compiler. I wrote the system prompt. I iterated on it with about fifteen test users. I read each generated email and asked, "would I want to receive this?" That is the only quality bar that matters.
Saturday, 9am to 1pm: I built the dispatcher. I set up the queue, the mail API, the logging, and the state updates. I wrote a small test harness that let me trigger the whole pipeline for a single user and inspect the output.
Saturday, 1pm to 6pm: I ran the pipeline on a sample of 200 users. I read every email. I tweaked the prompt. I found three emails that were a little too salesy, and I added a line to the prompt: "Do not use superlatives." I found two that were a little too long, and I tightened the word count.
Saturday, 6pm to 9pm: I wired up the state transitions. I made sure that when a user opens an email, the next email is generated with the new context. I tested the branching. I wrote a small dashboard that showed me, for any user, the dossier, the compiled prompt, and the generated email, side by side.
Sunday, 9am to noon: I ran the whole funnel end-to-end on a test list. I verified that the right emails went to the right users at the right times. I checked the logs. I checked the state updates.
Sunday, noon to 4pm: I wrote the documentation. A single page that explains the four layers, the prompt, the test harness, and how to add a new email to the funnel. This is the part people skip, and it is the part that makes the system maintainable.
Sunday, 4pm to 6pm: I retired the old system. I turned off the old sequences. I sent a note to the team explaining what changed. I made a cup of coffee. I sat down. The silence.
What I Got Wrong on the First Pass
Three things. I want to share them so you can skip the same mistakes.
First, I over-personalized. My first version of the prompt asked the model to reference specific details about the user's company. The model did, but it did so in a way that felt a little too familiar. It mentioned the user's company's recent funding round, which I had in the dossier, but which the user had not mentioned to me. The model wove it in naturally, and I could feel the slight uncanny quality. I fixed this by adding a line to the prompt: "Only reference details that the user has shared with us directly or that are publicly well-known." It sounds small. It is not.
Second, I under-constrained. My first version of the prompt did not specify a word count. The model wrote emails that ranged from 60 words to 320 words. Some were too short to be useful. Some were too long to be read. I added a word count and a structural template. The consistency improved dramatically.
Third, I forgot about the quiet emails. Not every user needs an email every day. My first version sent the next email in the sequence as soon as the previous one was opened. For some users, that was too fast. They opened, read, and wanted a day to think. I added a small delay: the next email goes out 24 hours after the previous one is opened, not immediately. It sounds like a small change. It changed the open rates on the second and third emails by more than I expected.
What the System Can Do That a Spreadsheet Cannot
Let me close with the part that I think is most important. A spreadsheet can do logic. A spreadsheet can say, "if the user opened email one, send email two." That is a condition. A spreadsheet cannot do inference. A spreadsheet cannot say, "this user is a marketing director at a mid-size SaaS company, she has been evaluating competitors for three weeks, she has opened our emails but not clicked through, and therefore the most helpful thing I can say to her right now is a specific, calm, peer-to-peer framing of how our pricing compares to the competitor she is looking at."
That is inference. That is the model reading the dossier, understanding the situation, and writing the email that fits. That is the difference between a funnel and a conversation. A funnel is a path. A conversation is a response. And a response is what a good email should be.
I am not saying the model is perfect. It still makes occasional small errors. It still occasionally uses a word I asked it not to use. It still occasionally gets the tone slightly off. But it is consistent, it is fast, it is available, and it is better than the alternative, which is a static email that was written once and has not been updated since.
If you have a funnel that is maintained by memory, you have a weekend project. You do not need to build a model. You do not need to train anything. You need to write a good prompt, assemble good context, and build a small system that puts them together. You need to read the output and iterate. You need to write the documentation. You need to retire the old system.
And then you can sit down, make a cup of coffee, and listen to the silence.