AutomationFlowsAI & RAG › Draft Personalized Outlook Support Email Replies with Supabase RAG and Openai

Draft Personalized Outlook Support Email Replies with Supabase RAG and Openai

ByMatthew @matthew-synteria on n8n.io

This workflow automates the first line of customer support by intelligently drafting email replies. It bridges the gap between your CRM (Supabase), your technical documentation (Vector Store), and your inbox (Outlook). By analyzing the sender's identity and the technical content…

Event trigger★★★★☆ complexityAI-powered13 nodesMicrosoft Outlook TriggerMicrosoft OutlookGoogle SheetsAgentOpenAI ChatSupabase Vector StoreOpenAI EmbeddingsSupabase
AI & RAG Trigger: Event Nodes: 13 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #12839 — we link there as the canonical source.

This workflow follows the Agent → OpenAI Embeddings recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "ad82d0b6-3eda-41c6-9f41-e18351dd0798",
      "name": "Template Header",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        112
      ],
      "parameters": {
        "color": 4,
        "width": 542,
        "height": 498,
        "content": "## \ud83e\udd16 AI Email Support Agent with RAG\n\n**Overview**\nThis workflow automates email responses by combining CRM data (Supabase) with technical knowledge (Vector Store) to draft accurate, personalized replies in Outlook.\n\n**Requirements**\n- **Microsoft Outlook** (Business Account)\n- **Supabase** (Postgres DB & Vector Store)\n- **OpenAI** (API Key for GPT-4o & Embeddings)\n- **Google Sheets** (For logging)\n\n**Setup Instructions**\n1. **Credentials**: Connect your Outlook, OpenAI, Supabase, and Google accounts.\n2. **Supabase**: Ensure you have a 'contacts' table and a Vector Store set up for your product manuals.\n3. **Placeholders**: Update the **Green** nodes with your specific IDs (Sheet ID, Table Name, etc.).\n4. **Code Node**: Update the 'Business Rules' and Persona details in the 'Build AI Prompt' node."
      },
      "typeVersion": 1
    },
    {
      "id": "bbab8f96-a08c-4a19-b6c9-a1d406ab3ecc",
      "name": "Context Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        80
      ],
      "parameters": {
        "color": 6,
        "width": 360,
        "height": 140,
        "content": "### 1. Context Building\nWe trigger on new emails, then immediately look up the sender in our Supabase CRM to get their Name, Role, and Department. This allows the AI to personalize the greeting."
      },
      "typeVersion": 1
    },
    {
      "id": "c6fdb366-2567-4c91-93f9-2f436b7e71a8",
      "name": "AI Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1360,
        96
      ],
      "parameters": {
        "color": 6,
        "width": 380,
        "height": 140,
        "content": "### 2. AI Reasoning (RAG)\nThe Agent uses **GPT-4o** to analyze the email intent. It utilizes the **Vector Store Tool** to look up technical answers from your documentation before formulating a reply."
      },
      "typeVersion": 1
    },
    {
      "id": "944780a6-03f4-4655-848f-7404c5b9c5e7",
      "name": "On Email Received",
      "type": "n8n-nodes-base.microsoftOutlookTrigger",
      "position": [
        128,
        288
      ],
      "parameters": {
        "filters": {},
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "21d513a5-ec79-4c56-8bbc-c2731f3976e8",
      "name": "Config Variables",
      "type": "n8n-nodes-base.set",
      "position": [
        352,
        288
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": []
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "b8f7e691-6959-40aa-a534-1652c2933a86",
      "name": "Draft Outlook Reply",
      "type": "n8n-nodes-base.microsoftOutlook",
      "position": [
        1568,
        288
      ],
      "parameters": {
        "subject": "=RE: {{ $('On Email Received').first().json.subject }}",
        "resource": "draft",
        "bodyContent": "={{ $json.reply_html }}",
        "additionalFields": {
          "toRecipients": "={{ $('On Email Received').first().json.from }}",
          "bodyContentType": "html"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "14ab319b-032d-4d4b-851c-6887c9b8ee89",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1792,
        288
      ],
      "parameters": {
        "columns": {
          "value": {
            "From": "={{ $('On Email Received').first().json.from }}",
            "Status": "Success",
            "Product": "={{ $('AI Support Agent').first().json.primary_product_codes[0] || '' }}",
            "Urgency": "={{ $('AI Support Agent').first().json.urgency }}",
            "Timestamp": "={{ $now.toISO() }}",
            "Department": "={{ $('AI Support Agent').first().json.department }}",
            "Email Subject": "={{ $('On Email Received').first().json.subject }}"
          },
          "schema": [
            {
              "id": "Status",
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Subject",
              "required": false,
              "displayName": "Email Subject",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "From",
              "required": false,
              "displayName": "From",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Department",
              "required": false,
              "displayName": "Department",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Product",
              "required": false,
              "displayName": "Product",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Urgency",
              "required": false,
              "displayName": "Urgency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timestamp",
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Email Subject"
          ]
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "<__PLACEHOLDER_VALUE__SHEET_NAME__>"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__GOOGLE_SHEET_ID__>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "5260b615-7c6d-46c3-b140-badf6563cbe9",
      "name": "AI Support Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1056,
        288
      ],
      "parameters": {
        "text": "={{ $json.chatInput }}",
        "options": {
          "systemMessage": "=You act as [YOUR_AGENT_NAME], [YOUR_JOB_TITLE] for [YOUR_COMPANY_NAME] supplying [YOUR_PRODUCT_TYPE].\n\nYou get inbound emails from customers/clients. You have sender info (name, company, department, role) and a vector store of manuals/specs/how-to guides/marketing docs/case studies.\n\nTasks:\n1) From the input, decide:\n   - intent: \"technical_question\" | \"pricing_request\" | \"internal_quote_email\" | \"generic_enquiry\"\n   - primary_product_codes: array of product codes mentioned (may be empty)\n   - urgency: \"high\" | \"normal\" | \"low\"\n   - department: best-guess department name\n\n2) Use the vector store tool only to retrieve relevant info for that department and those products.\n\n3) Draft a short, clear reply email as [YOUR_AGENT_NAME] that:\n   - Answers the question using retrieved context where useful\n   - Optionally and softly suggests relevant accessories or trials (no hard sell)\n   - Uses appropriate regional spelling (e.g., UK or US) and a professional tone\n   - Is max 2-3 short paragraphs plus optional bullets\n   - Starts with \"Hi {first_name},\" and ends with:\n     \"Kind regards,\n      [YOUR_AGENT_NAME]\n      [YOUR_JOB_TITLE]\"\n\n4) Never provide emergency advice. If unsure, say you will check and follow up.\n\nReturn a single JSON object ONLY:\n{\n  \"reply_html\": \"<html>\u2026full email body in HTML\u2026</html>\",\n  \"intent\": \"technical_question\",\n  \"primary_product_codes\": [\"...\"],\n  \"urgency\": \"normal\",\n  \"department\": \"Ophthalmology\"\n}"
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "03eb468a-8ac2-473d-9fda-2d0435b5cd0a",
      "name": "GPT-4o Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1008,
        544
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "gpt-4o"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "f480bfae-dbe1-417f-956e-3d7ed41836fb",
      "name": "Vector Store (Supabase)",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        1168,
        544
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "options": {
          "queryName": "<__PLACEHOLDER_VALUE__SUPABASE_FUNCTION_NAME__>"
        },
        "tableName": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__SUPABASE_VECTOR_TABLE__>"
        },
        "toolDescription": "Retrieves relevant information from product manuals and documentation for [YOUR_DEVICE_TYPE] to help answer customer support questions"
      },
      "typeVersion": 1.3
    },
    {
      "id": "5a9988d5-77d8-46f3-8c99-49f64fee586c",
      "name": "OpenAI Embeddings",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        1168,
        752
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "88d0d7f6-67fd-413e-b431-8e0ce97b596e",
      "name": "Build AI Prompt",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        288
      ],
      "parameters": {
        "jsCode": "const email = $('On Email Received').first().json;\nconst contact = $json; // From Supabase lookup\n\n// Extract contact details (Ensure these match your Supabase columns)\nconst senderName = contact.full_name || email.from || 'Unknown';\nconst senderEmail = email.from || '';\nconst hospitalName = contact.hospital_name || '';\nconst departmentName = contact.department_name || '';\nconst role = contact.role || '';\nconst emailBody = email.body || email.bodyPreview || '';\n\n// Build context with business rules\n// TODO: Customize these rules for your business case\nconst businessRules = `\nBUSINESS RULES:\n- Replies must be short (max 2-3 short paragraphs, optional bullets), friendly, professional.\n- No clinical or emergency medical advice; only equipment, pricing, logistics.\n- Only suggest accessories relevant to the sender's department.\n- Use consultative / solution-based selling, never hard sell.\n- If unsure about technical detail or price, say you will confirm and follow up instead of guessing.\n`;\n\nconst chatInput = `\nSender: ${senderName} (${senderEmail})\nHospital: ${hospitalName || 'Not available'}\nDepartment: ${departmentName || 'Not available'}\nRole: ${role || 'Not available'}\n\nEmail Subject: ${email.subject || 'No subject'}\nEmail Body:\n${emailBody}\n\n${businessRules}\n`;\n\nreturn {\n  json: {\n    chatInput: chatInput,\n    originalEmail: email\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "bba072e7-5ec6-470c-b0ca-962ef835b737",
      "name": "Fetch Contact Info",
      "type": "n8n-nodes-base.supabase",
      "position": [
        576,
        288
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "email",
              "keyValue": "={{ $('On Email Received').first().json.from }}"
            }
          ]
        },
        "tableId": "<__PLACEHOLDER_VALUE__SUPABASE_CONTACTS_TABLE__>",
        "operation": "get"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "GPT-4o Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Support Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Build AI Prompt": {
      "main": [
        [
          {
            "node": "AI Support Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Support Agent": {
      "main": [
        [
          {
            "node": "Draft Outlook Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config Variables": {
      "main": [
        [
          {
            "node": "Fetch Contact Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On Email Received": {
      "main": [
        [
          {
            "node": "Config Variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Embeddings": {
      "ai_embedding": [
        [
          {
            "node": "Vector Store (Supabase)",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Contact Info": {
      "main": [
        [
          {
            "node": "Build AI Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Draft Outlook Reply": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Vector Store (Supabase)": {
      "ai_tool": [
        [
          {
            "node": "AI Support Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow automates the first line of customer support by intelligently drafting email replies. It bridges the gap between your CRM (Supabase), your technical documentation (Vector Store), and your inbox (Outlook). By analyzing the sender's identity and the technical content…

Source: https://n8n.io/workflows/12839/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

🛠️ How It Works: System Architecture Workflow ini bekerja melalui empat lapisan proses utama yang terintegrasi secara otomatis: Input Processing & Routing Telegram Trigger: Menangkap setiap pesan masu

Telegram Trigger, HTTP Request, Telegram +13
AI & RAG

Ideal for businesses that receive frequent inquiries about products or services and want to automate responses, freeing up time to focus on core operations. Polls your inbox for new incoming emails Cl

OpenAI Embeddings, Microsoft Outlook Trigger, OpenAI +11
AI & RAG

Who is this for? This workflow is ideal for HR teams, startups, and enterprises that want to handle employee interactions through WhatsApp and automate responses using LLM (OpenAI) and intelligent rou

WhatsApp Trigger, OpenAI, OpenAI Chat +13
AI & RAG

Chat with docs - 5minAI New version. Uses httpRequest, documentDefaultDataLoader, textSplitterRecursiveCharacterTextSplitter, embeddingsOpenAi. Event-driven trigger; 62 nodes.

HTTP Request, Document Default Data Loader, Text Splitter Recursive Character Text Splitter +10
AI & RAG

I prepared a detailed guide that illustrates the entire process of building an AI agent using Supabase and Google Drive within N8N workflows.

HTTP Request, Document Default Data Loader, Text Splitter Recursive Character Text Splitter +10