GPT-4O와 Supabase 대화 메모리를 사용한 자동 이메일 회신
고급
이것은Support Chatbot, AI Chatbot분야의자동화 워크플로우로, 32개의 노드를 포함합니다.주로 If, Code, Postgres, Supabase, Aggregate 등의 노드를 사용하며. GPT-4O와 Supabase 대화 메모리를 사용한 자동 이메일 회신
사전 요구사항
- •PostgreSQL 데이터베이스 연결 정보
- •Supabase URL과 API Key
- •대상 API의 인증 정보가 필요할 수 있음
- •OpenAI API Key
사용된 노드 (32)
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
"meta": {
"instanceId": "7d7ddc233aab4d8c51542670cf7f945eb6d373593fbd55505f36a0a5efbbf885"
},
"nodes": [
{
"id": "2ea256d3-ba6f-4150-8f2b-e157b531967e",
"name": "임베딩 OpenAI1",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
3184,
528
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "xKlH7tyFCN8T1zQi",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "8aa40c2d-d7db-4c09-9d57-ead456da3a19",
"name": "임베딩 OpenAI2",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
2880,
528
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "xKlH7tyFCN8T1zQi",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "ddbda963-adae-4555-a2df-a37e96a45de2",
"name": "Microsoft Outlook 트리거",
"type": "n8n-nodes-base.microsoftOutlookTrigger",
"position": [
1024,
224
],
"parameters": {
"output": "raw",
"filters": {
"readStatus": "unread",
"hasAttachments": false,
"foldersToInclude": [
"AQMkADAwATMwMAItNDc5YS02YzcyLTAwAi0wMAoALgAAAyr74A1aBA5FmGCW-N3seyYBAK7gOo5dtNlAihU21SrvhjMAAAIBDAAAAA=="
]
},
"options": {
"attachmentsPrefix": "attachment",
"downloadAttachments": false
},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
}
},
"credentials": {
"microsoftOutlookOAuth2Api": {
"id": "rsOPp75XXqgvG8j6",
"name": "Microsoft Outlook account"
}
},
"typeVersion": 1
},
{
"id": "bf25d741-540a-4c47-a656-477c150dfa0f",
"name": "HTML 정리",
"type": "n8n-nodes-base.code",
"position": [
1520,
224
],
"parameters": {
"jsCode": "const items = $input.all();\n\nreturn items.map(item => {\n let html = item.json.body.content;\n \n // FIRST: Remove quoted blocks while HTML is still structured\n html = html\n .replace(/<div class=\"gmail_quote\">[\\s\\S]*?<\\/div>/gi, '')\n .replace(/<blockquote[\\s\\S]*?<\\/blockquote>/gi, '')\n .replace(/<div[^>]*id=\"divRplyFwdMsg\"[\\s\\S]*?<\\/div>/gi, '')\n .replace(/<hr[^>]*>[\\s\\S]*$/gi, '');\n \n // THEN: Strip all HTML\n let text = html\n .replace(/<style[^>]*>.*?<\\/style>/gis, '')\n .replace(/<script[^>]*>.*?<\\/script>/gis, '')\n .replace(/<[^>]+>/g, '')\n .replace(/ /g, ' ')\n .replace(/"/g, '\"')\n .replace(/&/g, '&')\n .replace(/&[a-z]+;/gi, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n \n // FINALLY: Regex fallback for plain text quotes\n const quotePatterns = [\n /On\\s+.+?wrote:/i,\n /From:\\s*.+?Sent:/is,\n /_{5,}/,\n /-{5,}\\s*Original Message\\s*-{5,}/i\n ];\n \n let splitIndex = text.length;\n for (const pattern of quotePatterns) {\n const match = text.search(pattern);\n if (match !== -1 && match < splitIndex) {\n splitIndex = match;\n }\n }\n \n text = text.substring(0, splitIndex).trim();\n \n return {\n json: {\n ...item.json,\n cleanBody: text\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "0154c66d-cedc-4021-b895-ff00e91fc524",
"name": "분류",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
2112,
224
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"messages": {
"values": [
{
"content": "=Here are the email details:\nFrom Email: {{ $('Clean HTML').item.json.from.emailAddress.address }}\nFrom Name: {{ $('Clean HTML').item.json.from.emailAddress.name }}\nSubject: {{ $('Clean HTML').item.json.subject }}\nBody: {{ $('Clean HTML').item.json.cleanBody }}\n\n"
},
{
"role": "system",
"content": "=You are an email classifier for a [COMPANY].\n\n# Task:\n1. Categorize the incoming email based on the provided category list\n2. If the email strongly fits an existing category, use it\n3. If the email would be \"Other\" but represents a meaningful, recurring business pattern, create a new specific category\n4. Output in structured JSON\n\n# Current Categories:\n{{ $json.category }}\n\n# Spam Detection (Always check first):\n- Generic greetings with urgent money requests\n- Cryptocurrency, loans, prizes, inheritance scams\n- Suspicious links or poor grammar with urgency\n- Unsolicited financial offers\n\nIf spam detected, immediately output: {\"category\": \"SPAM\"}\n\n# Categorization Logic:\n1. Check if email clearly matches an existing category\n2. If yes: Use that category\n3. If no strong match: Evaluate if a NEW category would be beneficial\n\n# New Category Criteria (All must be true):\n- Represents a distinct, recurring business function for a construction company\n- Will likely receive multiple similar emails per month\n- Requires different handling than existing categories\n- Category name is specific and action-oriented\n- Not already covered by existing categories\n\n# Invalid New Category Examples:\n- \"Important\"\n- \"Urgent\"\n- \"Miscellaneous\"\n- \"Random Emails\"\n- \"Needs Review\"\n- \"Follow Up\"\n\n# Legitimate Business Patterns:\n- Specific project references\n- Construction/renovation terminology\n- Professional supplier/customer correspondence\n- Job applications with CV\n\n# Output Format (JSON only):\n{\n \"category\": \"string\"\n}\n\n# Rules:\n- SPAM always uses existing \"SPAM\" category\n- Only create new categories for legitimate, recurring business needs\n- If uncertain, use the closest existing category\n- New category names: 1-3 words, title case, construction-relevant\n- Only respond in valid JSON format"
}
]
},
"jsonOutput": true
},
"credentials": {
"openAiApi": {
"id": "xKlH7tyFCN8T1zQi",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "4e661d6c-b4f5-43f2-bc74-58ea5dc8b349",
"name": "JSON",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
3152,
144
],
"parameters": {
"jsonSchemaExample": "{\n \"body\": \"full email body with <br> tags for line breaks\",\n \"forward\": true\n}"
},
"typeVersion": 1.3
},
{
"id": "3ea7fe84-95e1-40ae-b992-11c637b85b55",
"name": "4o",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2976,
144
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "gpt-4o"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "xKlH7tyFCN8T1zQi",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "7beff76f-0000-4abf-b676-e9989d1def42",
"name": "대화 검색",
"type": "n8n-nodes-base.postgres",
"position": [
2640,
224
],
"parameters": {
"query": "SELECT subject, category, content, reply, date\nFROM emailreplies\nWHERE conversation_id = '{{ $('Clean HTML').item.json.conversationId }}';\n",
"options": {},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "lYn12YZBR5aezI4R",
"name": "Lukmanabdh21"
}
},
"executeOnce": false,
"typeVersion": 2.6,
"alwaysOutputData": true
},
{
"id": "63ac0d0b-5167-466d-8814-6cc4933b1390",
"name": "항목 순환1",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1280,
224
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "77ac6486-243d-41b4-9822-81d79a219f82",
"name": "집계1",
"type": "n8n-nodes-base.aggregate",
"position": [
1904,
224
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "category"
}
]
}
},
"typeVersion": 1
},
{
"id": "17e15174-3f73-4e93-9610-82891b90ae0a",
"name": "스팸 필터",
"type": "n8n-nodes-base.if",
"position": [
2432,
224
],
"parameters": {
"options": {
"ignoreCase": true
},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "99049b97-ec32-4af1-8f46-7362f431ce0d",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.message.content.category }}",
"rightValue": "spam"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "0fba875c-61ae-4779-861c-bf1d0c76a820",
"name": "이메일 관리자",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2992,
224
],
"parameters": {
"text": "=From: {{ $('Clean HTML').first().json.from.emailAddress.address }}\nName: {{ $('Clean HTML').first().json.from.emailAddress.name }}\nEmail Content: {{ $('Clean HTML').first().json.cleanBody }}\nCategory: {{ $('Categorize').item.json.message.content.category }}\nHas attachment: {{ $('Clean HTML').item.json.hasAttachments }}\nConversation History: {{ $json.conversationHistory }}\n",
"options": {
"systemMessage": "=You are an email assistant for a [COMPANY] drafting professional email replies.\n\n# Context Provided\n- From/Name: Sender details\n- Email Content: The message\n- Category: Email category \n- Has attachment: true/false\n- Conversation History: Previous exchanges (if any)\n\n# Process\n1. Check if email has attachment:\n - IF Has attachment = true: Skip to step 4 (draft acknowledgment + set forward=true)\n\n2. Use 'FAQ DB' tool to search for relevant answers\n - Evaluate results: Do they adequately answer the sender's question?\n - Are the results on-topic and helpful?\n\n3. Use 'Email Template DB' tool to find appropriate reply format\n - First search: \"Category: {{ $('Categorize').item.json.message.content.category }}. [relevant search terms]\"\n - If results seem off-topic or unhelpful: Retry without category prefix\n\n4. Determine action:\n - Can answer with confidence: Draft full reply, set forward=false\n - FAQ results are off-topic/incomplete: Draft placeholder, set forward=true\n - Email is a complaint/urgent/complex: Draft placeholder, set forward=true\n - Has attachment: Draft acknowledgment, set forward=true\n\n# Reply Templates\n- Full answer: Use FAQ information + Email Template style, personalized with sender's name\n- Placeholder (when forwarding):\n\"Dear [Name],<br><br>Thank you for your email. Our team will review your [request/question/attachment] and respond within 24 hours.<br><br>Best regards\"\n\n# Output Format (strict JSON only)\n{\n \"body\": \"full email body with <br> tags for line breaks\",\n \"forward\": true or false\n}\n\n# Rules\n- ALWAYS use both tools unless attachment is present\n- ALWAYS address sender by name in email body\n- Evaluate tool results based on relevance to the question, not scores\n- Set forward=true if: attachment present, FAQ unhelpful, or email requires human attention\n- Output valid JSON only\n- Use <br> tags for line breaks."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "5e2a8030-3705-44fe-9530-f2c79cccde0f",
"name": "형식",
"type": "n8n-nodes-base.code",
"position": [
2800,
224
],
"parameters": {
"jsCode": "// Get all input items\nconst items = $input.all();\n\n// Sort by date (earliest first)\nconst sortedItems = items.sort((a, b) => {\n const dateA = new Date(a.json.date);\n const dateB = new Date(b.json.date);\n return dateA - dateB;\n});\n\n// Build the formatted string\nlet output = '';\n\n// Add date, body and reply for each item\nsortedItems.forEach((item, index) => {\n const data = item.json;\n output += `Date ${index + 1}: ${data.date || ''}\\n`;\n output += `Body ${index + 1}: ${data.content || ''}\\n`;\n output += `Reply ${index + 1}: ${data.reply || ''}\\n`;\n});\n\n// Return the formatted string\nreturn [{ json: { conversationHistory: output } }];"
},
"typeVersion": 2
},
{
"id": "a23f1876-6ef1-4678-999b-1d39c969676c",
"name": "이메일 템플릿 DB",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
3184,
448
],
"parameters": {
"mode": "retrieve-as-tool",
"options": {
"queryName": "match_emailreplies"
},
"tableName": {
"__rl": true,
"mode": "list",
"value": "emailreplies",
"cachedResultName": "emailreplies"
},
"toolDescription": "Use this to find the most relevant email reply templates by vector similarity in the Email Reply Template table."
},
"credentials": {
"supabaseApi": {
"id": "c0kq8tDZCHRcBrV1",
"name": "Lukmanabdh21"
}
},
"typeVersion": 1.3
},
{
"id": "ddfbc5a8-9449-4bde-87ea-9a807d843e21",
"name": "FAQ DB",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
2880,
448
],
"parameters": {
"mode": "retrieve-as-tool",
"options": {
"queryName": "match_faq"
},
"tableName": {
"__rl": true,
"mode": "list",
"value": "faq",
"cachedResultName": "faq"
},
"toolDescription": "Use this to find the most relevant FAQ by vector similarity in the FAQ table."
},
"credentials": {
"supabaseApi": {
"id": "c0kq8tDZCHRcBrV1",
"name": "Lukmanabdh21"
}
},
"typeVersion": 1.3
},
{
"id": "8f31665f-f493-4ad6-b14e-9b6bb6e49cdd",
"name": "답장",
"type": "n8n-nodes-base.microsoftOutlook",
"position": [
3584,
304
],
"webhookId": "0beecb97-10fb-4640-9056-74268311baa2",
"parameters": {
"message": "={{ $json.output.body }}",
"options": {},
"messageId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Clean HTML').item.json.id }}"
},
"operation": "reply"
},
"credentials": {
"microsoftOutlookOAuth2Api": {
"id": "rsOPp75XXqgvG8j6",
"name": "Microsoft Outlook account"
}
},
"typeVersion": 2
},
{
"id": "9dacab9f-27f1-4fe8-a826-3957d75207d7",
"name": "답장1",
"type": "n8n-nodes-base.microsoftOutlook",
"position": [
3584,
128
],
"webhookId": "0beecb97-10fb-4640-9056-74268311baa2",
"parameters": {
"message": "={{ $json.output.body }}",
"options": {},
"messageId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Clean HTML').item.json.id }}"
},
"operation": "reply"
},
"credentials": {
"microsoftOutlookOAuth2Api": {
"id": "rsOPp75XXqgvG8j6",
"name": "Microsoft Outlook account"
}
},
"typeVersion": 2
},
{
"id": "e0ce9f54-37ef-42b4-b807-60b8f6de35a8",
"name": "전달?",
"type": "n8n-nodes-base.if",
"position": [
3312,
224
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0abfde8c-38e2-48fe-918a-f10f962a2d63",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.output.forward }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "1a6ce559-bd71-4dd0-b1cb-9dd40efdb3e0",
"name": "분류 검색",
"type": "n8n-nodes-base.postgres",
"position": [
1712,
224
],
"parameters": {
"query": "SELECT DISTINCT category\nFROM emailreplies;",
"options": {},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "lYn12YZBR5aezI4R",
"name": "Lukmanabdh21"
}
},
"executeOnce": true,
"typeVersion": 2.6
},
{
"id": "cbd88406-110c-4dd8-8d77-2a48a1424e18",
"name": "워크플로 실행",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
4096,
224
],
"parameters": {
"options": {},
"workflowId": {
"__rl": true,
"mode": "id",
"value": "l6VbNoViT2nEeTmN"
},
"workflowInputs": {
"value": {
"body": "={{ $('Clean HTML').item.json.cleanBody }}",
"date": "={{ $('Clean HTML').item.json.receivedDateTime }}",
"reply": "={{ $('Email Manager').item.json.output.body }}",
"subject": "={{ $('Clean HTML').item.json.subject }}",
"category": "={{ $('Categorize').item.json.message.content.category }}",
"conversationID": "={{ $('Clean HTML').item.json.conversationId }}"
},
"schema": [
{
"id": "subject",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "subject",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "body",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "body",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "category",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "category",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "reply",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "reply",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "date",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "conversationID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "conversationID",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2
},
{
"id": "d0c6e016-a059-4f12-bb17-5aeb685c4a2f",
"name": "Outlook 전달",
"type": "n8n-nodes-base.httpRequest",
"position": [
3792,
128
],
"parameters": {
"url": "=https://graph.microsoft.com/v1.0/me/messages/{{ $('Clean HTML').item.json.id }}/forward",
"method": "POST",
"options": {},
"jsonBody": "={\n \"toRecipients\": [\n {\n \"emailAddress\": {\n \"address\": \"\"\n }\n }\n ],\n \"comment\": \"Please review the following email\"\n }",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "microsoftOutlookOAuth2Api"
},
"credentials": {
"microsoftOutlookOAuth2Api": {
"id": "rsOPp75XXqgvG8j6",
"name": "Microsoft Outlook account"
}
},
"typeVersion": 4.2
},
{
"id": "e7d9b7a8-ba35-4734-b212-6eb64d23f265",
"name": "스티키 노트",
"type": "n8n-nodes-base.stickyNote",
"position": [
480,
-16
],
"parameters": {
"width": 400,
"height": 560,
"content": "# Automation Overview\n\n1. Polls inbox for incoming emails\n2. Cleans HTML tags to reduce token bloating\n3. Identifies existing categories the emails could fall under\n4. LLM categorizes it and identifies spam\n5. Filters out spam emails\n6. Identifies whether or not an existing conversation exists\n7. AI Agent uses conversation history (if available) for context and uses FAQ documents ingested in Supabase to answer incoming questions\n8. If it can confidently answer, it will use an email template to structure it's reply\n9. If it can't answer using the FAQ documents, it will flag for human review.\n10. Every email gets ingested into Supabase to build a database of conversation history"
},
"typeVersion": 1
},
{
"id": "67b4bb5a-0e42-4191-97d7-db66a033c7e7",
"name": "다른 워크플로에 의해 실행 시",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
1040,
960
],
"parameters": {
"inputSource": "jsonExample",
"jsonExample": "{\n \"subject\": \"\",\n \"body\": \"\",\n \"category\": \"\",\n \"reply\": \"\",\n \"date\": \"\",\n \"conversationID\": \"\"\n}"
},
"typeVersion": 1.1
},
{
"id": "e3de77e5-f79f-4904-b43c-2f8ba4a55f45",
"name": "Supabase 벡터 저장소4",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
1296,
960
],
"parameters": {
"mode": "insert",
"options": {
"queryName": "match_emailreplies"
},
"tableName": {
"__rl": true,
"mode": "list",
"value": "emailreplies",
"cachedResultName": "emailreplies"
}
},
"credentials": {
"supabaseApi": {
"id": "c0kq8tDZCHRcBrV1",
"name": "Lukmanabdh21"
}
},
"typeVersion": 1.3
},
{
"id": "49825c43-d994-45a9-92e7-4f8b0ef903b6",
"name": "임베딩 OpenAI6",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
1296,
1056
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "xKlH7tyFCN8T1zQi",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "8499257a-c029-4a1b-81e1-73d8ce8694cf",
"name": "기본 데이터 로더3",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
1392,
1104
],
"parameters": {
"options": {},
"jsonData": "=\"subject\": \"{{ $json.subject }}\",\n\"body\": \"{{ $json.body }}\",\n\"category\": \"{{ $json.category }}\"",
"jsonMode": "expressionData",
"textSplittingMode": "custom"
},
"typeVersion": 1.1
},
{
"id": "8defcd27-ca6a-4734-890a-9b7abb18430e",
"name": "재귀 문자 텍스트 분할기3",
"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
"position": [
1392,
1184
],
"parameters": {
"options": {},
"chunkSize": 10000
},
"typeVersion": 1
},
{
"id": "24db4506-fdff-4710-b06d-0269dfa69d2c",
"name": "행 업데이트2",
"type": "n8n-nodes-base.supabase",
"position": [
1648,
960
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "content",
"keyValue": "={{ $json.pageContent }}",
"condition": "eq"
}
]
},
"tableId": "emailreplies",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "category",
"fieldValue": "={{ $('When Executed by Another Workflow').item.json.category }}"
},
{
"fieldId": "flag",
"fieldValue": "FALSE"
},
{
"fieldId": "subject",
"fieldValue": "={{ $('When Executed by Another Workflow').item.json.subject }}"
},
{
"fieldId": "conversation_id",
"fieldValue": "={{ $('When Executed by Another Workflow').item.json.conversationID }}"
},
{
"fieldId": "date",
"fieldValue": "={{ $('When Executed by Another Workflow').item.json.date }}"
},
{
"fieldId": "reply",
"fieldValue": "={{ $('When Executed by Another Workflow').item.json.reply }}"
}
]
},
"matchType": "allFilters",
"operation": "update"
},
"credentials": {
"supabaseApi": {
"id": "c0kq8tDZCHRcBrV1",
"name": "Lukmanabdh21"
}
},
"typeVersion": 1
},
{
"id": "eb2c31e8-7bb9-4842-83de-1483f5ffd1b1",
"name": "스티키 노트1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
16
],
"parameters": {
"width": 1072,
"height": 432,
"content": "# Phase 1\n- Every email gets stripped of HTML\n- Categorized via LLM\n- Filter for spam"
},
"typeVersion": 1
},
{
"id": "4c30cd33-812b-43a7-9403-ef5d0a9d35d0",
"name": "스티키 노트2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2560,
16
],
"parameters": {
"color": 4,
"width": 864,
"height": 704,
"content": "# Phase 2\n- Conversation history retrieved to provide AI agent context\n- AI agent has access to FAQ and Email Reply Template database stored in Supabase and will make one of two decisions: Flag for human review or reply using answer found in FAQ"
},
"typeVersion": 1
},
{
"id": "fc47df97-6055-412d-8f6a-a6979157ba0a",
"name": "스티키 노트3",
"type": "n8n-nodes-base.stickyNote",
"position": [
3424,
16
],
"parameters": {
"color": 5,
"width": 864,
"height": 496,
"content": "# Phase 3\n- Route determined by AI agent's ability to answer\n- Email + response sent to a subworkflow to ingest into Supabase to be used as training data and retain conversation history"
},
"typeVersion": 1
},
{
"id": "2524c1d1-9364-41fd-9cfd-64ec3f7ddbc8",
"name": "스티키 노트4",
"type": "n8n-nodes-base.stickyNote",
"position": [
992,
752
],
"parameters": {
"color": 7,
"width": 864,
"height": 576,
"content": "# Phase 4\n- Subworkflow to ingest email + response into Supabase via vector embedding"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"3ea7fe84-95e1-40ae-b992-11c637b85b55": {
"ai_languageModel": [
[
{
"node": "0fba875c-61ae-4779-861c-bf1d0c76a820",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"4e661d6c-b4f5-43f2-bc74-58ea5dc8b349": {
"ai_outputParser": [
[
{
"node": "0fba875c-61ae-4779-861c-bf1d0c76a820",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"8f31665f-f493-4ad6-b14e-9b6bb6e49cdd": {
"main": [
[
{
"node": "cbd88406-110c-4dd8-8d77-2a48a1424e18",
"type": "main",
"index": 0
}
]
]
},
"ddfbc5a8-9449-4bde-87ea-9a807d843e21": {
"ai_tool": [
[
{
"node": "0fba875c-61ae-4779-861c-bf1d0c76a820",
"type": "ai_tool",
"index": 0
}
]
]
},
"5e2a8030-3705-44fe-9530-f2c79cccde0f": {
"main": [
[
{
"node": "0fba875c-61ae-4779-861c-bf1d0c76a820",
"type": "main",
"index": 0
}
]
]
},
"9dacab9f-27f1-4fe8-a826-3957d75207d7": {
"main": [
[
{
"node": "d0c6e016-a059-4f12-bb17-5aeb685c4a2f",
"type": "main",
"index": 0
}
]
]
},
"e0ce9f54-37ef-42b4-b807-60b8f6de35a8": {
"main": [
[
{
"node": "9dacab9f-27f1-4fe8-a826-3957d75207d7",
"type": "main",
"index": 0
}
],
[
{
"node": "8f31665f-f493-4ad6-b14e-9b6bb6e49cdd",
"type": "main",
"index": 0
}
]
]
},
"77ac6486-243d-41b4-9822-81d79a219f82": {
"main": [
[
{
"node": "0154c66d-cedc-4021-b895-ff00e91fc524",
"type": "main",
"index": 0
}
]
]
},
"0154c66d-cedc-4021-b895-ff00e91fc524": {
"main": [
[
{
"node": "17e15174-3f73-4e93-9610-82891b90ae0a",
"type": "main",
"index": 0
}
]
]
},
"bf25d741-540a-4c47-a656-477c150dfa0f": {
"main": [
[
{
"node": "1a6ce559-bd71-4dd0-b1cb-9dd40efdb3e0",
"type": "main",
"index": 0
}
]
]
},
"17e15174-3f73-4e93-9610-82891b90ae0a": {
"main": [
[
{
"node": "7beff76f-0000-4abf-b676-e9989d1def42",
"type": "main",
"index": 0
}
],
[
{
"node": "63ac0d0b-5167-466d-8814-6cc4933b1390",
"type": "main",
"index": 0
}
]
]
},
"0fba875c-61ae-4779-861c-bf1d0c76a820": {
"main": [
[
{
"node": "e0ce9f54-37ef-42b4-b807-60b8f6de35a8",
"type": "main",
"index": 0
}
]
]
},
"d0c6e016-a059-4f12-bb17-5aeb685c4a2f": {
"main": [
[
{
"node": "cbd88406-110c-4dd8-8d77-2a48a1424e18",
"type": "main",
"index": 0
}
]
]
},
"cbd88406-110c-4dd8-8d77-2a48a1424e18": {
"main": [
[
{
"node": "63ac0d0b-5167-466d-8814-6cc4933b1390",
"type": "main",
"index": 0
}
]
]
},
"63ac0d0b-5167-466d-8814-6cc4933b1390": {
"main": [
[],
[
{
"node": "bf25d741-540a-4c47-a656-477c150dfa0f",
"type": "main",
"index": 0
}
]
]
},
"a23f1876-6ef1-4678-999b-1d39c969676c": {
"ai_tool": [
[
{
"node": "0fba875c-61ae-4779-861c-bf1d0c76a820",
"type": "ai_tool",
"index": 0
}
]
]
},
"2ea256d3-ba6f-4150-8f2b-e157b531967e": {
"ai_embedding": [
[
{
"node": "a23f1876-6ef1-4678-999b-1d39c969676c",
"type": "ai_embedding",
"index": 0
}
]
]
},
"8aa40c2d-d7db-4c09-9d57-ead456da3a19": {
"ai_embedding": [
[
{
"node": "ddfbc5a8-9449-4bde-87ea-9a807d843e21",
"type": "ai_embedding",
"index": 0
}
]
]
},
"49825c43-d994-45a9-92e7-4f8b0ef903b6": {
"ai_embedding": [
[
{
"node": "e3de77e5-f79f-4904-b43c-2f8ba4a55f45",
"type": "ai_embedding",
"index": 0
}
]
]
},
"1a6ce559-bd71-4dd0-b1cb-9dd40efdb3e0": {
"main": [
[
{
"node": "77ac6486-243d-41b4-9822-81d79a219f82",
"type": "main",
"index": 0
}
]
]
},
"8499257a-c029-4a1b-81e1-73d8ce8694cf": {
"ai_document": [
[
{
"node": "e3de77e5-f79f-4904-b43c-2f8ba4a55f45",
"type": "ai_document",
"index": 0
}
]
]
},
"7beff76f-0000-4abf-b676-e9989d1def42": {
"main": [
[
{
"node": "5e2a8030-3705-44fe-9530-f2c79cccde0f",
"type": "main",
"index": 0
}
]
]
},
"e3de77e5-f79f-4904-b43c-2f8ba4a55f45": {
"main": [
[
{
"node": "24db4506-fdff-4710-b06d-0269dfa69d2c",
"type": "main",
"index": 0
}
]
]
},
"ddbda963-adae-4555-a2df-a37e96a45de2": {
"main": [
[
{
"node": "63ac0d0b-5167-466d-8814-6cc4933b1390",
"type": "main",
"index": 0
}
]
]
},
"67b4bb5a-0e42-4191-97d7-db66a033c7e7": {
"main": [
[
{
"node": "e3de77e5-f79f-4904-b43c-2f8ba4a55f45",
"type": "main",
"index": 0
}
]
]
},
"8defcd27-ca6a-4734-890a-9b7abb18430e": {
"ai_textSplitter": [
[
{
"node": "8499257a-c029-4a1b-81e1-73d8ce8694cf",
"type": "ai_textSplitter",
"index": 0
}
]
]
}
}
}자주 묻는 질문
이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
고급 - 지원 챗봇, AI 챗봇
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
컨텍스트 혼합 RAG AI 콘텐츠
Google Drive에서 Supabase 상황 벡터 데이터베이스로 동기화, RAG 애플리케이션 사용
If
Set
Code
+
If
Set
Code
76 노드Michael Taleb
AI RAG
배달 햄버거점 MVP
🤖 레스토랑과 배달 자동화의 AI 드라이브 WhatsApp 도우미
If
Set
Code
+
If
Set
Code
152 노드Bruno Dias
시각화 참조 라이브러리에서 n8n 노드를 탐색
可视化 참조 라이브러리에서 n8n 노드를 탐색
If
Ftp
Set
+
If
Ftp
Set
113 노드I versus AI
기타
반려동물 가게 4
🐶 펫 샵 예약 AI 대리자
If
Set
Code
+
If
Set
Code
187 노드Bruno Dias
인공지능
[템플릿] AI 반려동물 가게 v8
🐶 AI 펫 샵 어시스턴트 - GPT-4o, Google 캘린더 및 WhatsApp/Instagram/Facebook 통합
If
N8n
Set
+
If
N8n
Set
244 노드Amanda Benks
영업
AI 대리인 레스토랑 [템플릿]
🤖 WhatsApp, 인스타그램, 메신저의 AI 레스토랑 도우미
If
N8n
Set
+
If
N8n
Set
239 노드Amanda Benks
기타
워크플로우 정보
난이도
고급
노드 수32
카테고리2
노드 유형20
저자
Lukman
@lukmanabdhFirm believer that the best automation doesn't replace humans, but compliments their workflow.
외부 링크
n8n.io에서 보기 →
이 워크플로우 공유