How I Turned My Messy Inbox Into a Daily Signal Feed Using n8n + AI

By Akshat Gupta
March 28, 2026

I was subscribed to Morning Brew, the NYT briefing, and a handful of LinkedIn newsletters. Good stuff. Stuff I actually wanted to read.

The problem wasn’t the content. The problem was everything around it

Every tool I’d ever signed up for had decided I needed to be on their mailing list. Every form submission came with a checkbox I’d missed. Slowly, my inbox became a graveyard of promotional emails with three newsletters I actually cared about buried somewhere in the middle.

Eventually, I just stopped opening Gmail.

Not because the content wasn’t valuable. But because finding it required effort, I didn’t have it at 9 am. Open Gmail, scroll, decide what to read, skip irrelevant stuff, open another tab, forget what you were doing. It felt like work before the actual work.

So I built a small system to fix it. Nothing fancy. Five nodes in n8n, a bit of JavaScript, and a Slack channel. Now every morning I open Slack and see a clean summary of only the newsletters I care about.

No inbox. No scrolling. No decisions.

Here’s exactly how I built it.

Before the tools: solve selection, not summarization

Most people think the hard part is summarization. Get an AI to read your emails and tell you what matters.

That’s not the hard part. The hard part is selection, figuring out which emails are worth processing in the first place. Feed garbage to AI and you get a better-formatted version of garbage.

So before I touched n8n, I made one decision: I’m going to define “worth reading” manually. Not algorithmically. Me. Using a Gmail label.

Step 1 – Label what matters in Gmail

I created a Gmail label called Worth Newsletter.

image

Then, for each newsletter I actually wanted, Morning Brew, the NYT briefing, LinkedIn newsletters from people I follow. I opened one email, clicked the three-dot menu, selected “Filter messages like this”, and applied the label. Gmail auto-fills the sender address. I also checked “Apply to existing emails” so past issues got labeled too.

That’s it. Gmail becomes your memory. Every future email from that sender is automatically labeled, no thinking required.

I went through this for maybe 8–10 senders over two days. No overthinking. If I’d opened it in the last month and found it useful, it got the label. If not, I ignored it.

The inbox is still messy after this. But now there’s a clean layer inside it, a curated stream of only what matters. That layer is what feeds the automation.

Step 2 – Why n8n (and not Zapier or Make)

I’ve used Zapier before. It’s fine for simple stuff. But the moment you need any custom logic like cleaning HTML or formatting a prompt, you’re hitting paywalls or workarounds. n8n is visual like Zapier, but lets you drop in JavaScript nodes when you need them. It’s the right balance for someone who can read code but doesn’t want to write a backend.

Self-hosted n8n is free. Cloud has a free tier. For this workflow, either works.

Step 3 – The workflow (5 nodes)

image 1
Daily Trigger  →  Gmail  →  Code (JS)  →  AI  →  Slack

Each node does one thing. Together, they take 10 newsletters and deliver one clean Slack message every morning.

Node 1 > Daily Trigger

Add a Schedule Trigger node. Set it to run once a day at whatever time you want to start with insights, no configuration beyond that.

Node 2 > Gmail (fetch only what’s labeled)

Add a Gmail node. Set the operation to “Get Many Messages”. In the label field, select “Worth Newsletter”.

This is why Step 1 matters. You’re not asking AI to decide what’s relevant. You already decided. The system just respects that.

image 2

Node 3 > Code (clean the HTML mess)

Emails arrive as raw HTML. Styling, tracking pixels, buttons, unsubscribe links, all of it. If you send that directly to an AI, the summary will be garbage

image 3

🚨 The toggle that cost me 20 minutes
Inside the Gmail node, there’s a setting called “Simplify”. It’s toggled ON by default. When it’s on, you only get a stripped-down version of the email data, not the full HTML content. I spent 20 minutes debugging why my Code node was outputting “no content found” before I found this. Turn Simplify OFF. You need the full email data for the HTML cleaning step to work

This code node strips it down to readable text and pulls out useful links. You can copy-paste it exactly, no changes needed:

