> ## Content Index
> Fetch the complete content index at: https://www.implicator.ai/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to build an AI email manager with Claude and n8n
- URL: https://www.implicator.ai/how-to-build-an-ai-email-manager-with-claude-and-n8n/
- Published: 2026-03-03T11:00:58.000Z
- Updated: 2026-10-21T15:21:37.000Z
- Description: How to build an AI email manager that classifies 40+ categories, drafts context-aware replies, and waits for your approval. Complete tutorial with code.
- Author: Marcus Schuler
- Tags: Implicator PRO Briefing

***Implicator PRO Briefing / 3 Mar 2026***

|                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Pro Members Only A complete build guide for an AI email triage system that costs a dollar a day. Classification workflows, context-aware draft generation, Slack-based human review, and the spreadsheet feedback loop that pushes accuracy from 85% to 95%. New to Implicator PRO? [Subscribe for $8/month](https://www.implicator.ai/become-an-implicator-pro-member/) — new deep dive every Tuesday morning PST. |
|                                                                                                                                                                                                                                                                                                                                                                                                                     |

You wake up, reach for your phone, and the badge says 147\. Not notifications. Emails. Half of them arrived while you slept, from servers that don't care about time zones. Shipping updates, payment receipts, subscription renewals, LinkedIn connection requests from faces you don't recognize.

Somewhere in that pile, a conference organizer wants you on stage next month. A client needs an answer before lunch. A potential partner is waiting on your proposal before their board meets Friday.

Good luck finding any of them.

Gmail filters work until they don't. You can route newsletters to a folder, sure. But the interesting pitch from a PR person who sends from a personal @gmail.com? That slips through every rule you can write. Rules-based systems break the moment the world stops being neat. And the world stopped being neat around email number 50.

The commercial alternatives aren't much better. SaneBox, Superhuman, Shortwave. They all promise inbox zero through some mix of AI and aggressive UI design. They work, mostly, for a while. But they're black boxes. You can't see the classification logic. You can't fix the mistakes. When the system buries something important under "not now," you might not notice for days. That's an expensive kind of wrong.

Commercial email services like Superhuman and Hey charge between $25 and $40 per month to win you as a customer. If you invest a bit more time using tools like Claude or ChatGPT's code capabilities, you can host similar services for much less money.

So I built one. Runs on a mini PC in my office, costs about a dollar a day in API calls. It shows its work. And it waits for me to approve every outgoing word.

The system handles two Gmail accounts. It classifies every incoming email into one of 40+ categories using [Claude Haiku](https://www.anthropic.com/pricing?ref=implicator.ai), Anthropic's fastest model. For emails that need a reply, it generates context-aware drafts with Claude Sonnet. Every draft gets posted to a Slack channel with Approve, Edit, and Reject buttons. Nothing sends without a human pressing a button.

And it gets smarter over time. When classification goes wrong, I type the correct label in a spreadsheet. That fix feeds back into the next cycle's prompt. No model fine-tuning. No machine learning pipeline. Just a Google Sheet and a well-constructed prompt.

What follows is a build guide. Not a developer project, exactly, but you should know your way around code and API credentials. The whole thing runs on [n8n](https://n8n.io/?ref=implicator.ai), an open-source workflow automation platform. Zapier's self-hosted cousin, with a proper code editor. If you've touched any visual workflow tool before, you'll recognize the patterns.

What makes this approach different from off-the-shelf email AI? Three things.

You pick the models. Haiku handles classification at a fraction of a cent per email because sorting doesn't need a powerful model. Sonnet handles drafting, where quality matters. Matching model capability to task complexity is how you keep costs sane.

You own the logic. Every classification rule, every routing decision, every prompt lives in your workflow. Something breaks? You open the workflow, see exactly where it failed, and fix it in minutes.

And you stay in the loop. The AI drafts. You decide. That's not a limitation. That's the feature.

### Tech stack

- [n8n](https://n8n.io/?ref=implicator.ai) — Open-source workflow automation (self-hosted or cloud)
- [Claude Haiku 4.5](https://www.anthropic.com/pricing?ref=implicator.ai) — Fast, cheap model for email classification
- [Claude Sonnet 4](https://www.anthropic.com/pricing?ref=implicator.ai) — Capable model for draft reply generation
- **Gmail API** — Email access, labels, drafts, and push notifications
- **Google Sheets** — Data persistence, feedback loop, contact memory
- **Slack** — Human review interface with approve/edit/reject buttons
- **Google Cloud Pub/Sub** — Optional, for real-time email notifications

### Hardware: what to run it on

n8n runs comfortably on any mini computer. The workflows in this guide use minimal CPU and memory. A few options:

- **Beelink Mini S13 Pro (\~$199)** — Budget pick. Enough for n8n and light automation. Draws about 35W under load.
- **Beelink SER5 Pro (\~$289)** — AMD Ryzen 5, 16GB RAM. Handles n8n plus other self-hosted services without breaking a sweat.
- **Mac Mini M4 ($499)** — Premium option. 5W at idle, 20W under load, silent. Runs Docker and n8n natively. The base 16GB model is more than enough.

Any of these will handle two Gmail accounts and a hundred daily emails without stress. The total power draw is low enough that electricity costs are negligible.

## Every email workflow starts with the same problem

Before getting into code, it helps to understand what "email triage" actually requires.

A human processing email does four things, usually without thinking about them. You identify the sender and their relationship to you. You classify the email by type: newsletter, invoice, a request that needs a response? You decide on an action: reply, archive, flag for later. And if you reply, you draw on context, what you discussed last time, what you know about this person, the tone that fits the relationship.

Gmail filters handle step two, barely. AI handles all four, but with a catch: it hallucinates details you'd never get wrong, like your own availability or the name of a project you're working on.

The system I'm describing solves this by splitting work between three layers.

**Layer one: triage.** A fast, cheap AI model reads every incoming email and assigns a label. "Newsletter." "Invoice." "Action Needed." "PR." It also scores confidence, urgency, and sentiment. Emails that need a reply get flagged. Everything else gets sorted and archived. This runs every time a new email arrives.

**Layer two: draft generation.** A more capable AI model takes flagged emails and writes a reply. Before it writes a word, the system fetches the full conversation thread, the sender's contact history, and any relevant knowledge from a reference sheet. The draft gets saved in Gmail and posted to Slack for review.

**Layer three: human review.** You see the draft in Slack with three buttons. Approve keeps it. Edit opens Gmail so you can tweak it. Reject deletes it. Nothing leaves your outbox without explicit approval.

Your emails never leave your own infrastructure. The AI processes the text and returns a classification or a draft. No training on your data, no third-party email access beyond the APIs you configure yourself. If you self-host n8n, the entire pipeline runs on hardware you control.

## The sorting machine

![Email classification workflow](https://www.implicator.ai/content/images/2026/03/2026-03-02-19.47.07-email_sorting@2x.webp)

The triage workflow runs on a simple loop. Every ten minutes, or instantly if you set up push notifications, it fetches unread, unlabeled emails from Gmail, runs them through Claude Haiku, and applies the classification.

Seven stages, each feeding into the next.

**Fetch emails.** An n8n Schedule Trigger fires every ten minutes. A Gmail node pulls up to ten unread emails that don't already have a user-applied label:

```
in:inbox is:unread -has:userlabels

```

That filter matters. By targeting only emails without labels, you guarantee the system never reprocesses an email it's already classified. You don't need flags or read receipts. The label itself is the marker.

**Fetch available labels.** Classification needs a vocabulary. You can't sort into categories the model has never heard of. So an HTTP Request node calls the [Gmail API](https://developers.google.com/gmail/api?ref=implicator.ai) to pull every label from your account, and a Code node filters down to the user-created ones:

```javascript
const response = $input.first().json;
const labels = response.labels || [];
const userLabels = labels
  .filter(l => l.type === 'user')
  .sort((a, b) => a.name.localeCompare(b.name));

const labelList = userLabels
  .map(l => `- ${l.name} (ID: ${l.id})`)
  .join('\n');

return [{ json: { labelList, labels: userLabels } }];

```

Why fetch labels at runtime instead of hardcoding them? You'll add labels. Rename others. Maybe create a whole new category for a client who emails too much. If the AI's list is stale, it'll try to assign categories that don't exist. Runtime discovery means the system adapts the moment you add a new label in Gmail. Zero config updates.

**Build corrections context.** This is where the feedback loop lives. More on that later, but the short version: the system fetches recent classification corrections from a Google Sheet and injects them into the AI's prompt as few-shot examples. "Last time you saw an email like this, you called it X. The correct answer was Y."

**Classify with Claude Haiku.** The AI Agent node is where the sorting happens. The system prompt defines 40+ label categories with descriptions, classification rules, and a structured output schema:

```json
{
  "label": "Action Needed",
  "labelId": "Label_42",
  "needsReply": true,
  "shouldArchive": false,
  "confidence": 0.92,
  "urgency": "high",
  "sentiment": "neutral"
}

```

Temperature is set to zero. That makes classification deterministic. Feed the same email through twice, get the same answer. For sorting, you want consistency over creativity.

The triage prompt also gives the AI two tools it can call: one to check if you've previously sent emails to an address (indicating an existing relationship), and one to search for past emails from a sender. When classification is ambiguous, the AI checks your history before deciding.

Here's a stripped-down version of the classification rules that go into the prompt:

```
You are an email classification agent. Analyze each incoming email and:
1. Assign the most appropriate Gmail label
2. Determine if it needs a reply
3. Decide if it should be auto-archived
4. Rate your confidence (0-1)
5. Assess urgency and sentiment

CRITICAL: Partnership vs Sales distinction.
Someone proposing a genuine collaboration or project = Action Needed.
Someone pitching THEIR product or service for you to buy = Sales.

Domain match first: @amazon.com → Amazon Orders, @stripe.com → Stripe

needsReply: true only for real humans expecting a response.
Automated emails, newsletters, receipts = false, always.

```

The partnership-versus-sales rule is worth a closer look because it's the kind of distinction that trips up every AI classifier. Both email types come from unfamiliar senders. Both mention collaboration. Both include pleasantries. The difference is directional, who's offering value and who's extracting it. Spelling this out in the prompt fixes a mistake that would otherwise repeat constantly.

**Route by action.** After classification, a Code node evaluates three conditions:

```javascript
const confidence = typeof output.confidence === 'number'
  ? output.confidence
  : parseFloat(output.confidence) || 0;
const isLowConfidence = confidence < 0.85;

```

Emails that need a reply get a `generate-reply` label applied, which triggers the draft workflow. Emails marked for archive get removed from the inbox. Low-confidence classifications (below 85%) fire a Slack alert for manual review.

That threshold is adjustable. Set it higher and you'll get more alerts. Lower and you'll miss more mistakes. Start at 85% and tune based on how many corrections you're actually making in the first week.

**Log everything.** Every classification gets appended to a Google Sheet: timestamp, sender, subject, label, confidence, urgency, sentiment, and message ID. This sheet is your audit trail and your training data.

## Teaching the AI to write like you

Classification is pattern matching. Draft replies are harder. The AI needs to sound like you, reference conversations it didn't have, and know things it was never trained on. Context injection does the heavy lifting here.

The draft reply workflow polls every two minutes for emails tagged with `generate-reply`. For each one, it gathers context from four sources, generates a draft with Claude Sonnet, and sends it for review.

**Thread history.** The workflow fetches the full Gmail thread via the API and extracts the last five messages. Without thread context, the AI writes replies to ongoing conversations as if they're first contact. With it, the reply references prior commitments and builds on what's been discussed.

```javascript
const contextMessages = messages.slice(-6, -1).slice(-5);

const formatted = contextMessages.map(msg => {
  const headers = msg.payload?.headers || [];
  const from = headers.find(
    h => h.name.toLowerCase() === 'from'
  )?.value;

  let body = '';
  const parts = msg.payload?.parts || [];
  if (parts.length > 0) {
    const textPart = parts.find(p => p.mimeType === 'text/plain');
    if (textPart?.body?.data) {
      body = Buffer.from(textPart.body.data, 'base64')
        .toString('utf-8');
    }
  }

  if (body.length > 500) body = body.substring(0, 500) + '...';
  return `**${from}**:\n${body}`;
}).join('\n\n---\n\n');

```

**Contact memory.** A Google Sheet stores what the system knows about each sender. Name, domain, preferred language, how often they write, what they write about, plus any notes you've scribbled in by hand. Before generating a draft, the workflow fetches that sender's row and builds a context block.

If someone has written eight times before, the AI adjusts its tone. If their language preference is Spanish, it writes in Spanish. If your notes say "prefers formal address," the AI opens with "Estimado" instead of "Hi." This is a CRM you never have to maintain. It updates itself on every incoming email.

**Knowledge base.** A separate sheet tab acts as a lightweight retrieval system. Each row holds a topic, content block, and tags. When a reply is being generated, the workflow scores every entry against the sender's domain, the subject line, and past topics. The three best matches get stuffed into the prompt.

```javascript
const scored = rows.map(row => {
  const tags = (row.Tags || '').toLowerCase();
  const topic = (row.Topic || '').toLowerCase();
  let score = 0;

  if (tags.includes(senderDomain)) score += 3;
  if (topic.includes(senderDomain)) score += 2;

  const subjectWords = subject.split(/\s+/)
    .filter(w => w.length > 3);
  for (const word of subjectWords) {
    if (tags.includes(word)) score += 2;
    if (topic.includes(word)) score += 1;
  }

  return { ...row, score };
}).filter(r => r.score > 0);

scored.sort((a, b) => b.score - a.score);
const top = scored.slice(0, 3);

```

Skip the vector embeddings and the similarity search. Just keyword matching against a spreadsheet. Maybe 30-50 rows, tops. It works because the knowledge base is small and curated. When someone emails asking about pricing, the word "pricing" matches a row that contains your pricing details. The AI includes that in its reply naturally, without you typing it for the hundredth time.

**Style examples.** The system pulls actual past replies from a style examples sheet, matched by language, sender domain, tone, and category. These work as few-shot examples showing the AI how you write. Not "be professional." Instead: here are three replies you actually sent in similar situations. Match this voice.

All four sources get concatenated and appended to the system prompt. Then Claude Sonnet generates the draft.

There's a catch with n8n's built-in Gmail node, though. A bug in the node drops the "To" header when creating drafts. Annoying. The workaround is building an RFC 2822 MIME message by hand:

```javascript
let mime = 'To: ' + toHeader + '\r\n';
mime += 'Subject: Re: ' + subject + '\r\n';
mime += 'Content-Type: text/plain; charset=utf-8\r\n';
if (originalMessageId) {
  mime += 'In-Reply-To: ' + originalMessageId + '\r\n';
  mime += 'References: ' + originalMessageId + '\r\n';
}
mime += '\r\n' + body;

const raw = Buffer.from(mime).toString('base64url');

```

The `In-Reply-To` and `References` headers tell Gmail where to thread the reply. Drop them and your response lands as a separate conversation, which confuses everyone. The signature gets fetched at runtime from Gmail's settings API and appended automatically, HTML converted to plain text. One less thing to hardcode.

## The part where you stay in control

![Human review with approve, edit, reject buttons](https://www.implicator.ai/content/images/2026/03/2026-03-02-19.47.55-email_approve@2x.webp)

After a draft is created, the workflow builds a Slack message with Block Kit formatting: sender info, subject line, a preview of the draft, and three buttons.

Approve marks the draft as reviewed. It stays in Gmail, ready to send. You open Gmail, glance at it, hit send.

Edit opens Gmail's compose window with the draft loaded. Tweak a sentence, add a detail the AI got wrong, send.

Reject deletes the draft entirely. The AI got it wrong, or you decided not to reply. No loose drafts cluttering your account.

The handler for these buttons is its own n8n workflow. A webhook receives Slack's interactive message payload, routes by which button was pressed, performs the action, and updates the Slack message to confirm. Eight nodes total.

This matters more than it looks. Most AI email tools fail for a reason people don't expect. The writing is fine. The problem is that the AI sends without asking. When an auto-response gets the tone wrong, or invents a detail you'd never say, the person reading it feels something shift. They might not call it out. But the next email is shorter. The replies slow down. Once a client suspects they're talking to a bot, rebuilding that trust takes months.

Approve, edit, reject. Three buttons that keep the AI's output where it belongs, as a suggestion. Never a decision. And if you reject every single draft, the system still saves you time through classification and sorting alone.

![The feedback loop: corrections flow back into classification](https://www.implicator.ai/content/images/2026/03/2026-03-02-19.49.07-email_feedback@2x.webp)

**The feedback loop.** Expect classification mistakes. Lots of them, in the first week especially. The system handles this through a corrections column in the triage Google Sheet.

Say the AI labels something "Newsletter" when it should have been "Action Needed." You open the sheet, type the right label in the CorrectLabel column, and move on. Next time the workflow runs, it picks up that correction and does two things.

First, it fixes Gmail directly, strips the wrong label and sticks on the right one. Type a label name that doesn't exist yet? The workflow builds it for you.

Second, and this is the part that compounds, it injects the correction into future prompts:

```javascript
const examples = corrections.map(c =>
  `- Email from "${c.From}" with subject "${c.Subject}"
     was classified as "${c.Label}" but the correct
     label was "${c.CorrectLabel}"`
).join('\n');

```

A dozen corrections in and the edge cases mostly stop repeating. The system gets better without any model training. Just prompt examples from a spreadsheet.

And the contact memory works on the same principle. Each classified email updates the sender's record: interaction count goes up, the label gets added to their topic list, the timestamp refreshes. Next time this person writes, the draft generator knows who they are. Over weeks, you end up with a sender database you never had to build manually. It built itself.

## Making it instant

The default setup polls every ten minutes. For most people, fine. But if you want classification within seconds of an email arriving, Google Cloud Pub/Sub lets Gmail push notifications directly to your system.

Three components. A Pub/Sub topic in Google Cloud Console. A push subscription pointed at your n8n webhook URL. And a handler workflow that decodes the notification and triggers the right triage workflow.

The handler is six nodes:

```
Webhook → Respond 200 → Decode Pub/Sub → Route by Account → Trigger Triage → Log

```

The notification arrives as a base64-encoded JSON blob:

```javascript
const message = body.message || {};
const data = message.data || '';

let decoded = {};
if (data) {
  const raw = Buffer.from(data, 'base64').toString('utf-8');
  decoded = JSON.parse(raw);
}

return [{
  json: {
    emailAddress: decoded.emailAddress || '',
    historyId: decoded.historyId || ''
  }
}];

```

The handler maps the email address to the correct triage workflow and fires it via n8n's REST API. Running multiple accounts? Each one gets its own triage workflow.

One gotcha. Gmail push watches expire after seven days. The fix is a renewal workflow. Three nodes: poll every six days, hit Gmail's watch endpoint, send yourself a Slack confirmation that it worked. Took me ten minutes to build. Haven't touched it since.

Worth flagging: the handler sends a 200 back to Google before doing anything else. Pub/Sub expects an acknowledgment within seconds. If your handler waits for triage to finish before responding, Pub/Sub retries, and you get duplicate triggers. Acknowledge first, process second.

Your n8n instance needs to be reachable from the internet for push to work. Reverse proxy with a public domain. The ten-minute polling fallback still runs as a safety net, so if Pub/Sub hiccups, you're covered within the next cycle.

**Running costs:** Claude Haiku 4.5 runs at $0.80 per million input tokens and $4.00 per million output tokens. At roughly 1,000 tokens per classification, triage costs about half a cent per email. Claude Sonnet 4 at $3/$15 per million tokens runs about a cent per draft reply. For two accounts processing 100 emails daily, with 10-15 requiring draft replies, AI costs land between $0.60 and $1.30 per day. The n8n instance is free if self-hosted. Google Sheets and Gmail API have generous free tiers.

## The pattern worth stealing

Forget email for a moment. The architecture underneath this system applies to any workflow where you need AI to process, classify, and generate, but don't trust it enough to act alone.

Three principles.

**Match the model to the task.** Don't spend $15 per million output tokens on classification. Don't ask a $4-per-million model to write your emails. The cheapest model that produces reliable output at a given task is the right model for that task. For categorical decisions, fast and cheap wins every time. For anything creative, capability matters.

**Build memory from spreadsheets.** Vector databases and retrieval pipelines get all the conference talks. Google Sheets solves the same problem for personal automation with zero infrastructure. A corrections column is a feedback loop. A contacts tab is a CRM. A context tab is a knowledge base. If your dataset fits in 50 rows, a spreadsheet is the right database. Migrate when you actually outgrow it. You probably won't.

**Keep the human at the decision point.** The value of AI in personal workflows isn't replacing your judgment. It's doing the prep work that makes your judgment faster. Scroll through 147 emails to find the three that matter, or let a model sort them and show you just those three? Same decision, smaller surface area.

The temptation with any AI automation is to remove yourself from the loop entirely. Resist it. Fully automated email responses are a career risk. Fully automated classification with human-reviewed drafts is a productivity tool. The line between those two things is one button.

This system took a weekend to build and has been running daily for months. The AI gets classification right roughly 95% of the time after a few weeks of corrections. The drafts need editing maybe half the time, mostly for specific details the AI couldn't know. On a good day, it saves 30-45 minutes. On a bad day with a flooded inbox, closer to two hours.

The tools here, n8n, Claude, Gmail API, are not the only way to build this. You could use Make instead of n8n. GPT-4o mini instead of Haiku. The Outlook API instead of Gmail. The architecture transfers because the problem transfers. Every inbox is the same problem in different fonts.

## What to watch

- **Prompt caching for classification:** Anthropic's prompt caching feature can cut triage costs by another 50-70% for the system prompt and label list, which stay identical across emails. If you're processing hundreds of emails daily, this moves the math from cheap to effectively free.
- **n8n's AI agent updates:** The platform ships agent improvements monthly. Structured output parsing and error output routing already made this system possible without custom code servers. Native MCP tool support would let the AI agent call external APIs directly during classification, removing the need for separate tool nodes.
- **Gmail API notification reliability:** Google has been inconsistent about Pub/Sub delivery guarantees for Gmail. The dual-trigger approach (push plus polling fallback) exists because of this. If Google ships a more reliable notification mechanism, the polling backup becomes optional.
- **Model cost curves:** When Haiku 4.5 launched, classification costs dropped 60% from the previous cheapest option. The next generation of small models will push triage toward effectively zero cost, making it viable to run AI classification across every account in an organization.
- **Agentic email workflows:** Browser-based agents like Claude's computer use could eventually handle the edit step directly, opening the draft, making changes, clicking send, within the review workflow. At that point, approve means send. One tap, done. Still early days for that, but the pieces exist.

### Key takeaways

- **Cheap models sort, expensive models write:** Using Haiku for classification ($0.005/email) and Sonnet for drafting ($0.01/email) keeps total AI costs below $1.30/day for 200 emails across two accounts.
- **Spreadsheets replace databases at small scale:** Google Sheets handles feedback loops, contact memory, and knowledge retrieval without infrastructure beyond what you already have. Migrate when you outgrow it, not before.
- **The approve button is the product:** Reducing 147 emails to 3 draft-review decisions is where the time savings live. Everything else is preprocessing for that moment.
- **Corrections compound without training:** A dozen fixes in a spreadsheet column, injected as prompt examples, push classification accuracy from around 85% to 95% within weeks. No fine-tuning pipeline required.
- **Runtime label discovery prevents drift:** Fetching Gmail labels at execution time means you never update your automation config when you add new categories. The system adapts on every run.
- **Context beats capability:** Thread history, contact memory, and a 50-row knowledge base concatenated into a prompt give a mid-tier model most of the benefit of a custom-trained one. The retrieval is simple keyword matching. It works because the dataset is small and curated.

### Sources & further reading

#### Primary sources

- [n8n documentation](https://docs.n8n.io/?ref=implicator.ai) — Workflow automation platform, self-hosted or cloud
- [Anthropic Claude pricing](https://www.anthropic.com/pricing?ref=implicator.ai) — Current model pricing for Haiku 4.5, Sonnet 4, and Opus
- [Gmail API reference](https://developers.google.com/gmail/api?ref=implicator.ai) — Full API documentation for email access, labels, and drafts
- [Gmail push notifications guide](https://developers.google.com/gmail/api/guides/push?ref=implicator.ai) — Setting up Pub/Sub for real-time email triggers

#### Technical references

- [n8n AI Agent node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent/?ref=implicator.ai) — Documentation for the AI agent node with tool calling
- [n8n error handling](https://docs.n8n.io/flow-logic/error-handling/?ref=implicator.ai) — Error workflows and continue-on-fail patterns
- [Slack Block Kit reference](https://api.slack.com/reference/block-kit?ref=implicator.ai) — Building interactive messages with buttons

#### Further reading

- [Human-in-the-loop automation](https://blog.n8n.io/human-in-the-loop-automation/?ref=implicator.ai) — n8n's guide to building approval workflows
- [RFC 2822: Internet Message Format](https://datatracker.ietf.org/doc/html/rfc2822?ref=implicator.ai) — The standard behind MIME message construction for email threading

---