Trigger n8n Workflows from Incoming Emails

Build email-powered automations in n8n. Process support tickets, invoices, leads, and more — triggered instantly when emails arrive.

Mailhooks TeamJanuary 28, 20256 min read
n8nautomationworkflowemailwebhook

n8n is brilliant for workflow automation. But when it comes to email triggers, you're stuck with the IMAP node — polling every few minutes, wrestling with OAuth tokens, and parsing raw MIME data.

There's a better way: trigger workflows instantly when emails arrive, with clean JSON payloads ready to use.

The IMAP Problem

n8n's built-in IMAP node works, but it has friction:

  • Polling delays — 1-5 minute intervals, not real-time
  • OAuth headaches — Gmail tokens expire, connections drop
  • MIME parsing — raw email data needs manual extraction
  • No retry logic — if n8n is down during a poll, emails are missed

For simple use cases, this is fine. For production workflows, you want something more reliable.

Email to Webhook

The solution: convert incoming emails to webhooks. Emails arrive → instant HTTP POST to n8n → workflow runs.

Here's how to set it up with Mailhooks.

Two Ways to Connect

Option A: Mailhooks Community Node

We've built a community node for n8n that makes setup even easier:

# Install in your n8n instance
npm install n8n-nodes-mailhooks

Or install via n8n's Community Nodes settings panel.

The node provides:

  • Mailhooks Trigger — fires when emails arrive (real-time, no polling)
  • Mailhooks — fetch emails, list inboxes, manage hooks via API

View on npm →

Option B: Generic Webhook

If you prefer not to install community nodes, use n8n's built-in Webhook node:

Setup: 5 Minutes

1. Create a Webhook Trigger in n8n

  1. Create a new workflow
  2. Add a Webhook node as the trigger
  3. Set HTTP Method to POST
  4. Copy the Production Webhook URL

2. Create a Mailhooks Inbox

  1. Sign up at mailhooks.dev (free tier available)
  2. Go to Dashboard → Inboxes → Create Inbox
  3. Name it (e.g., "n8n Support")
  4. Add a Webhook hook with your n8n URL
  5. Save

You'll get an email address like [email protected]

3. Test It

Send an email to your new address. Watch n8n execute instantly.

The Payload

When an email arrives, your webhook receives clean JSON:

