DEV Community

Alex Kane
Alex Kane

Posted on

n8n + OpenAI: Build AI-Powered Automations Without Code (5 Real Workflows with Free JSON)

I spent three months manually doing things that an LLM could handle in milliseconds: triaging support tickets, qualifying leads, summarizing customer feedback, drafting email replies.

Then I connected n8n to OpenAI. Now those workflows run 24/7 without me touching them.

In this guide I'll show you exactly how to wire n8n to OpenAI — and give you 5 complete workflow JSONs you can import and run today.


Why n8n + OpenAI Is a Power Combo

n8n handles the plumbing: triggers, data routing, API calls, database writes.

OpenAI handles the thinking: classify this, summarize that, draft a reply, decide which bucket this belongs in.

Together they let you build automations that weren't possible before LLMs — not just "if X then Y" but "read this, understand it, then do the right thing."

The best part: n8n's OpenAI node handles auth, rate limiting, and response parsing. You write prompts, not API glue code.


Prerequisites

Add Your OpenAI Credentials in n8n

  1. Go to Settings → Credentials → New
  2. Search for OpenAI
  3. Paste your API key
  4. Click Save

That's it. All 5 workflows below will use this credential.


Workflow 1: AI Email Auto-Responder

The problem: You get the same 10 types of emails every day. Pricing questions, support requests, "how does this work" — you write the same reply each time.

The solution: GPT-4o-mini reads each incoming email, classifies it, and drafts a contextually accurate reply.

{
  "name": "AI Email Auto-Responder",
  "nodes": [
    {
      "parameters": {
        "rule": { "interval": [{ "field": "minutes", "minutesInterval": 5 }] }
      },
      "name": "Check Every 5min",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [240, 300]
    },
    {
      "parameters": {
        "operation": "getAll",
        "filters": { "readStatus": "unread" },
        "limit": 10
      },
      "name": "Get Unread Emails",
      "type": "n8n-nodes-base.gmail",
      "position": [460, 300]
    },
    {
      "parameters": {
        "model": "gpt-4o-mini",
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a helpful business assistant. Classify the email into one of: pricing, support, general-inquiry, spam. Then draft a professional reply. Reply in JSON: {\"category\": \"...\", \"draft_reply\": \"...\"}"
            },
            {
              "role": "user",
              "content": "From: {{ $json.from }}\nSubject: {{ $json.subject }}\nBody: {{ $json.text }}"
            }
          ]
        }
      },
      "name": "Classify + Draft Reply",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [680, 300]
    },
    {
      "parameters": {
        "jsCode": "const raw = $input.item.json.message.content;\nconst parsed = JSON.parse(raw);\nreturn [{ json: { ...parsed, original_from: $('Get Unread Emails').item.json.from, original_subject: $('Get Unread Emails').item.json.subject } }];"
      },
      "name": "Parse AI Response",
      "type": "n8n-nodes-base.code",
      "position": [900, 300]
    },
    {
      "parameters": {
        "conditions": {
          "string": [{ "value1": "={{ $json.category }}", "operation": "notEqual", "value2": "spam" }]
        }
      },
      "name": "Skip Spam",
      "type": "n8n-nodes-base.if",
      "position": [1120, 300]
    },
    {
      "parameters": {
        "operation": "send",
        "to": "={{ $json.original_from }}",
        "subject": "Re: {{ $json.original_subject }}",
        "message": "={{ $json.draft_reply }}"
      },
      "name": "Send Reply",
      "type": "n8n-nodes-base.gmail",
      "position": [1340, 300]
    }
  ],
  "connections": {
    "Check Every 5min": { "main": [[{ "node": "Get Unread Emails", "type": "main", "index": 0 }]] },
    "Get Unread Emails": { "main": [[{ "node": "Classify + Draft Reply", "type": "main", "index": 0 }]] },
    "Classify + Draft Reply": { "main": [[{ "node": "Parse AI Response", "type": "main", "index": 0 }]] },
    "Parse AI Response": { "main": [[{ "node": "Skip Spam", "type": "main", "index": 0 }]] },
    "Skip Spam": { "main": [[{ "node": "Send Reply", "type": "main", "index": 0 }]] }
  }
}
Enter fullscreen mode Exit fullscreen mode

What it does:

  1. Checks Gmail for unread emails every 5 minutes
  2. Sends each email to GPT-4o-mini for classification + reply drafting
  3. Filters out spam
  4. Sends the draft reply automatically

Time saved: ~20 minutes per day if you get 10+ similar emails.

Pro tip: Change "Send Reply" to "Create Draft" in the Gmail node if you want to review before sending. Safer for a first run.


Workflow 2: AI Customer Support Ticket Triage

The problem: Support tickets pile up. You need to prioritize billing issues and bug reports over general questions — but reading each one to decide takes time.