return items.map(item => {
  let html = item.json.html || "";
  const links = [];
  const linkRegex = /<a[^>]+href="([^"]+)"[^>]*>(.*?)<\/a>/gi;
  let match;
  while ((match = linkRegex.exec(html)) !== null) {
    const url = match[1];
    const text = match[2].replace(/<[^>]+>/g, "").trim();
    if (url && !url.includes("unsubscribe") &&
        !url.includes("preferences") && text.length > 3) {
      links.push({ text, url });
    }
  }
  let cleanText = html
    .replace(/<style[\s\S]*?<\/style>/gi, '')
    .replace(/<script[\s\S]*?<\/script>/gi, '')
    .replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
  return { json: {
    subject: item.json.headers?.subject || "No Subject",
    content: cleanText.slice(0, 4000),
    links: links.slice(0, 5)
  }};
});

In plain English: it removes all the HTML styling and junk, keeps only readable text, filters out unsubscribe/preference links, and caps the content at 4000 characters so the AI node doesn’t choke.

Node 4 > AI (the prompt matters more than the model)

image 5

I used Gemini for this, but OpenAI or Claude work equally well. The model is not the variable that determines quality. The prompt is.

Most people write “summarize this email” and then complain that AI summaries are generic. The problem is that “summarize” is too vague. The AI doesn’t know what you care about.

Here’s the prompt I use:

You are a sharp operator who summarizes newsletters for founders.

Your job is to extract signal, not summarize everything.

Focus on:
- key insights
- strategic implications
- trends
- actionable ideas

Ignore:
- fluff
- storytelling
- self-promotion
- ads

---

INPUT:
Subject: {{$json["subject"]}}

Content:
{{$json["content"]}}

---

OUTPUT FORMAT:

🧠 TL;DR

Title: (rewrite if needed to make it sharper)

• 3–5 bullet points (only high-signal insights)
• Keep each bullet crisp (max 1 line)

🔗 Links:
- Extract and include any important URLs (if present)

⚡ Why it matters:
(1 sharp line for a founder/operator)

---

Rules:
- Keep total output under 120 words
- Be brutally concise
- No generic statements
- No repetition
- If content is low quality, say: "No strong signal"

Node 5 > Slack (the final delivery)

Create a Slack app at api.slack.com/apps, get the OAuth token (it’s under OAuth & Permissions after you add the bot:chat:write scope), and paste it into n8n’s Slack credential.

Point the Slack node at a channel, I use #email-newsletter, and set the message content to the AI node’s output.

image 6

That’s it. Every morning that channel fills up with clean summaries. No inbox. No decisions.


Three things I learned building this

1. Clean inputs beat better models

When I skipped the HTML cleaning step, the AI summaries were genuinely terrible, full of button labels and tracking URL fragments. Fixing the input improved the output more than switching models ever would.

2. Read the node settings, not just the docs.

The Simplify toggle in the Gmail node is exactly the kind of thing that’s easy to miss and costs you 20 minutes of debugging. Most workflow tools have hidden settings like this. When something returns empty, check the node configuration before touching the code.

3. Simple systems get used. Complex ones get abandoned.

I’ve built fancier things. Multi-agent setups. Notion databases with auto-tagging. Most of them sit unused. This one runs every day because it does exactly one thing and nothing breaks.


Next step

Once the base flow is working, the natural extensions are:

  • Pipe summaries into a Notion database to build a searchable knowledge base over time
  • Add a second AI node to categorize by topic (marketing, product, funding, etc.) and route to different Slack channels
  • Extract only the links and save to a reading list for later
  • Apply the same pattern (label → fetch → clean → AI → deliver) to any other high-volume input — support emails, Reddit threads, competitor blogs

Start with one flow. Get it running. The pattern is reusable.


Final thought

The real skill here isn’t JavaScript or n8n. It’s thinking in systems, seeing a problem as input, processing, and output, and asking what needs to happen at each stage.

Once you see it that way, you can apply the same logic to almost anything. Inbox overload is just one version of a much broader problem: too much incoming, not enough clarity. Build a layer that filters it and you get your attention back.

This took me an afternoon to build. It’s saved me time every day since.

Get In Touch

Let's Build Something Useful

If you’re building a product and want to move faster, let’s talk.