{
  "id": "msg_abc123",
  "from": "[email protected]",
  "fromName": "Jane Customer",
  "to": "[email protected]",
  "subject": "Help with my order #12345",
  "text": "Hi, I haven't received my order yet...",
  "html": "

Hi, I haven't received my order yet...

", "date": "2025-01-28T10:30:00Z", "attachments": [ { "filename": "screenshot.png", "contentType": "image/png", "size": 45678, "url": "https://files.mailhooks.dev/..." } ] }

No MIME parsing. No base64 decoding. Just use {{ $json.from }} in your next node.

Real-World Workflows

Support Ticket from Email

Automatically create tickets when customers email:

[Webhook] → [Notion] Create Page → [Slack] Notify #support

Notion node config:

  • Database: Support Tickets
  • Title: {{ $json.subject }}
  • Customer: {{ $json.from }}
  • Description: {{ $json.text }}

Slack node config:

  • Message: 📧 New ticket from {{ $json.fromName }}: {{ $json.subject }}

Lead Capture from Contact Form

When leads email your sales address:

[Webhook] → [HubSpot] Create Contact → [Gmail] Send Auto-Reply → [Slack] Notify #sales

HubSpot node:

  • Email: {{ $json.from }}
  • First Name: {{ $json.fromName.split(' ')[0] }}
  • Lead Source: "Email Inquiry"
  • Notes: {{ $json.text }}

Invoice Processing

Vendors send invoices to a dedicated address:

[Webhook] → [IF] Has PDF Attachment? Yes → [HTTP Request] Download PDF → [Google Drive] Upload to Invoices folder → [Airtable] Log invoice record No → [Slack] "Invoice missing attachment"

Attachment download:

// In HTTP Request node
URL: {{ $json.attachments[0].url }}
Response Format: File

Auto-Responder

Acknowledge emails immediately:

[Webhook] → [Gmail] Send Reply

Gmail node:

  • To: {{ $json.from }}
  • Subject: Re: {{ $json.subject }}
  • Body: "Thanks for reaching out! We've received your email and will respond within 24 hours."

Order Notifications to Slack

E-commerce order confirmations forwarded to your team:

[Webhook] → [Code] Extract Order Details → [Slack] Post to #orders

Code node:

const text = $json.text;
const orderMatch = text.match(/Order #(\d+)/);
const totalMatch = text.match(/Total: \$?([\d.]+)/);

return {
  orderId: orderMatch ? orderMatch[1] : 'Unknown',
  total: totalMatch ? totalMatch[1] : 'Unknown',
  customer: $json.from
};

Slack message:

🛒 New Order #{{ $json.orderId }} Customer: {{ $json.customer }} Total: ${{ $json.total }}

Email to Database

Archive all emails to a database:

[Webhook] → [Postgres] Insert Row

Postgres node:

INSERT INTO emails (from_address, subject, body, received_at)
VALUES (
  '{{ $json.from }}',
  '{{ $json.subject }}',
  '{{ $json.text }}',
  '{{ $json.date }}'
)

Handling Attachments

Mailhooks provides direct URLs for attachments. Download them in n8n:

Save to Google Drive

[Webhook] → [IF] Has Attachments? → [HTTP Request] Download File → [Google Drive] Upload

HTTP Request config:

  • URL: {{ $json.attachments[0].url }}
  • Response Format: File

Google Drive config:

  • File Name: {{ $json.attachments[0].filename }}
  • Parent Folder: Your folder ID

Process Multiple Attachments

Use a Loop Over Items node:

[Webhook] → [Split In Batches] attachments array → [HTTP Request] Download each → [Google Drive] Upload each

Filtering & Routing

By Sender

[Webhook] → [Switch] Check sender domain @vip-client.com → [Priority handling] @vendor.com → [Invoice processing] default → [Standard queue]

Switch conditions:

{{ $json.from.endsWith('@vip-client.com') }}
{{ $json.from.endsWith('@vendor.com') }}

By Subject

[Webhook] → [Switch] Check subject keywords contains "urgent" → [High priority] contains "invoice" → [Accounting] default → [General inbox]

By Recipient (Catch-All)

With Mailhooks, any address at your domain works:

Route in n8n:

// Switch node
{{ $json.to.includes('support@') }}
{{ $json.to.includes('sales@') }}
{{ $json.to.includes('invoices@') }}

Reliability

What if n8n is Down?

Mailhooks queues failed webhooks and retries automatically:

  • First retry: 1 minute
  • Then: 5 min, 15 min, 1 hour
  • Continues for 24 hours

Your emails aren't lost if n8n restarts or has downtime.

Monitoring Deliveries

Check webhook status in Mailhooks dashboard:

  • Delivered — n8n responded 2xx
  • 🔄 Pending — queued for retry
  • Failed — all retries exhausted

Compared to IMAP

FeatureMailhooks Noden8n IMAP Node
LatencyInstant (< 10s)1-5 minutes
Setup2 minutes15+ minutes
OAuth managementNoneToken refresh needed
Email parsingPre-parsed JSONRaw MIME
AttachmentsDirect URLsBase64 encoded
Downtime handlingQueued + retriesEmails missed
Multiple addressesUnlimited catch-allOne per credential
Community noden8n-nodes-mailhooksBuilt-in

Advanced: Custom Domain

Instead of @yourteam.mailhooks.email, use your own domain:

  1. Add domain in Mailhooks dashboard
  2. Set MX records to Mailhooks servers
  3. Create inboxes with your domain

Now emails to [email protected] trigger your n8n workflows.

Getting Started

  1. Sign up for Mailhooks — free tier includes 100 emails/month
  2. Create an inbox with your n8n webhook URL
  3. Send a test email
  4. Build your workflow

Total setup: 5-10 minutes. No OAuth, no polling, no MIME parsing.


Need help setting up email-triggered workflows? Check our n8n integration docs or reach out.

Ready to receive emails in your app?

Get started with Mailhooks in minutes. No credit card required.