Build email-powered automations in n8n. Process support tickets, invoices, leads, and more — triggered instantly when emails arrive.
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.
n8n's built-in IMAP node works, but it has friction:
For simple use cases, this is fine. For production workflows, you want something more reliable.
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.
We've built a community node for n8n that makes setup even easier:
# Install in your n8n instance
npm install n8n-nodes-mailhooksOr install via n8n's Community Nodes settings panel.
The node provides:
If you prefer not to install community nodes, use n8n's built-in Webhook node:
You'll get an email address like [email protected]
Send an email to your new address. Watch n8n execute instantly.
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.
Automatically create tickets when customers email:
[Webhook] → [Notion] Create Page
→ [Slack] Notify #support
Notion node config:
{{ $json.subject }}{{ $json.from }}{{ $json.text }}Slack node config:
📧 New ticket from {{ $json.fromName }}: {{ $json.subject }}When leads email your sales address:
[Webhook] → [HubSpot] Create Contact
→ [Gmail] Send Auto-Reply
→ [Slack] Notify #sales
HubSpot node:
{{ $json.from }}{{ $json.fromName.split(' ')[0] }}{{ $json.text }}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: FileAcknowledge emails immediately:
[Webhook] → [Gmail] Send Reply
Gmail node:
{{ $json.from }}Re: {{ $json.subject }}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 }}
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 }}'
)Mailhooks provides direct URLs for attachments. Download them in n8n:
[Webhook] → [IF] Has Attachments?
→ [HTTP Request] Download File
→ [Google Drive] Upload
HTTP Request config:
{{ $json.attachments[0].url }}Google Drive config:
{{ $json.attachments[0].filename }}Use a Loop Over Items node:
[Webhook] → [Split In Batches] attachments array
→ [HTTP Request] Download each
→ [Google Drive] Upload each
[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') }}[Webhook] → [Switch] Check subject keywords
contains "urgent" → [High priority]
contains "invoice" → [Accounting]
default → [General inbox]
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@') }}Mailhooks queues failed webhooks and retries automatically:
Your emails aren't lost if n8n restarts or has downtime.
Check webhook status in Mailhooks dashboard:
| Feature | Mailhooks Node | n8n IMAP Node |
|---|---|---|
| Latency | Instant (< 10s) | 1-5 minutes |
| Setup | 2 minutes | 15+ minutes |
| OAuth management | None | Token refresh needed |
| Email parsing | Pre-parsed JSON | Raw MIME |
| Attachments | Direct URLs | Base64 encoded |
| Downtime handling | Queued + retries | Emails missed |
| Multiple addresses | Unlimited catch-all | One per credential |
| Community node | ✅ n8n-nodes-mailhooks | Built-in |
Instead of @yourteam.mailhooks.email, use your own domain:
Now emails to [email protected] trigger your n8n workflows.
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.