Skip to main content

Forward Important Emails to Slack Automatically

Introduction
#

Important emails often get lost in crowded inboxes. By forwarding critical messages to Slack, you ensure your team sees them immediately. This tutorial shows you how to set up smart email-to-Slack forwarding with n8n.

Download the Workflow
Get the ready-to-use workflow from our n8n Workflow Gallery.

Prerequisites
#

  • An n8n instance
  • Email account with IMAP access (Gmail, Outlook, etc.)
  • Slack workspace with incoming webhooks

Workflow Overview
#

1
Email Trigger (IMAP) → Filter Important → Format Message → Post to Slack

Step-by-Step Setup
#

Step 1: Configure Email Trigger
#

  1. Add an Email Read IMAP node
  2. Configure your email credentials:
    • Host: imap.gmail.com (for Gmail)
    • Port: 993
    • User: Your email
    • Password: App-specific password
  3. Set polling interval (e.g., every minute)
  4. Mailbox: INBOX

Step 2: Filter Important Emails
#

Add a Filter node to only forward relevant emails:

Conditions (match ANY):

1
2
3
4
5
6
7
8
// From important domains
$json.from.includes('@important-client.com')

// Contains urgent keywords
$json.subject.toLowerCase().includes('urgent')

// From VIP senders
['ceo@company.com', 'support@vendor.com'].includes($json.from)

Example filter configuration:

  • from contains @important-domain.com OR
  • subject contains URGENT OR
  • subject contains ACTION REQUIRED

Step 3: Format for Slack
#

Add a Set node to prepare the message:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Truncate long email bodies
const maxLength = 500;
let body = $json.text || $json.html || 'No content';
if (body.length > maxLength) {
  body = body.substring(0, maxLength) + '...';
}

// Clean HTML if present
body = body.replace(/<[^>]*>/g, '');

return {
  from: $json.from,
  subject: $json.subject,
  preview: body,
  date: $json.date
};

Step 4: Post to Slack
#

Add a Slack node:

Channel: #important-emails

Message:

1
2
3
4
5
6
7
šŸ“§ *New Important Email*

*From:* {{ $json.from }}
*Subject:* {{ $json.subject }}
*Received:* {{ $json.date }}

>>> {{ $json.preview }}

Or use Block Kit for richer formatting:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": "šŸ“§ New Important Email"
      }
    },
    {
      "type": "section",
      "fields": [
        {
          "type": "mrkdwn",
          "text": "*From:*\n{{ $json.from }}"
        },
        {
          "type": "mrkdwn",
          "text": "*Subject:*\n{{ $json.subject }}"
        }
      ]
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "{{ $json.preview }}"
      }
    }
  ]
}

Advanced Filtering
#

Filter by Sender Domain
#

1
2
3
4
5
6
7
8
const importantDomains = [
  'client1.com',
  'client2.com',
  'partner.com'
];

const senderDomain = $json.from.split('@')[1];
return importantDomains.includes(senderDomain);

Filter by Keywords
#

1
2
3
const urgentKeywords = ['urgent', 'asap', 'critical', 'emergency', 'action required'];
const subject = $json.subject.toLowerCase();
return urgentKeywords.some(keyword => subject.includes(keyword));

Exclude Newsletters
#

1
2
3
4
5
6
7
8
9
const excludePatterns = [
  'unsubscribe',
  'newsletter',
  'marketing',
  'noreply'
];

const content = ($json.subject + ' ' + $json.from).toLowerCase();
return !excludePatterns.some(pattern => content.includes(pattern));

Route to Different Channels
#

Send emails to different channels based on content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const subject = $json.subject.toLowerCase();

if (subject.includes('support') || subject.includes('ticket')) {
  return '#support';
} else if (subject.includes('sales') || subject.includes('deal')) {
  return '#sales';
} else if (subject.includes('invoice') || subject.includes('payment')) {
  return '#finance';
} else {
  return '#general-emails';
}

Handle Attachments
#

Notify about attachments without forwarding them:

1
2
3
4
5
6
7
8
9
const hasAttachments = $json.attachments && $json.attachments.length > 0;
const attachmentInfo = hasAttachments
  ? `\nšŸ“Ž *Attachments:* ${$json.attachments.length} file(s)`
  : '';

return {
  ...$json,
  attachmentInfo: attachmentInfo
};

Gmail-Specific Setup
#

Create App Password
#

  1. Go to Google Account → Security
  2. Enable 2-Step Verification
  3. Go to App Passwords
  4. Generate password for “Mail”
  5. Use this password in n8n

Use Gmail Labels
#

Filter by Gmail label instead of scanning all emails:

1
Mailbox: [Gmail]/Important

Troubleshooting
#

Connection Failed
#

  • Verify IMAP is enabled in email settings
  • Check host and port are correct
  • Use app-specific password for Gmail

Missing Emails
#

  • Check spam/junk folder
  • Verify filter conditions aren’t too strict
  • Check polling interval

Duplicate Messages
#

  • Add a seen/processed check
  • Use email Message-ID for deduplication

Best Practices
#

  1. Start with strict filters - Expand gradually to avoid noise
  2. Use a dedicated channel - Don’t spam general channels
  3. Include original link - Let users read full email in client
  4. Handle errors gracefully - Don’t crash on malformed emails
  5. Monitor the workflow - Ensure it’s running reliably

Conclusion
#

Email-to-Slack forwarding ensures critical messages get immediate attention. With n8n’s flexible filtering, you can fine-tune exactly which emails get forwarded and to which channels.

Download the complete workflow from our n8n Workflow Gallery.