Respuestas automáticas de correo con GPT-4O y memoria de conversación de Supabase

Avanzado

Este es unSupport Chatbot, AI Chatbotflujo de automatización del dominio deautomatización que contiene 32 nodos.Utiliza principalmente nodos como If, Code, Postgres, Supabase, Aggregate. Respuestas automáticas de correo electrónico con memoria de conversación utilizando GPT-4O y Supabase

Requisitos previos
  • Información de conexión de la base de datos PostgreSQL
  • URL y Clave de API de Supabase
  • Pueden requerirse credenciales de autenticación para la API de destino
  • Clave de API de OpenAI
Vista previa del flujo de trabajo
Visualización de las conexiones entre nodos, con soporte para zoom y panorámica
Exportar flujo de trabajo
Copie la siguiente configuración JSON en n8n para importar y usar este flujo de trabajo
{
  "meta": {
    "instanceId": "7d7ddc233aab4d8c51542670cf7f945eb6d373593fbd55505f36a0a5efbbf885"
  },
  "nodes": [
    {
      "id": "2ea256d3-ba6f-4150-8f2b-e157b531967e",
      "name": "Embeddings 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": "Embeddings 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": "Activador de 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": "Limpiar 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(/&nbsp;/g, ' ')\n    .replace(/&quot;/g, '\"')\n    .replace(/&amp;/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": "Categorizar",
      "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": "Recuperación de Conversación",
      "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": "Iterar sobre Elementos1",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1280,
        224
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "77ac6486-243d-41b4-9822-81d79a219f82",
      "name": "Agregar1",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1904,
        224
      ],
      "parameters": {
        "options": {},
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "fieldToAggregate": "category"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "17e15174-3f73-4e93-9610-82891b90ae0a",
      "name": "Filtro de Spam",
      "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": "Gestor de Correos",
      "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": "Formatear",
      "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": "Base de Datos de Plantillas de Correo",
      "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": "Base de Datos de Preguntas Frecuentes",
      "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": "Responder",
      "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": "Responder1",
      "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": "¿Reenviar?",
      "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": "Recuperar Categorías",
      "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": "Ejecutar Flujo de Trabajo",
      "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": "Reenviar en 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": "Nota Adhesiva",
      "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": "Cuando se Ejecuta por Otro Flujo de Trabajo",
      "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 Vector Store4",
      "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": "Embeddings 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": "Cargador de Datos Predeterminado3",
      "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": "Divisor de Texto Recursivo3",
      "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
      "position": [
        1392,
        1184
      ],
      "parameters": {
        "options": {},
        "chunkSize": 10000
      },
      "typeVersion": 1
    },
    {
      "id": "24db4506-fdff-4710-b06d-0269dfa69d2c",
      "name": "Actualizar una fila2",
      "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": "Nota Adhesiva1",
      "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": "Nota Adhesiva2",
      "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": "Nota Adhesiva3",
      "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": "Nota Adhesiva4",
      "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
          }
        ]
      ]
    }
  }
}
Preguntas frecuentes

¿Cómo usar este flujo de trabajo?

Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.

¿En qué escenarios es adecuado este flujo de trabajo?

Avanzado - Chatbot de soporte, Chatbot de IA

¿Es de pago?

Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.

Información del flujo de trabajo
Nivel de dificultad
Avanzado
Número de nodos32
Categoría2
Tipos de nodos20
Descripción de la dificultad

Adecuado para usuarios avanzados, flujos de trabajo complejos con 16+ nodos

Autor

Firm believer that the best automation doesn't replace humans, but compliments their workflow.

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34