The solution: GPT-4o-mini reads each ticket, categorizes severity, drafts a response, and routes high-priority tickets to Slack.

{
  "name": "AI Support Triage",
  "nodes": [
    {
      "parameters": { "httpMethod": "POST", "path": "support-ticket" },
      "name": "Webhook — New Ticket",
      "type": "n8n-nodes-base.webhook",
      "position": [240, 300]
    },
    {
      "parameters": {
        "model": "gpt-4o-mini",
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a support triage agent. Given a ticket, return JSON only: {\"category\": \"billing|bug|feature-request|general\", \"priority\": \"high|medium|low\", \"draft_response\": \"...\", \"summary\": \"one sentence summary\"}"
            },
            {
              "role": "user",
              "content": "Customer: {{ $json.customer_name }}\nEmail: {{ $json.email }}\nMessage: {{ $json.message }}"
            }
          ]
        }
      },
      "name": "Triage with GPT",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [460, 300]
    },
    {
      "parameters": {
        "jsCode": "const raw = $input.item.json.message.content;\nconst parsed = JSON.parse(raw);\nreturn [{ json: { ...parsed, customer_email: $('Webhook — New Ticket').item.json.email, customer_name: $('Webhook — New Ticket').item.json.customer_name } }];"
      },
      "name": "Parse Triage",
      "type": "n8n-nodes-base.code",
      "position": [680, 300]
    },
    {
      "parameters": {
        "conditions": {
          "string": [{ "value1": "={{ $json.priority }}", "operation": "equal", "value2": "high" }]
        }
      },
      "name": "High Priority?",
      "type": "n8n-nodes-base.if",
      "position": [900, 300]
    },
    {
      "parameters": {
        "channel": "#support-urgent",
        "text": "🚨 HIGH PRIORITY TICKET\nCustomer: {{ $json.customer_name }}\nCategory: {{ $json.category }}\nSummary: {{ $json.summary }}\nEmail: {{ $json.customer_email }}"
      },
      "name": "Alert Slack",
      "type": "n8n-nodes-base.slack",
      "position": [1120, 200]
    },
    {
      "parameters": {
        "operation": "send",
        "to": "={{ $json.customer_email }}",
        "subject": "Re: Your Support Request",
        "message": "={{ $json.draft_response }}"
      },
      "name": "Send Auto-Reply",
      "type": "n8n-nodes-base.gmail",
      "position": [1120, 420]
    }
  ],
  "connections": {
    "Webhook — New Ticket": { "main": [[{ "node": "Triage with GPT", "type": "main", "index": 0 }]] },
    "Triage with GPT": { "main": [[{ "node": "Parse Triage", "type": "main", "index": 0 }]] },
    "Parse Triage": { "main": [[{ "node": "High Priority?", "type": "main", "index": 0 }]] },
    "High Priority?": {
      "main": [
        [{ "node": "Alert Slack", "type": "main", "index": 0 }],
        [{ "node": "Send Auto-Reply", "type": "main", "index": 0 }]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

What it does:

  1. Receives tickets via webhook (connect to Typeform, Intercom, or a simple form)
  2. GPT-4o-mini categorizes severity and drafts a response
  3. High-priority tickets → Slack alert for immediate human attention
  4. All tickets get an immediate auto-reply

Workflow 3: AI Content Repurposer

The problem: You write a blog post. Then you need a Twitter thread, a LinkedIn post, and an email teaser. That's 3x the work for the same content.

The solution: Paste your blog URL, get all three formats in 30 seconds.

{
  "name": "AI Content Repurposer",
  "nodes": [
    {
      "parameters": { "httpMethod": "POST", "path": "repurpose" },
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [240, 300]
    },
    {
      "parameters": { "url": "={{ $json.article_url }}", "options": {} },
      "name": "Fetch Article",
      "type": "n8n-nodes-base.httpRequest",
      "position": [460, 300]
    },
    {
      "parameters": {
        "model": "gpt-4o-mini",
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a content repurposing expert. Given an article, create: 1) A 5-tweet Twitter thread (numbered 1/5 through 5/5), 2) A LinkedIn post (150-200 words, professional tone), 3) An email newsletter teaser (2-3 sentences + CTA). Return as JSON: {\"twitter_thread\": \"...\", \"linkedin_post\": \"...\", \"email_teaser\": \"...\"}"
            },
            {
              "role": "user",
              "content": "Article content:\n{{ $json.data }}"
            }
          ]
        }
      },
      "name": "Repurpose with GPT",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [680, 300]
    },
    {
      "parameters": {
        "jsCode": "const raw = $input.item.json.message.content;\nconst parsed = JSON.parse(raw);\nreturn [{ json: parsed }];"
      },
      "name": "Parse Output",
      "type": "n8n-nodes-base.code",
      "position": [900, 300]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": { "value": "YOUR_SHEET_ID" },
        "sheetName": "Repurposed Content",
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Date": "={{ $now }}",
            "Twitter Thread": "={{ $json.twitter_thread }}",
            "LinkedIn Post": "={{ $json.linkedin_post }}",
            "Email Teaser": "={{ $json.email_teaser }}"
          }
        }
      },
      "name": "Save to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [1120, 300]
    }
  ],
  "connections": {
    "Webhook": { "main": [[{ "node": "Fetch Article", "type": "main", "index": 0 }]] },
    "Fetch Article": { "main": [[{ "node": "Repurpose with GPT", "type": "main", "index": 0 }]] },
    "Repurpose with GPT": { "main": [[{ "node": "Parse Output", "type": "main", "index": 0 }]] },
    "Parse Output": { "main": [[{ "node": "Save to Sheets", "type": "main", "index": 0 }]] }
  }
}
Enter fullscreen mode Exit fullscreen mode

