DEV Community

Pirate Prentice
Pirate Prentice

Posted on

n8n Gmail Node: Send, Read, and Automate Email in Your Workflows (Free Workflow JSON)

Email is still the backbone of business communication — and the Gmail node in n8n lets you send messages, read your inbox, manage labels, and build fully automated email workflows without writing custom API code.

In this guide you'll learn every Gmail node operation, the OAuth2 setup gotchas, and three real-world patterns you can steal today. Free workflow JSON included.


What the Gmail Node Can Do

The n8n Gmail node covers the full Gmail API surface:

Message operations:

  • Send — compose and send an email with attachments, CC/BCC, reply-to headers
  • Get — fetch a single message by ID
  • Get Many — list messages with filters (label, sender, subject, date range)
  • Reply — reply to a thread (preserves threading)
  • Delete — permanently delete a message
  • Mark as Read / Unread — update read state
  • Add/Remove Label — apply or strip Gmail labels

Label operations:

  • Create, get, get many, delete Gmail labels

Draft operations:

  • Create, get, get many, delete, send drafts

Trigger (Gmail Trigger node):

  • Fires when new mail arrives matching a filter (label, sender, subject pattern)
  • Polls on your configured interval (minimum ~1 minute)

Prerequisites: OAuth2 Setup

The Gmail node uses OAuth2 — you need a Google Cloud project with Gmail API enabled.

Steps:

  1. Go to console.cloud.google.com → APIs & Services → Enable APIs → search "Gmail API" → Enable.
  2. Create OAuth 2.0 credentials (Desktop or Web Application type).
  3. Add your n8n instance URL as an authorized redirect URI: https://your-n8n.domain/rest/oauth2-credential/callback
  4. Copy Client ID and Client Secret into n8n's Google (OAuth2 API) credential.
  5. Click "Connect my account" — Google consent screen appears — authorize.

For self-hosted n8n: make sure N8N_EDITOR_BASE_URL is set to your public URL; localhost OAuth flows will fail.


Gmail Node: Key Parameters

Send Message

Field Notes
To Comma-separated or expression from upstream data
Subject Supports n8n expressions
Message Plain text or HTML (toggle "Send as HTML")
Attachments Reference binary fields from upstream nodes
CC / BCC Optional
Reply To Override reply-to address
Thread ID Supply to send as a reply in an existing thread

Get Many Messages

Filter Example
Label INBOX, SENT, or a custom label ID
Sender from:noreply@stripe.com
Query Full Gmail search syntax — subject:invoice is:unread after:2024/01/01
Return All Off by default; set limit or paginate manually

6 Gotchas to Know Before You Build

1. OAuth consent screen must be verified for production.
Apps in "Testing" mode only work for listed test users. For production use (any Gmail account), submit the app for Google verification or add all required accounts as test users.

2. Rate limits are generous but real.
Gmail API: 250 quota units/second per user, 1 billion units/day. Sending: up to 500 messages/day for regular accounts; 2,000/day for Google Workspace. Bulk sending from Gmail is ToS-prohibited — use SendGrid or Brevo for marketing email.

3. Get Many returns metadata by default, not full body.
Set "Format" to "Full" or "Raw" to get message body. Default "Metadata" only returns headers.

4. HTML emails need Send as HTML toggled on.
If you paste HTML into the message field without enabling that toggle, recipients see raw <p> tags.

5. Attachments must be binary data.
Attach files by referencing binary properties from upstream nodes (HTTP Request, Read/Write Files, etc.) — you can't attach a URL directly.

6. Gmail Trigger has a minimum poll of ~1 minute.
It's not a true push webhook. For near-real-time responses, consider a catch-all IMAP trigger or use App Script + webhooks for sub-minute latency.


3 Workflow Patterns You Can Steal

Pattern 1: Stripe Payment → Branded Receipt Email

Use case: Send a custom-branded receipt when a Stripe payment succeeds — without Stripe's generic template.

Nodes:

  1. Webhook Trigger — receives payment_intent.succeeded from Stripe
  2. Stripe node — fetch full customer details (name, email, amount, description)
  3. Gmail → Send — compose HTML receipt with company logo, line items, support CTA

Key config:

  • Enable "Send as HTML"
  • Build the HTML body with an n8n expression: {{ $json.customer_name }}, {{ $json.amount_formatted }}
  • Set Reply-To to your support address

Result: Every Stripe payment triggers a polished, on-brand email — not the default Stripe receipt.


Pattern 2: Inbox Triage → Slack Routing

Use case: Monitor a support inbox, classify emails by topic with AI, route to the right Slack channel.

