Every inbox has the same problem: most emails don't need a response, but the ones that do need a good one fast. Manually reading every email to decide which category it falls into is pure wasted time — especially for customer-facing inboxes that receive a mix of actual customer questions and everything else.

I built a workflow in n8n called "Customer Flow" that handles this automatically. New emails hit Gmail, an AI classifier decides if they're from a customer, and if they are — the agent searches a Pinecone knowledge base and sends a reply. Everything else gets silently dropped. Here's how it works.

What you'll need A self-hosted n8n instance, Gmail connected via OAuth, a Pinecone index with your knowledge base loaded, a free OpenRouter account, and optionally a Slack workspace for notifications. All free to run.

The Full Workflow

n8n Customer Flow workflow — Gmail trigger, Text Classifier, two paths: AI Agent with RAG reply vs No Operation, plus Slack nodes

The complete "Customer Flow" — Gmail → classify → either reply with RAG or do nothing

Reading from left to right: Gmail Trigger fires on every new email. A Text Classifier node decides whether it's a customer email or something else. Customer emails go up to the AI Agent which uses Pinecone to find relevant answers and sends a reply via Gmail. Everything else goes to a "No Operation" node — effectively discarded. On the right, two Slack nodes handle channel cleanup as part of a broader notification setup.

Step 1 — Gmail Trigger

The Gmail Trigger node fires every time a new email arrives in the connected inbox. In n8n, add the node, authenticate with your Google account via OAuth, and set it to trigger on new messages. You can optionally filter by label — for example only watching a specific "Support" label — to avoid processing internal emails or newsletters.

The trigger outputs the full email: subject, body, sender address, thread ID, and message ID. All of these flow into the next node.

Step 2 — Text Classifier

This is the decision point. The Text Classifier node uses an AI model to read the email and route it to one of two outputs. I configured two categories:

The Text Classifier connects to its own OpenRouter Chat Model node for the classification step. This keeps classification separate from reply generation — two different model calls, each focused on one job.

The classifier prompt is simple but specific:

Classify this email into one of two categories:
- "gmail": a real customer asking a question, requesting support, 
  or sending a genuine enquiry
- "other": newsletters, automated emails, spam, or internal messages

Email subject: {{ $json.subject }}
Email body: {{ $json.text }}

Reply with only the category name: gmail or other
⚠ Keep the classifier output strict If the model outputs "Gmail" with a capital G or adds extra text, the routing breaks. Explicitly tell it to output only the exact category name in lowercase. Adding "Reply with only the category name" at the end eliminates most formatting issues.

Step 3a — Customer Path: AI Agent + RAG Reply

When the classifier outputs gmail, the email goes to the AI Agent node. This agent has two things connected to it: an OpenRouter Chat Model for generating the reply, and a Pinecone Vector Store as a tool for searching the knowledge base.

The flow inside the agent: it reads the email, searches Pinecone for relevant FAQ content, and uses that to write a reply. Because it's using RAG, the reply is grounded in your actual documentation — not a generic AI response.

The system prompt for the agent:

You are a customer service assistant replying to customer emails 
on behalf of the business.

You have access to a knowledge base tool. Always search it before 
replying — your answers must be based on what you find there.

Guidelines:
- Be professional but friendly
- Keep replies concise — 3-5 sentences unless more detail is needed
- If you can't find an answer in the knowledge base, say you'll 
  follow up rather than guessing
- Sign off as "The Support Team"

The customer's email:
Subject: {{ $json.subject }}
Message: {{ $json.text }}

Sending the reply

Once the agent generates the reply text, it flows to a Reply to a Message Gmail node. This sends the reply in the same thread as the original email — so it appears as a proper reply in the customer's inbox, not a separate new email. Set the Thread ID and Message ID from the trigger output to keep the thread intact.

The combination of classification + RAG means the reply isn't just automated — it's accurate. The agent only replies when it's confident it has relevant knowledge, and the content comes from your own documentation, not hallucinated facts.

Step 3b — Other Path: No Operation

When the classifier outputs other, the workflow routes to a No Operation node — which does exactly nothing. The email is ignored. No reply, no storage, no notification. This keeps the system clean and avoids accidentally auto-replying to mailing lists or automated system emails.

You could replace this with a Label node to mark non-customer emails in Gmail, or an archive node to keep the inbox tidy. For my use case, doing nothing was the right call.

The Slack Nodes

On the right side of the workflow, two Slack nodes — Close a Channel and Delete a Message — handle cleanup in a connected Slack workspace. These run in parallel with the email reply path as part of a broader customer communication workflow: when a customer email is resolved, the associated Slack thread gets cleaned up automatically. This keeps the support workspace tidy without manual intervention.

What I'd Do Differently

Add a confidence threshold. The Text Classifier sometimes misclassifies edge cases — a newsletter that reads like a genuine question, or an automated order confirmation. Adding a second check that reviews borderline classifications before routing would improve accuracy. n8n's IF node can handle this by checking the classifier's output against specific keywords.

Log every classified email. Right now there's no record of what came in and how it was classified. Adding a Google Sheets append node that logs the sender, subject, classification result, and timestamp would make the system auditable — useful if a client ever asks why a particular email didn't get a response.

Add a human review step for replies. Sending fully automated replies carries risk. A safer version sends a draft reply to a Slack channel first, where a human can approve or edit before it goes out. n8n's Slack integration makes this straightforward — hold the reply, post to Slack with approve/reject buttons, then send only after approval.

Conclusion

The workflow has 7 active nodes and handles the full triage cycle: receive, classify, retrieve, reply. Once set up it runs silently in the background — customer emails get answered within seconds, everything else is ignored.

The most valuable part isn't the automation itself — it's the combination of classification and RAG. Classification prevents the agent from replying to things it shouldn't. RAG ensures the replies it does send are accurate. Together they make a system you can actually trust to run unsupervised.

For a small business receiving 20-50 customer emails a day, this eliminates hours of repetitive work per week while maintaining reply quality. That's the pitch when selling this to clients — not "AI email", but "your response time drops from hours to seconds, and the answers are consistent every time."