What it does:

  1. Receives article URL via webhook
  2. Fetches the full article content
  3. GPT-4o-mini generates Twitter thread + LinkedIn post + email teaser in one shot
  4. Saves all three to Google Sheets (or send directly to Buffer/social tools)

Cost: ~$0.001 per repurpose with gpt-4o-mini. Free if you're under the OpenAI free tier.


Workflow 4: AI Customer Feedback Analyzer

The problem: You collect feedback from surveys, reviews, and support tickets — but making sense of it all takes hours.

The solution: GPT-4o-mini reads each piece of feedback, extracts sentiment, key themes, and product improvement ideas, and logs everything to a dashboard sheet.

{
  "name": "AI Feedback Analyzer",
  "nodes": [
    {
      "parameters": { "httpMethod": "POST", "path": "feedback" },
      "name": "New Feedback",
      "type": "n8n-nodes-base.webhook",
      "position": [240, 300]
    },
    {
      "parameters": {
        "model": "gpt-4o-mini",
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "Analyze this customer feedback. Return JSON: {\"sentiment\": \"positive|neutral|negative\", \"score\": 1-10, \"themes\": [\"list\", \"of\", \"themes\"], \"improvement_idea\": \"one actionable improvement suggestion\", \"summary\": \"one sentence\"}"
            },
            {
              "role": "user",
              "content": "{{ $json.feedback_text }}"
            }
          ]
        }
      },
      "name": "Analyze with GPT",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [460, 300]
    },
    {
      "parameters": {
        "jsCode": "const raw = $input.item.json.message.content;\nconst parsed = JSON.parse(raw);\nreturn [{ json: { ...parsed, themes: parsed.themes.join(', '), original_feedback: $('New Feedback').item.json.feedback_text, customer: $('New Feedback').item.json.customer_name || 'Anonymous', date: new Date().toISOString() } }];"
      },
      "name": "Parse Analysis",
      "type": "n8n-nodes-base.code",
      "position": [680, 300]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": { "value": "YOUR_SHEET_ID" },
        "sheetName": "Feedback Dashboard",
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Date": "={{ $json.date }}",
            "Customer": "={{ $json.customer }}",
            "Sentiment": "={{ $json.sentiment }}",
            "Score": "={{ $json.score }}",
            "Themes": "={{ $json.themes }}",
            "Improvement Idea": "={{ $json.improvement_idea }}",
            "Summary": "={{ $json.summary }}",
            "Original Feedback": "={{ $json.original_feedback }}"
          }
        }
      },
      "name": "Log to Dashboard",
      "type": "n8n-nodes-base.googleSheets",
      "position": [900, 300]
    }
  ],
  "connections": {
    "New Feedback": { "main": [[{ "node": "Analyze with GPT", "type": "main", "index": 0 }]] },
    "Analyze with GPT": { "main": [[{ "node": "Parse Analysis", "type": "main", "index": 0 }]] },
    "Parse Analysis": { "main": [[{ "node": "Log to Dashboard", "type": "main", "index": 0 }]] }
  }
}
Enter fullscreen mode Exit fullscreen mode

What it does:

  1. Receives feedback via webhook (Typeform, Tally, or any form)
  2. GPT-4o-mini extracts sentiment (1–10 score), themes, and actionable improvement ideas
  3. Logs everything to a Google Sheet with structured columns
  4. After a week you can see patterns: "50% of negative feedback mentions onboarding" — that's a product roadmap input that used to take hours to generate

Workflow 5: AI Lead Qualifier

The problem: New leads come in from your website form. Some are ready to buy, some are browsers. You waste time on the wrong ones.

The solution: GPT-4o-mini reads the lead's form submission, scores them (1–10), writes a personalized intro email, and routes hot leads to Slack for immediate follow-up.