Nodes:

  1. Gmail Trigger — watches INBOX label, fires on new messages
  2. Gmail → Get — fetch full message body (Format: Full)
  3. OpenAI Chat node — classify as: billing / technical / general / urgent
  4. Switch node — routes on classification
  5. Slack → Send Message — posts to #billing-support, #tech-support, #general, #urgent respectively

Key config:

  • Gmail Trigger: filter by label INBOX to skip sent/drafts
  • OpenAI prompt: "Classify this email into exactly one category: billing, technical, general, urgent. Reply with only the category word."
  • Add Gmail → Mark as Read after routing so you don't reprocess

Result: Zero manual inbox monitoring. Every inbound email is classified and surfaced in Slack within 60 seconds.


Pattern 3: Weekly Report → Stakeholder Digest

Use case: Every Monday morning, pull data from Google Sheets, generate a plain-English summary with AI, and email it to a stakeholder list.

Nodes:

  1. Schedule Trigger — Monday 08:00
  2. Google Sheets → Get Many — pull last week's KPI rows
  3. Code node — aggregate: sum revenue, count orders, calc avg, format as text block
  4. OpenAI Chat node — write a 3-sentence executive summary from the data block
  5. Gmail → Send — email to static list; subject: Weekly KPI Report — {{ $now.toFormat('MMM d') }}

Key config:

  • Keep the email plain-text unless you need branding (HTML adds complexity)
  • Use BCC for the stakeholder list if it's large — avoids "reply all" chaos
  • Store the recipient list in a Google Sheet for easy updates

Result: Automated weekly reporting with zero manual effort — the kind of thing that makes you look organized.


Free Workflow JSON

{
  "name": "Gmail Inbox Triage → Slack Router",
  "nodes": [
    {
      "parameters": {
        "pollTimes": { "item": [{ "mode": "everyMinute" }] },
        "filters": { "labelIds": ["INBOX"] },
        "format": "full",
        "options": {}
      },
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "typeVersion": 1,
      "position": [240, 300]
    },
    {
      "parameters": {
        "model": "gpt-4o-mini",
        "messages": {
          "values": [
            {
              "content": "Classify this email into exactly one category: billing, technical, general, urgent. Reply with only the category word.\n\nSubject: {{ $json.subject }}\nBody: {{ $json.text }}"
            }
          ]
        }
      },
      "name": "Classify Email",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1,
      "position": [460, 300]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            { "outputKey": "billing", "conditions": { "string": [{ "value1": "={{ $json.message.content }}", "operation": "equals", "value2": "billing" }] } },
            { "outputKey": "technical", "conditions": { "string": [{ "value1": "={{ $json.message.content }}", "operation": "equals", "value2": "technical" }] } },
            { "outputKey": "urgent", "conditions": { "string": [{ "value1": "={{ $json.message.content }}", "operation": "equals", "value2": "urgent" }] } }
          ]
        },
        "fallbackOutput": "general"
      },
      "name": "Route by Category",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [680, 300]
    }
  ],
  "connections": {
    "Gmail Trigger": { "main": [[{ "node": "Classify Email", "type": "main", "index": 0 }]] },
    "Classify Email": { "main": [[{ "node": "Route by Category", "type": "main", "index": 0 }]] }
  }
}
Enter fullscreen mode Exit fullscreen mode

Drop this into n8n → add your Gmail credential → connect Slack nodes to each Switch output → activate. Full inbox triage in under 10 minutes.


Gmail Node vs. Email Send Node

Gmail Node Send Email node (SMTP)
Auth OAuth2 (Google account) SMTP credentials
Attachments Yes (binary fields) Yes
Read inbox Yes No
Label management Yes No
Rate limits Gmail API quota Your SMTP server limits
Best for Google Workspace shops Any email provider

Use Gmail node if you're already in the Google ecosystem. Use the generic Send Email node if you need provider flexibility or higher volume via a transactional ESP.


What's Next

  • Pair Gmail with the Google Sheets node to log every inbound email to a spreadsheet
  • Use Gmail + Notion to turn emails into tasks or database entries automatically
  • Add the n8n Workflow Starter Pack for pre-built automation templates: pirateprentice.gumroad.com/l/sxcoe

Need a custom Gmail automation built for your team? Done-for-you service, $99 flat: buy.stripe.com/4gMdRaetT3Yv3yxbOs2go03

Top comments (1)

Collapse
 
pirateprentice profile image
Pirate Prentice

Are you using the Gmail node to send transactional receipts, triage your inbox with AI, or build weekly digest workflows? Drop your use case in the comments — always curious what people are automating with Gmail in n8n.