{
  "name": "AI Lead Qualifier",
  "nodes": [
    {
      "parameters": { "httpMethod": "POST", "path": "new-lead" },
      "name": "New Lead",
      "type": "n8n-nodes-base.webhook",
      "position": [240, 300]
    },
    {
      "parameters": {
        "model": "gpt-4o-mini",
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a sales qualification expert. Analyze this lead and return JSON only: {\"score\": 1-10, \"qualification\": \"hot|warm|cold\", \"reason\": \"why this score\", \"personalized_email\": \"friendly intro email tailored to their message\", \"follow_up_note\": \"what to say if we call them\"}"
            },
            {
              "role": "user",
              "content": "Name: {{ $json.name }}\nCompany: {{ $json.company }}\nEmail: {{ $json.email }}\nMessage: {{ $json.message }}\nBudget: {{ $json.budget }}\nTimeline: {{ $json.timeline }}"
            }
          ]
        }
      },
      "name": "Qualify Lead",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [460, 300]
    },
    {
      "parameters": {
        "jsCode": "const raw = $input.item.json.message.content;\nconst parsed = JSON.parse(raw);\nreturn [{ json: { ...parsed, name: $('New Lead').item.json.name, email: $('New Lead').item.json.email, company: $('New Lead').item.json.company } }];"
      },
      "name": "Parse Result",
      "type": "n8n-nodes-base.code",
      "position": [680, 300]
    },
    {
      "parameters": {
        "conditions": {
          "string": [{ "value1": "={{ $json.qualification }}", "operation": "equal", "value2": "hot" }]
        }
      },
      "name": "Hot Lead?",
      "type": "n8n-nodes-base.if",
      "position": [900, 300]
    },
    {
      "parameters": {
        "channel": "#sales",
        "text": "🔥 HOT LEAD (Score: {{ $json.score }}/10)\nName: {{ $json.name }} | {{ $json.company }}\nWhy: {{ $json.reason }}\nCall note: {{ $json.follow_up_note }}"
      },
      "name": "Slack — Hot Lead",
      "type": "n8n-nodes-base.slack",
      "position": [1120, 200]
    },
    {
      "parameters": {
        "operation": "send",
        "to": "={{ $json.email }}",
        "subject": "Hey {{ $json.name }}, quick note",
        "message": "={{ $json.personalized_email }}"
      },
      "name": "Send Personalized Email",
      "type": "n8n-nodes-base.gmail",
      "position": [1120, 420]
    }
  ],
  "connections": {
    "New Lead": { "main": [[{ "node": "Qualify Lead", "type": "main", "index": 0 }]] },
    "Qualify Lead": { "main": [[{ "node": "Parse Result", "type": "main", "index": 0 }]] },
    "Parse Result": { "main": [[{ "node": "Hot Lead?", "type": "main", "index": 0 }]] },
    "Hot Lead?": {
      "main": [
        [{ "node": "Slack — Hot Lead", "type": "main", "index": 0 }],
        [{ "node": "Send Personalized Email", "type": "main", "index": 0 }]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

What it does:

  1. New lead submits your contact form
  2. GPT-4o-mini scores them 1–10 and writes a personalized intro email
  3. Hot leads (8+) get an immediate Slack ping so you respond within minutes
  4. Everyone gets a personalized (not templated) follow-up email automatically

Key Patterns to Reuse

These 5 workflows share patterns you can lift and apply anywhere:

Structured JSON output: Always tell GPT exactly what JSON schema to return. Parse it with a Code node. Never try to parse free-form text.

Graceful parsing: Wrap JSON.parse() in a Code node. If GPT returns markdown fences (

json), strip them first: `raw.replace(/

json\n?/g, '').replace(/


/g, '')`

**Model choice:** Use `gpt-4o-mini` for classification/triage (cheap, fast, accurate). Use `gpt-4o` for long-form drafting where quality matters. `gpt-4o-mini` at ~$0.15/million input tokens is basically free for most workflows.

**Temperature:** For structured classification, set temperature to 0 for deterministic output. For creative writing (email drafts, content), use 0.7–0.8.

---

## Ready-Made Templates

If you want these workflows pre-built and tested (with error handling, logging, and retry logic already added), I put them together as a template pack at **[stripeai.gumroad.com](https://stripeai.gumroad.com)**.

Each template comes with:
- The complete workflow JSON
- Setup guide (which credentials to add, where to put your Sheet IDs)
- Customization notes

The Email Auto-Responder, AI Customer Support Bot, Content Repurposer, Customer Feedback Analyzer, and Lead Capture workflows are all in there.

---

## What's Next

Once you have n8n + OpenAI running, the next step is chaining agents: have one GPT node classify, another draft, another review. That's where you start building real AI pipelines, not just single-step automations.

I'll cover that in a follow-up post.

What are you automating with n8n + OpenAI? Drop a comment — I read everything.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)