AutomationFlowsAI & RAG › AI Email Agent - Complete System

AI Email Agent - Complete System

AI Email Agent - Complete System. Uses gmailTrigger, gmail, vectorStorePGVector, embeddingsOpenAi. Event-driven trigger; 47 nodes.

Event trigger★★★★★ complexityAI-powered47 nodesGmail TriggerGmailVector Store PgvectorOpenAI EmbeddingsDocument Default Data LoaderText Splitter Recursive Character Text SplitterDiscordOpenAI
AI & RAG Trigger: Event Nodes: 47 Complexity: ★★★★★ AI nodes: yes Added:
AI Email Agent - Complete System — n8n workflow card showing Gmail Trigger, Gmail, Vector Store Pgvector integration

This workflow follows the Agent → Discord 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
{
  "name": "AI Email Agent - Complete System",
  "nodes": [
    {
      "parameters": {
        "content": "## \ud83e\udd16 AI Email Agent - H\u1ec7 th\u1ed1ng ho\u00e0n ch\u1ec9nh\n\n### Flow A (m\u00e0u cam): Email Ingestion\nGmail Trigger \u2192 L\u1ea5y n\u1ed9i dung \u2192 Ph\u00e2n lo\u1ea1i + T\u00f3m t\u1eaft (Gemini) \u2192 L\u01b0u PGVector \u2192 Th\u00f4ng b\u00e1o WhatsApp\n\n### Flow B (m\u00e0u xanh): WhatsApp RAG Agent\nWhatsApp Webhook \u2192 Ph\u00e1t hi\u1ec7n intent \u2192 RAG Chat / T\u1ea1o Draft / C\u00e0i \u0111\u1eb7t / Help\n\n### \u26a0\ufe0f C\u1ea7n thay th\u1ebf Credential IDs:\n- GMAIL_CRED_ID \u2192 ID credential Gmail OAuth2\n- OPENAI_CRED_ID \u2192 ID credential OpenAI\n- POSTGRES_CRED_ID \u2192 ID credential PostgreSQL\n- WHATSAPP_CRED_ID \u2192 ID credential WhatsApp Business\n\n### \ud83d\udce6 SQL Setup (ch\u1ea1y tr\u00ean RDS tr\u01b0\u1edbc):\n```sql\nCREATE EXTENSION IF NOT EXISTS vector;\n\nCREATE TABLE IF NOT EXISTS emails_vector_store (\n  id bigserial PRIMARY KEY,\n  content text,\n  metadata jsonb,\n  embedding vector(1536)\n);\n\nCREATE INDEX ON emails_vector_store\n  USING hnsw (embedding vector_cosine_ops);\n\nCREATE TABLE IF NOT EXISTS user_preferences (\n  phone_number varchar(30) PRIMARY KEY,\n  email_style varchar(50) DEFAULT 'professional',\n  response_language varchar(10) DEFAULT 'vi',\n  summary_length varchar(20) DEFAULT 'medium',\n  custom_categories jsonb DEFAULT '[\"C\u00f4ng vi\u1ec7c\",\"C\u00e1 nh\u00e2n\",\"M\u1ea1ng x\u00e3 h\u1ed9i\",\"Qu\u1ea3ng c\u00e1o\",\"H\u00f3a \u0111\u01a1n\",\"Kh\u00e1c\"]',\n  updated_at timestamp DEFAULT NOW()\n);\n\nCREATE TABLE IF NOT EXISTS n8n_chat_histories (\n  id serial PRIMARY KEY,\n  session_id varchar(255),\n  data jsonb,\n  created_at timestamp DEFAULT NOW()\n);\n```",
        "height": 872,
        "width": 540,
        "color": 7
      },
      "id": "7f93bfae-09d2-45de-8859-3602ca456d69",
      "name": "\ud83d\udccb T\u00e0i li\u1ec7u h\u1ec7 th\u1ed1ng",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -176
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "content": "## \ud83d\udce8 FLOW A: Email Ingestion\nT\u1ef1 \u0111\u1ed9ng x\u1eed l\u00fd email m\u1edbi \u2192 Vector Store \u2192 Discord",
        "height": 1844,
        "width": 2532,
        "color": 3
      },
      "id": "7ba68b1c-892a-4775-8d62-092e81a8e687",
      "name": "Flow A Header",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        784,
        0
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "filters": {}
      },
      "id": "10518394-e395-4f5a-9d55-8fad79e1fe0e",
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        864,
        256
      ],
      "typeVersion": 1.2,
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "get",
        "messageId": "={{ $json.id }}",
        "simple": false,
        "options": {}
      },
      "id": "5dbd16b5-c74c-4f8d-81f2-e74e2824af78",
      "name": "Get Mail Data",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1056,
        256
      ],
      "typeVersion": 2.1,
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// ============================================================\n// X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI \u2014 t\u00e1ch bi\u1ec7t AI output vs d\u1eef li\u1ec7u email g\u1ed1c\n// ============================================================\nconst items = $input.all();\nconst results = [];\n\nfor (const item of items) {\n  // -----------------------------------------------------------\n  // 1. L\u1ea4Y D\u1eee LI\u1ec6U EMAIL G\u1ed0C t\u1eeb node \"Get Mail Data\"\n  // -----------------------------------------------------------\n  let emailData = {};\n  try {\n    emailData = $('Get Mail Data').item.json;\n  } catch (e) {\n    // N\u1ebfu kh\u00f4ng t\u00ecm \u0111\u01b0\u1ee3c, fallback v\u1ec1 item hi\u1ec7n t\u1ea1i\n    emailData = item.json;\n  }\n\n  // -----------------------------------------------------------\n  // 2. EXTRACT AI OUTPUT (t\u1eeb node \"Message a model\")\n  // H\u1ed7 tr\u1ee3 nhi\u1ec1u format output c\u1ee7a OpenAI / Langchain node\n  // -----------------------------------------------------------\n  const aiRaw = item.json;\n  let rawString =\n    // n8n OpenAI node (langchain) v2.x\n    aiRaw?.content?.[0]?.text ||\n    aiRaw?.content?.[0]?.content ||\n    (Array.isArray(aiRaw?.content) ? aiRaw.content.map(c => c.text || c.content || '').join('') : '') ||\n    // n8n OpenAI node legacy\n    aiRaw?.choices?.[0]?.message?.content ||\n    // Generic fallbacks\n    aiRaw?.output?.[0]?.content?.[0]?.text ||\n    aiRaw?.output?.[0]?.text ||\n    aiRaw?.output_text ||\n    aiRaw?.message?.content ||\n    aiRaw?.text ||\n    (typeof aiRaw?.content === 'string' ? aiRaw.content : '') ||\n    '';\n\n  // -----------------------------------------------------------\n  // 3. PARSE JSON t\u1eeb AI output\n  // -----------------------------------------------------------\n  let aiResult = {};\n  if (typeof rawString === 'string' && rawString.includes('{')) {\n    try {\n      const clean = rawString\n        .replace(/```json/gi, '')\n        .replace(/```/g, '')\n        .trim();\n      // T\u00ecm block JSON \u0111\u1ea7u ti\u00ean n\u1ebfu c\u00f3 text th\u1eeba xung quanh\n      const jsonMatch = clean.match(/\\{[\\s\\S]*\\}/);\n      if (jsonMatch) {\n        aiResult = JSON.parse(jsonMatch[0]);\n      }\n    } catch (e) {\n      // AI kh\u00f4ng tr\u1ea3 JSON h\u1ee3p l\u1ec7 \u2192 gi\u1eef nguy\u00ean r\u1ed7ng, fallback b\u00ean d\u01b0\u1edbi\n    }\n  }\n\n  // -----------------------------------------------------------\n  // 4. N\u1ed8I DUNG EMAIL (body) \u2014 l\u1ea5y t\u1eeb email g\u1ed1c\n  // -----------------------------------------------------------\n  const bodyText = (\n    emailData.text ||\n    emailData.textPlain ||\n    emailData.snippet ||\n    ''\n  ).trim();\n\n  const textLower = bodyText.toLowerCase();\n\n  // -----------------------------------------------------------\n  // 5. SUBJECT \u2014 t\u1eeb email g\u1ed1c\n  // -----------------------------------------------------------\n  const subject =\n    emailData.subject ||\n    emailData.headers?.subject ||\n    '(kh\u00f4ng c\u00f3 ti\u00eau \u0111\u1ec1)';\n\n  // -----------------------------------------------------------\n  // 6. FROM \u2014 h\u1ed7 tr\u1ee3 c\u1ea3 Gmail full format v\u00e0 simple format\n  // -----------------------------------------------------------\n  let from_name = '';\n  let from_address = '';\n\n  if (emailData.from?.value?.[0]?.address) {\n    from_name    = emailData.from.value[0].name    || '';\n    from_address = emailData.from.value[0].address || '';\n  } else if (typeof emailData.from === 'string') {\n    const match = emailData.from.match(/^(.*?)\\s*<(.+?)>$/);\n    if (match) {\n      from_name    = match[1].trim();\n      from_address = match[2].trim();\n    } else {\n      from_address = emailData.from.trim();\n    }\n  } else if (emailData.headers?.from) {\n    const match = emailData.headers.from.match(/^(.*?)\\s*<(.+?)>$/);\n    if (match) {\n      from_name    = match[1].trim();\n      from_address = match[2].trim();\n    } else {\n      from_address = emailData.headers.from.trim();\n    }\n  }\n\n  // -----------------------------------------------------------\n  // 7. TO ADDRESS\n  // -----------------------------------------------------------\n  let to_address = '';\n  if (emailData.to?.value?.[0]?.address) {\n    to_address = emailData.to.value[0].address;\n  } else if (typeof emailData.to === 'string') {\n    const m = emailData.to.match(/<(.+?)>/);\n    to_address = m ? m[1] : emailData.to.trim();\n  }\n\n  // -----------------------------------------------------------\n  // 8. MESSAGE ID & DATE\n  // -----------------------------------------------------------\n  const message_id =\n    emailData.id ||\n    emailData.messageId ||\n    emailData.message_id ||\n    '';\n\n  const emailDate =\n    emailData.date ||\n    emailData.internalDate ||\n    new Date().toISOString();\n\n  // -----------------------------------------------------------\n  // 9. AI FIELDS \u2014 \u01b0u ti\u00ean k\u1ebft qu\u1ea3 AI, fallback v\u1ec1 rule-based\n  // -----------------------------------------------------------\n\n  // CATEGORY\n  let category = aiResult.category || '';\n  if (!category || category === 'Kh\u00e1c') {\n    if (/otp|m\u00e3 x\u00e1c nh\u1eadn|verification code|security code/.test(textLower))     category = 'OTP/B\u1ea3o m\u1eadt';\n    else if (/invoice|receipt|bill|payment|h\u00f3a \u0111\u01a1n/.test(textLower))           category = 'H\u00f3a \u0111\u01a1n';\n    else if (/sale|discount|promotion|offer|unsubscribe|khuy\u1ebfn m\u00e3i/.test(textLower)) category = 'Qu\u1ea3ng c\u00e1o';\n    else if (/facebook|instagram|linkedin|twitter/.test(textLower))             category = 'M\u1ea1ng x\u00e3 h\u1ed9i';\n    else if (/meeting|deadline|project|client|h\u1ecdp|d\u1ef1 \u00e1n/.test(textLower))      category = 'C\u00f4ng vi\u1ec7c';\n    else if (/\u0111i ch\u01a1i|cafe|\u0103n|h\u1eb9n|party/.test(textLower))                      category = 'C\u00e1 nh\u00e2n';\n    else                                                                         category = aiResult.category || 'Kh\u00e1c';\n  }\n\n  // PRIORITY\n  let priority = aiResult.priority || '';\n  if (!priority) {\n    if (/otp|g\u1ea5p|asap|h\u00f4m nay|urgent/.test(textLower)) priority = 'high';\n    else if (category === 'C\u00f4ng vi\u1ec7c')                  priority = 'medium';\n    else                                                priority = 'low';\n  }\n\n  // SUMMARY\n  let summary = (aiResult.summary || '').trim();\n  if (!summary) summary = bodyText.slice(0, 200) || 'Email ng\u1eafn, kh\u00f4ng \u0111\u1ee7 th\u00f4ng tin \u0111\u1ec3 t\u00f3m t\u1eaft';\n\n  // KEY POINTS\n  let key_points = Array.isArray(aiResult.key_points) ? aiResult.key_points : [];\n  if (key_points.length === 0 && summary) key_points = [summary];\n\n  // SUGGESTED ACTION\n  const suggested_action = (aiResult.suggested_action || '').trim();\n\n  // REPLY NEEDED\n  const reply_needed =\n    typeof aiResult.reply_needed === 'boolean'\n      ? aiResult.reply_needed\n      : category === 'C\u00f4ng vi\u1ec7c';\n\n  // SENTIMENT\n  const sentiment = aiResult.sentiment || 'neutral';\n\n  // -----------------------------------------------------------\n  // 10. discord MESSAGE\n  // -----------------------------------------------------------\n  const priorityLabel =\n    priority === 'high'   ? '\ud83d\udd34 Cao' :\n    priority === 'medium' ? '\ud83d\udfe1 Trung b\u00ecnh' :\n                            '\ud83d\udfe2 Th\u1ea5p';\n\n  const discord_message =\n`\ud83d\udce7 *Email m\u1edbi*\n\n\ud83d\udcc2 *Lo\u1ea1i:* ${category}\n\u26a1 *\u01afu ti\u00ean:* ${priorityLabel}\n\ud83d\udc64 *T\u1eeb:* ${from_name}${from_address ? ' (' + from_address + ')' : ''}\n\ud83d\udccc *Ti\u00eau \u0111\u1ec1:* ${subject}\n\ud83d\udcc5 *Ng\u00e0y:* ${emailDate}\n\n\ud83d\udcdd *T\u00f3m t\u1eaft:*\n${summary}\n\n${key_points.length > 0 ? '\ud83d\udd11 *\u0110i\u1ec3m ch\u00ednh:*\\n' + key_points.map(p => '\u2022 ' + p).join('\\n') + '\\n\\n' : ''}${suggested_action ? '\ud83d\udca1 *\u0110\u1ec1 xu\u1ea5t:* ' + suggested_action + '\\n\\n' : ''}${reply_needed ? '\u26a0\ufe0f _Email n\u00e0y c\u1ea7n tr\u1ea3 l\u1eddi_' : ''}\n\n_H\u1ecfi v\u1ec1 email n\u00e0y: g\u00f5 c\u00e2u h\u1ecfi b\u1ea5t k\u1ef3_`;\n\n  // -----------------------------------------------------------\n  // 11. OUTPUT\n  // -----------------------------------------------------------\n  results.push({\n    json: {\n      category,\n      priority,\n      summary,\n      key_points,\n      suggested_action,\n      reply_needed,\n      sentiment,\n      subject,\n      from_name,\n      from_address,\n      to_address,\n      date: emailDate,\n      message_id,\n      body_text: bodyText,\n      id: message_id,\n      discord_message\n    }\n  });\n}\n\nreturn results;"
      },
      "id": "1abc02d0-93df-4267-ba67-9ad0b698888c",
      "name": "X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI",
      "type": "n8n-nodes-base.code",
      "position": [
        1904,
        368
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "mode": "insert",
        "tableName": "emails_vector_store",
        "options": {}
      },
      "id": "cf425db2-2329-4b97-9fce-f1177d1b55ed",
      "name": "L\u01b0u v\u00e0o PGVector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
      "position": [
        2576,
        144
      ],
      "typeVersion": 1.1,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "961b7d17-5ae0-40c5-9304-7597aadae10d",
      "name": "Embeddings for Insert",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        2544,
        352
      ],
      "typeVersion": 1.2,
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsonMode": "expressionData",
        "jsonData": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.subject + '\\n\\n' + ($('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.body_text || '') }}",
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "source",
                "value": "gmail"
              },
              {
                "name": "message_id",
                "value": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.message_id }}"
              },
              {
                "name": "category",
                "value": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.category }}"
              },
              {
                "name": "from_address",
                "value": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.from_address }}"
              },
              {
                "name": "from_name",
                "value": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.from_name }}"
              },
              {
                "name": "subject",
                "value": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.subject }}"
              },
              {
                "name": "date",
                "value": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.date }}"
              },
              {
                "name": "priority",
                "value": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.priority }}"
              },
              {
                "name": "reply_needed",
                "value": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.reply_needed }}"
              },
              {
                "name": "sentiment",
                "value": "={{ $('X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI').item.json.sentiment }}"
              }
            ]
          }
        }
      },
      "id": "57550332-6054-4b5a-ae77-7fca3a8d81bc",
      "name": "Email Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        2784,
        352
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "chunkSize": 1500,
        "chunkOverlap": 150,
        "options": {}
      },
      "id": "a65e1665-fee8-4fc9-aafb-4f1575f9f132",
      "name": "Email Text Splitter",
      "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
      "position": [
        2944,
        544
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wa-msg-1",
              "name": "wa_message",
              "value": "={{ \n'\ud83d\udce7 *Email m\u1edbi*\\n\\n' +\n'\ud83d\udcc2 *Lo\u1ea1i:* ' + $json.category + '\\n' +\n'\u26a1 *\u01afu ti\u00ean:* ' + ($json.priority === 'high' ? '\ud83d\udd34 Cao' : $json.priority === 'medium' ? '\ud83d\udfe1 Trung b\u00ecnh' : '\ud83d\udfe2 Th\u1ea5p') + '\\n' +\n'\ud83d\udc64 *T\u1eeb:* ' + $json.from_name + ' (' + $json.from_address + ')\\n' +\n'\ud83d\udccc *Ti\u00eau \u0111\u1ec1:* ' + $json.subject + '\\n' +\n'\ud83d\udcc5 *Ng\u00e0y:* ' + $json.date + '\\n\\n' +\n'\ud83d\udcdd *T\u00f3m t\u1eaft:*\\n' + $json.summary + '\\n\\n' +\n($json.key_points?.length > 0 ? '\ud83d\udd11 *\u0110i\u1ec3m ch\u00ednh:*\\n' + $json.key_points.map(p => '\u2022 ' + p).join('\\n') + '\\n\\n' : '') +\n($json.suggested_action ? '\ud83d\udca1 *\u0110\u1ec1 xu\u1ea5t:* ' + $json.suggested_action + '\\n\\n' : '') +\n($json.reply_needed ? '\u26a0\ufe0f _Email n\u00e0y c\u1ea7n tr\u1ea3 l\u1eddi_' : '') +\n'\\n\\n_H\u1ecfi v\u1ec1 email n\u00e0y: g\u00f5 c\u00e2u h\u1ecfi b\u1ea5t k\u1ef3_'\n}}",
              "type": "string"
            },
            {
              "id": "wa-msg-2",
              "name": "recipient_phone",
              "value": "0961664349",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "a55305f7-ff75-437e-ac19-5bb178263a6a",
      "name": "T\u1ea1o tin nh\u1eafn Discord",
      "type": "n8n-nodes-base.set",
      "position": [
        2320,
        560
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "intent-chat",
                    "leftValue": "={{ $json.category }}",
                    "rightValue": "C\u00e1 nh\u00e2n",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "C\u00e1 nh\u00e2n"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "intent-draft",
                    "leftValue": "={{ $json.category }}",
                    "rightValue": "C\u00f4ng vi\u1ec7c",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "C\u00f4ng vi\u1ec7c"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "intent-prefs",
                    "leftValue": "={{ $json.category }}",
                    "rightValue": "M\u1ea1ng x\u00e3 h\u1ed9i",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "M\u1ea1ng x\u00e3 h\u1ed9i"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "intent-help",
                    "leftValue": "={{ $json.category }}",
                    "rightValue": "Ho\u00e1 \u0111\u01a1n",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Ho\u00e1 \u0111\u01a1n"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "6cc68708-a1d5-428c-a664-99f719007e6c",
                    "leftValue": "={{ $json.category }}",
                    "rightValue": "Kh\u00e1c",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Kh\u00e1c"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "04e5d9bd-9e0e-4b82-b843-360bf3c0c993",
                    "leftValue": "={{ $json.category }}",
                    "rightValue": "Qu\u1ea3ng c\u00e1o",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Qu\u1ea3ng c\u00e1o"
            }
          ]
        },
        "options": {}
      },
      "id": "4df83541-811e-41a9-a9b3-8880f74f5887",
      "name": "Ph\u00e2n lu\u1ed3ng theo Intent1",
      "type": "n8n-nodes-base.switch",
      "position": [
        2208,
        992
      ],
      "typeVersion": 3.2
    },
    {
      "parameters": {
        "operation": "addLabels",
        "messageId": "={{ $('Gmail Trigger').item.json.id }}",
        "labelIds": [
          "Label_1988667992165077584"
        ]
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2672,
        768
      ],
      "id": "45478ac5-8933-49f6-b29b-62563c16e5d1",
      "name": "C\u00e1 nh\u00e2n",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "addLabels",
        "messageId": "={{ $('Gmail Trigger').item.json.id }}",
        "labelIds": [
          "Label_1679528670208077481"
        ]
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2672,
        944
      ],
      "id": "a2b4209e-6427-46a5-b121-d6c67db38ad5",
      "name": "C\u00f4ng vi\u1ec7c",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "addLabels",
        "messageId": "={{ $('Gmail Trigger').item.json.id }}",
        "labelIds": [
          "Label_5717814711797274905"
        ]
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2672,
        1104
      ],
      "id": "e6030465-25b7-468f-9533-d9d575364847",
      "name": "M\u1ea1ng x\u00e3 h\u1ed9i",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "addLabels",
        "messageId": "={{ $('Gmail Trigger').item.json.id }}",
        "labelIds": [
          "Label_274030861553114605"
        ]
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2672,
        1280
      ],
      "id": "48963943-fb09-4b7c-87db-8e96557cd645",
      "name": "Ho\u00e1 \u0111\u01a1n",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "addLabels",
        "messageId": "={{ $('Gmail Trigger').item.json.id }}",
        "labelIds": [
          "Label_6370485165580022646"
        ]
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2656,
        1632
      ],
      "id": "5db0c544-3fb4-475c-913a-d1be3e7b3940",
      "name": "Qu\u1ea3ng c\u00e1o",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "addLabels",
        "messageId": "={{ $('Gmail Trigger').item.json.id }}",
        "labelIds": [
          "Label_3139644122484525406"
        ]
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2672,
        1440
      ],
      "id": "2a7786ab-5297-4315-b250-60e46d82d7ac",
      "name": "Kh\u00e1c",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "guildId": {
          "__rl": true,
          "value": "1491467637887340664",
          "mode": "list",
          "cachedResultName": "M\u00e1y ch\u1ee7 c\u1ee7a KhoiTeyChin",
          "cachedResultUrl": "https://discord.com/channels/1491467637887340664"
        },
        "channelId": {
          "__rl": true,
          "value": "1491470225655206008",
          "mode": "list",
          "cachedResultName": "email-manager-bot",
          "cachedResultUrl": "https://discord.com/channels/1491467637887340664/1491470225655206008"
        },
        "content": "= {{ $json.wa_message }}",
        "options": {}
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        2592,
        624
      ],
      "id": "13997523-8370-43d4-910c-1ab3cae8be73",
      "name": "Send a message",
      "credentials": {
        "discordBotApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "GPT-4O-MINI"
        },
        "responses": {
          "values": [
            {
              "content": "=B\u1ea1n l\u00e0 tr\u1ee3 l\u00fd AI chuy\u00ean x\u1eed l\u00fd email.\n\nNhi\u1ec7m v\u1ee5:\n1. Ph\u00e2n lo\u1ea1i email v\u00e0o 1 trong c\u00e1c nh\u00f3m:\n- H\u00f3a \u0111\u01a1n\n- Qu\u1ea3ng c\u00e1o\n- M\u1ea1ng x\u00e3 h\u1ed9i\n- C\u00f4ng vi\u1ec7c\n- C\u00e1 nh\u00e2n\n- Kh\u00e1c\n\n2. X\u00e1c \u0111\u1ecbnh m\u1ee9c \u0111\u1ed9 \u01b0u ti\u00ean:\n- high (g\u1ea5p, OTP, deadline g\u1ea7n)\n- medium (c\u00f4ng vi\u1ec7c b\u00ecnh th\u01b0\u1eddng)\n- low (c\u00f2n l\u1ea1i)\n\n3. T\u00f3m t\u1eaft email:\n- Vi\u1ebft 1-2 c\u00e2u ti\u1ebfng Vi\u1ec7t\n- Kh\u00f4ng \u0111\u01b0\u1ee3c b\u1ecba th\u00eam th\u00f4ng tin\n- N\u1ebfu n\u1ed9i dung qu\u00e1 ng\u1eafn \u2192 vi\u1ebft l\u1ea1i th\u00e0nh c\u00e2u \u0111\u1ea7y \u0111\u1ee7, r\u00f5 ngh\u0129a\n\n4. Tr\u00edch xu\u1ea5t:\n- key_points: c\u00e1c \u00fd ch\u00ednh (2\u20134 \u00fd)\n- suggested_action: n\u00ean l\u00e0m g\u00ec ti\u1ebfp theo\n- reply_needed: email n\u00e0y c\u00f3 c\u1ea7n tr\u1ea3 l\u1eddi kh\u00f4ng (true/false)\n- sentiment: positive | neutral | negative\n\n---\n\nEMAIL:\nTi\u00eau \u0111\u1ec1: {{$json.subject}}\nN\u1ed9i dung:\n{{$json.text}}\n\n---\n\nQUY T\u1eaeC QUAN TR\u1eccNG:\n- Ch\u1ec9 s\u1eed d\u1ee5ng th\u00f4ng tin c\u00f3 trong email\n- Kh\u00f4ng suy \u0111o\u00e1n ngo\u00e0i d\u1eef li\u1ec7u\n- N\u1ebfu kh\u00f4ng \u0111\u1ee7 th\u00f4ng tin \u2192 ghi \"Kh\u00f4ng r\u00f5\"\n- Output PH\u1ea2I l\u00e0 JSON h\u1ee3p l\u1ec7 (kh\u00f4ng text th\u1eeba)\n\n---\n\nTr\u1ea3 v\u1ec1 \u0111\u00fang format JSON:\n\n{\n  \"category\": \"...\",\n  \"priority\": \"...\",\n  \"summary\": \"...\",\n  \"key_points\": [\"...\", \"...\"],\n  \"suggested_action\": \"...\",\n  \"reply_needed\": true,\n  \"sentiment\": \"...\"\n}"
            }
          ]
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2.1,
      "position": [
        1296,
        256
      ],
      "id": "247952b8-b963-4307-a665-7aa02b696c89",
      "name": "Message a model",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "## \ud83d\udcac FLOW B: Discords AI Agent\nRAG Chatbot + Draft Email + Qu\u1ea3n l\u00fd t\u00f9y ch\u1ec9nh",
        "height": 1572,
        "width": 2836,
        "color": 5
      },
      "id": "bac625e0-de5d-41b8-a064-9dcc1f03bf4c",
      "name": "Flow B Header",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        752,
        2032
      ],
      "typeVersion": 1,
      "disabled": true
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.message }}",
        "options": {
          "systemMessage": "B\u1ea1n l\u00e0 m\u1ed9t AI Email Assistant th\u00f4ng minh, t\u00edch h\u1ee3p v\u1edbi Discord.\n\n=====================\nTH\u00d4NG TIN NG\u01af\u1edcI D\u00d9NG\n=====================\n- V\u0103n phong: chuy\u00ean nghi\u1ec7p, r\u00f5 r\u00e0ng\n- Ng\u00f4n ng\u1eef: vi\n- M\u1ee9c \u0111\u1ed9 t\u00f3m t\u1eaft: ng\u1eafn g\u1ecdn\n\n=====================\nNHI\u1ec6M V\u1ee4\n=====================\n1. Tr\u1ea3 l\u1eddi c\u00e2u h\u1ecfi v\u1ec1 email d\u1ef1a tr\u00ean d\u1eef li\u1ec7u t\u1eeb vector database\n2. T\u00ecm ki\u1ebfm email li\u00ean quan khi ng\u01b0\u1eddi d\u00f9ng y\u00eau c\u1ea7u\n3. T\u00f3m t\u1eaft email theo m\u1ee9c \u0111\u1ed9 y\u00eau c\u1ea7u\n4. Ph\u00e2n t\u00edch n\u1ed9i dung email (\u00fd ch\u00ednh, ng\u01b0\u1eddi g\u1eedi, h\u00e0nh \u0111\u1ed9ng c\u1ea7n thi\u1ebft)\n5. G\u1ee3i \u00fd h\u00e0nh \u0111\u1ed9ng ti\u1ebfp theo\n\n=====================\nQUY T\u1eaeC QUAN TR\u1eccNG\n=====================\n- KH\u00d4NG \u0111\u01b0\u1ee3c b\u1ecba th\u00f4ng tin n\u1ebfu kh\u00f4ng c\u00f3 trong database\n- N\u1ebfu kh\u00f4ng t\u00ecm th\u1ea5y d\u1eef li\u1ec7u, tr\u1ea3 l\u1eddi: 'Kh\u00f4ng t\u00ecm th\u1ea5y th\u00f4ng tin ph\u00f9 h\u1ee3p trong h\u1ec7 th\u1ed1ng.'\n- Lu\u00f4n tr\u1ea3 l\u1eddi b\u1eb1ng ti\u1ebfng Vi\u1ec7t\n- T\u1ed1i \u01b0u format cho WhatsApp:\n  - D\u00f9ng *bold* cho ti\u00eau \u0111\u1ec1\n  - D\u00f9ng _italic_ cho ghi ch\u00fa\n  - D\u00f9ng emoji h\u1ee3p l\u00fd (\ud83d\udce7, \ud83d\udccc, \u26a0\ufe0f, \u2705)\n- C\u00e2u tr\u1ea3 l\u1eddi ph\u1ea3i ng\u1eafn g\u1ecdn, d\u1ec5 \u0111\u1ecdc, c\u00f3 c\u1ea5u tr\u00fac r\u00f5 r\u00e0ng\n\n=====================\nX\u1eec L\u00dd L\u1ec6NH \u0110\u1eb6C BI\u1ec6T\n=====================\n- N\u1ebfu tin nh\u1eafn b\u1eaft \u0111\u1ea7u b\u1eb1ng '/draft': T\u1ea1o email draft chuy\u00ean nghi\u1ec7p\n- N\u1ebfu tin nh\u1eafn b\u1eaft \u0111\u1ea7u b\u1eb1ng '/prefs': H\u01b0\u1edbng d\u1eabn ng\u01b0\u1eddi d\u00f9ng c\u1eadp nh\u1eadt c\u00e0i \u0111\u1eb7t\n- N\u1ebfu tin nh\u1eafn b\u1eaft \u0111\u1ea7u b\u1eb1ng '/help': Tr\u1ea3 v\u1ec1 h\u01b0\u1edbng d\u1eabn s\u1eed d\u1ee5ng\n\n=====================\nOUTPUT FORMAT\n=====================\nLu\u00f4n tr\u1ea3 v\u1ec1 text (KH\u00d4NG JSON). Kh\u00f4ng th\u00eam gi\u1ea3i th\u00edch ngo\u00e0i n\u1ed9i dung tr\u1ea3 l\u1eddi."
        }
      },
      "id": "1a3ab4a0-f484-419f-b93b-8e56ad313b64",
      "name": "RAG AI Agent1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2176,
        2960
      ],
      "typeVersion": 1.7
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolName": "tim_kiem_email",
        "toolDescription": "T\u00ecm ki\u1ebfm email trong database. D\u00f9ng khi c\u1ea7n t\u00ecm email li\u00ean quan \u0111\u1ebfn ch\u1ee7 \u0111\u1ec1, ng\u01b0\u1eddi g\u1eedi, th\u1eddi gian ho\u1eb7c b\u1ea5t k\u1ef3 n\u1ed9i dung n\u00e0o. H\u00e3y bao g\u1ed3m th\u00f4ng tin th\u1eddi gian trong query n\u1ebfu ng\u01b0\u1eddi d\u00f9ng h\u1ecfi v\u1ec1 kho\u1ea3ng th\u1eddi gian c\u1ee5 th\u1ec3.",
        "tableName": "emails_vector_store",
        "topK": 5,
        "options": {}
      },
      "id": "ba1b945a-2d60-489e-8e4e-e981070340c8",
      "name": "RAG PGVector Tool1",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
      "position": [
        2256,
        3232
      ],
      "typeVersion": 1.1,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "42157f15-896e-475a-b336-9cf9283ca8cc",
      "name": "RAG Embeddings1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        2336,
        3392
      ],
      "typeVersion": 1.2,
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "name": "sessionId",
              "value": "={{ $json.session_id }}",
              "type": "string",
              "id": "655b8b9e-d466-4053-9347-34a6c97b060b"
            },
            {
              "name": "message",
              "value": "={{ $json.message }}",
              "type": "string",
              "id": "1b445b67-5793-4329-8785-8221763dd312"
            },
            {
              "name": "channelId",
              "value": "={{ $('Webhook').item.json.body.channelId }}",
              "type": "string",
              "id": "b19c28a9-c494-42b4-b19d-c36ae36bb248"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1264,
        2464
      ],
      "id": "e0aca48e-9f93-4f80-b9ba-1eb7682cf58e",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "gpt-4o-mini"
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.3,
      "position": [
        2016,
        3200
      ],
      "id": "4f86508a-da46-49d5-8982-adb7b760b784",
      "name": "OpenAI Chat Model",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "discord-agent",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        864,
        2464
      ],
      "id": "1c051acf-6c81-4792-bacc-7de334545825",
      "name": "Webhook"
    },
    {
      "parameters": {
        "resource": "message",
        "guildId": {
          "__rl": true,
          "value": "1491467637887340664",
          "mode": "list",
          "cachedResultName": "M\u00e1y ch\u1ee7 c\u1ee7a KhoiTeyChin",
          "cachedResultUrl": "https://discord.com/channels/1491467637887340664"
        },
        "channelId": {
          "__rl": true,
          "value": "1491470225655206008",
          "mode": "list",
          "cachedResultName": "email-manager-bot",
          "cachedResultUrl": "https://discord.com/channels/1491467637887340664/1491470225655206008"
        },
        "content": "={{ $json.output }}",
        "options": {}
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        2848,
        3088
      ],
      "id": "948c3cbc-3f07-4e38-9439-1c6d2d1dd133",
      "name": "Send a message1",
      "credentials": {
        "discordBotApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const body = $input.item.json.body;\n\nconst userId = body.userId || '';\nconst username = body.username || 'unknown';\nconst messageText = (body.content || '').trim();\nconst channelId = body.channelId || '';\n\nif (!messageText) return [];\n\nconst lowerText = messageText.toLowerCase();\n\n// default\nlet intent = 'chat';\nlet commandArgs = messageText;\n\n// ========================\n// DRAFT\n// ========================\nif (/^(\\/draft\\b|t\u1ea1o draft|so\u1ea1n draft|draft email)/i.test(lowerText)) {\n  intent = 'draft';\n  commandArgs = messageText.replace(/^(\\/draft\\s*|t\u1ea1o draft\\s*|so\u1ea1n draft\\s*|draft email\\s*)/i, '').trim();\n}\n\n// ========================\n// SEND\n// ========================\nelse if (/^(\\/send\\b|g\u1eedi email|send email)/i.test(lowerText)) {\n  intent = 'send';\n  commandArgs = messageText.replace(/^(\\/send\\s*|g\u1eedi email\\s*|send email\\s*)/i, '').trim();\n}\n\n\n// ========================\n// EMAIL / RAG QUERY\n// ========================\nelse if (/(email|h\u1ed9p th\u01b0|tin nh\u1eafn|\u0111\u1ecdc|t\u00f3m t\u1eaft|ki\u1ec3m tra|t\u00ecm)/i.test(lowerText)) {\n  intent = 'chat';\n}\n\n// ========================\n// DEFAULT\n// ========================\nelse {\n  intent = 'chat';\n}\n\nreturn [{\n  json: {\n    userId,\n    username,\n    message: messageText,\n    intent,\n    commandArgs,\n    messageType: 'text',\n    timestamp: Date.now(),\n    channelId\n  }\n}];"
      },
      "id": "5f966261-6909-4298-a3ae-b36ea33e5fa8",
      "name": "Parse Discord Message",
      "type": "n8n-nodes-base.code",
      "position": [
        1056,
        2464
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "jsCode": "// L\u1ea5y l\u1ecbch s\u1eed chat t\u1eeb bi\u1ebfn to\u00e0n c\u1ee5c\nconst sessionId = $json.sessionId;\nconst globalKey = `chat_history_${sessionId}`;\n\n// L\u1ea5y history t\u1eeb global (n\u1ebfu c\u00f3)\nlet history = $getWorkflowStaticData('global')[globalKey] || [];\n\n// Th\u00eam tin nh\u1eafn hi\u1ec7n t\u1ea1i\nhistory.push({\n  role: 'user',\n  content: $json.message\n});\n\n// Ch\u1ec9 gi\u1eef 10 tin nh\u1eafn g\u1ea7n nh\u1ea5t\nif (history.length > 10) {\n  history = history.slice(-10);\n}\n\n// L\u01b0u l\u1ea1i\n$getWorkflowStaticData('global')[globalKey] = history;\n\n// T\u1ea1o context cho AI\nconst context = history.map(msg => \n  `${msg.role === 'user' ? 'Ng\u01b0\u1eddi d\u00f9ng' : 'Tr\u1ee3 l\u00fd'}: ${msg.content}`\n).join('\\n');\n\nreturn [{\n  json: {\n    ...$json,\n    chat_context: context,\n    message: $json.message\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1456,
        2464
      ],
      "id": "dc02ee70-7ae4-4a8e-ade2-93c1d1556ca4",
      "name": "Code in JavaScript"
    },
    {
      "parameters": {},
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "typeVersion": 1.3,
      "position": [
        2144,
        3216
      ],
      "id": "f4e4e914-f91b-44e0-817c-987b42ca4f99",
      "name": "Postgres Chat Memory",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "guildId": {
          "__rl": true,
          "value": "1491467637887340664",
          "mode": "list",
          "cachedResultName": "M\u00e1y ch\u1ee7 c\u1ee7a KhoiTeyChin"
        },
        "channelId": {
          "__rl": true,
          "value": "1491470225655206008",
          "mode": "list",
          "cachedResultName": "email-manager-bot"
        },
        "content": "=\u2705 *Email \u0111\u00e3 \u0111\u01b0\u1ee3c g\u1eedi th\u00e0nh c\u00f4ng!*\n\n\ud83d\udccc *Ti\u00eau \u0111\u1ec1:* {{ $('Code in JavaScript2').item.json.subject }}\n\ud83d\udce7 *G\u1eedi \u0111\u1ebfn:* {{ $('Code in JavaScript2').item.json.to }}\n\n_Ki\u1ec3m tra Gmail Sent \u0111\u1ec3 x\u00e1c nh\u1eadn._",
        "options": {}
      },
      "id": "9647913f-2fe4-493c-a18b-4656ab1590bf",
      "name": "Th\u00f4ng b\u00e1o Email Sent",
      "type": "n8n-nodes-base.discord",
      "position": [
        3088,
        2528
      ],
      "typeVersion": 2,
      "credentials": {
        "discordBotApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "guildId": {
          "__rl": true,
          "value": "1491467637887340664",
          "mode": "list",
          "cachedResultName": "M\u00e1y ch\u1ee7 c\u1ee7a KhoiTeyChin"
        },
        "channelId": {
          "__rl": true,
          "value": "1491470225655206008",
          "mode": "list",
          "cachedResultName": "email-manager-bot"
        },
        "content": "=\u2705 *Draft \u0111\u00e3 \u0111\u01b0\u1ee3c t\u1ea1o trong Gmail!*\n\n\ud83d\udccc *Ti\u00eau \u0111\u1ec1:* {{ $('Code in JavaScript1').item.json.subject }}\n\ud83d\udce7 *G\u1eedi \u0111\u1ebfn:* {{ $('Code in JavaScript1').item.json.to }}\n\n_V\u00e0o Gmail Drafts \u0111\u1ec3 xem v\u00e0 ch\u1ec9nh s\u1eeda tr\u01b0\u1edbc khi g\u1eedi._",
        "options": {}
      },
      "id": "1aa3807b-0d9a-42b3-b587-8ef274caa166",
      "name": "Th\u00f4ng b\u00e1o Draft Created",
      "type": "n8n-nodes-base.discord",
      "position": [
        2848,
        2048
      ],
      "typeVersion": 2,
      "credentials": {
        "discordBotApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "sendTo": "={{ $json.to }}",
        "subject": "={{ $json.subject }}",
        "message": "={{ $json.body }}",
        "options": {}
      },
      "id": "5b506ff5-cc47-4287-9cc3-fe9437fca2f0",
      "name": "G\u1eedi Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2832,
        2528
      ],
      "typeVersion": 2.1,
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "intent-chat",
                    "leftValue": "={{ $('Parse Discord Message').item.json.intent }}",
                    "rightValue": "draft",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Draft"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "intent-draft",
                    "leftValue": "={{ $('Parse Discord Message').item.json.intent }}",
                    "rightValue": "send",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Send"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "intent-prefs",
                    "leftValue": "={{ $('Parse Discord Message').item.json.intent }}",
                    "rightValue": "chat",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Chat"
            }
          ]
        },
        "options": {}
      },
      "id": "5d1474ae-1aea-4306-beae-c629863819d8",
      "name": "Ph\u00e2n lu\u1ed3ng theo Intent",
      "type": "n8n-nodes-base.switch",
      "position": [
        1648,
        2448
      ],
      "typeVersion": 3.2
    },
    {
      "parameters": {
        "resource": "draft",
        "subject": "={{ $json.subject }}",
        "message": "={{ $json.body }}",
        "options": {}
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2656,
        2064
      ],
      "id": "310254a6-a6d1-427c-9f68-9e11979674f5",
      "name": "T\u1ea1o draft",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const raw = $input.item.json.output;\n\nlet data;\n\ntry {\n  data = JSON.parse(raw);\n} catch {\n  data = {\n    to: '',\n    subject: 'Re:',\n    body: raw\n  };\n}\n\nreturn [{\n  json: {\n    ...data,\n    threadId: $json.threadId\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2464,
        2064
      ],
      "id": "4bc6b775-5214-4ec9-96ab-8e6af06e4f5d",
      "name": "Code in JavaScript1"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.message }}",
        "options": {
          "systemMessage": "B\u1ea1n l\u00e0 AI Email Assistant chuy\u00ean nghi\u1ec7p.\n\nY\u00eau c\u1ea7u:\n{{ $json.commandArgs }}\n\nQuy t\u1eafc:\n- CH\u1ec8 tr\u1ea3 v\u1ec1 JSON h\u1ee3p l\u1ec7\n- KH\u00d4NG markdown, KH\u00d4NG emoji\n- KH\u00d4NG th\u00eam text ngo\u00e0i JSON\n- Email ph\u1ea3i chuy\u00ean nghi\u1ec7p\n\nFormat:\n{\n  \"to\": \"\",\n  \"subject\": \"\",\n  \"body\": \"\"\n}"
        }
      },
      "id": "a54b3957-f6b4-4e27-9c14-c300db732ab8",
      "name": "RAG AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2080,
        2064
      ],
      "typeVersion": 1.7
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolName": "tim_kiem_email",
        "toolDescription": "T\u00ecm ki\u1ebfm email trong database. D\u00f9ng khi c\u1ea7n t\u00ecm email li\u00ean quan \u0111\u1ebfn ch\u1ee7 \u0111\u1ec1, ng\u01b0\u1eddi g\u1eedi, th\u1eddi gian ho\u1eb7c b\u1ea5t k\u1ef3 n\u1ed9i dung n\u00e0o. H\u00e3y bao g\u1ed3m th\u00f4ng tin th\u1eddi gian trong query n\u1ebfu ng\u01b0\u1eddi d\u00f9ng h\u1ecfi v\u1ec1 kho\u1ea3ng th\u1eddi gian c\u1ee5 th\u1ec3.",
        "tableName": "emails_vector_store",
        "topK": 5,
        "options": {}
      },
      "id": "a71bab0f-48e7-4845-9187-d4812a699077",
      "name": "RAG PGVector Tool",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
      "position": [
        2272,
        2240
      ],
      "typeVersion": 1.1,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "2c6a723d-3f40-45eb-a8eb-10c7ea916e60",
      "name": "RAG Embeddings",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        2432,
        2368
      ],
      "typeVersion": 1.2,
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "gpt-4o-mini"
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.3,
      "position": [
        2000,
        2272
      ],
      "id": "a2113701-e1dd-41b0-90f4-4bac63682d80",
      "name": "OpenAI Chat Model1",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {},
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "typeVersion": 1.3,
      "position": [
        2144,
        2224
      ],
      "id": "f95f27cc-713b-453f-9cc7-31638501b7c2",
      "name": "Postgres Chat Memory1",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.message }}",
        "options": {
          "systemMessage": "B\u1ea1n l\u00e0 AI Email Assistant chuy\u00ean nghi\u1ec7p.\n\nY\u00eau c\u1ea7u:\n{{ $json.commandArgs }}\n\nQuy t\u1eafc:\n- CH\u1ec8 tr\u1ea3 v\u1ec1 JSON h\u1ee3p l\u1ec7\n- KH\u00d4NG markdown, KH\u00d4NG emoji\n- KH\u00d4NG th\u00eam text ngo\u00e0i JSON\n- Email ph\u1ea3i chuy\u00ean nghi\u1ec7p\n\nFormat:\n{\n  \"to\": \"\",\n  \"subject\": \"\",\n  \"body\": \"\"\n}"
        }
      },
      "id": "e0796682-d189-4890-85a5-249de74d1aeb",
      "name": "RAG AI Agent2",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2064,
        2464
      ],
      "typeVersion": 1.7
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolName": "tim_kiem_email",
        "toolDescription": "T\u00ecm ki\u1ebfm email trong database. D\u00f9ng khi c\u1ea7n t\u00ecm email li\u00ean quan \u0111\u1ebfn ch\u1ee7 \u0111\u1ec1, ng\u01b0\u1eddi g\u1eedi, th\u1eddi gian ho\u1eb7c b\u1ea5t k\u1ef3 n\u1ed9i dung n\u00e0o. H\u00e3y bao g\u1ed3m th\u00f4ng tin th\u1eddi gian trong query n\u1ebfu ng\u01b0\u1eddi d\u00f9ng h\u1ecfi v\u1ec1 kho\u1ea3ng th\u1eddi gian c\u1ee5 th\u1ec3.",
        "tableName": "emails_vector_store",
        "topK": 5,
        "options": {}
      },
      "id": "92db9ab1-5724-4203-ab9f-1567c23c40a5",
      "name": "RAG PGVector Tool2",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
      "position": [
        2352,
        2688
      ],
      "typeVersion": 1.1,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "02a286b4-2255-4ac8-a9d7-694cd8ed8cb1",
      "name": "RAG Embeddings2",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        2528,
        2864
      ],
      "typeVersion": 1.2,
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "gpt-4o-mini"
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.3,
      "position": [
        2064,
        2672
      ],
      "id": "5e23551e-d531-4332-af0e-174ffe04e37e",
      "name": "OpenAI Chat Model2",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {},
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "typeVersion": 1.3,
      "position": [
        2224,
        2688
      ],
      "id": "1306ddb2-9893-4397-9129-23690f1f8daa",
      "name": "Postgres Chat Memory2",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const raw = $input.item.json.output;\n\nlet data;\n\ntry {\n  data = JSON.parse(raw);\n} catch {\n  data = {\n    to: '',\n    subject: 'Re:',\n    body: raw\n  };\n}\n\nreturn [{\n  json: {\n    ...data,\n    threadId: $json.threadId\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2576,
        2512
      ],
      "id": "163688c5-182b-47cf-82ff-d28a97efc801",
      "name": "Code in JavaScript2"
    }
  ],
  "connections": {
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "Get Mail Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI": {
      "main": [
        [
          {
            "node": "L\u01b0u v\u00e0o PGVector Store",
            "type": "main",
            "index": 0
          },
          {
            "node": "T\u1ea1o tin nh\u1eafn Discord",
            "type": "main",
            "index": 0
          },
          {
            "node": "Ph\u00e2n lu\u1ed3ng theo Intent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings for Insert": {
      "ai_embedding": [
        [
          {
            "node": "L\u01b0u v\u00e0o PGVector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Email Data Loader": {
      "ai_document": [
        [
          {
            "node": "L\u01b0u v\u00e0o PGVector Store",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Email Text Splitter": {
      "ai_textSplitter": [
        [
          {
            "node": "Email Data Loader",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Get Mail Data": {
      "main": [
        [
          {
            "node": "Message a model",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ph\u00e2n lu\u1ed3ng theo Intent1": {
      "main": [
        [
          {
            "node": "C\u00e1 nh\u00e2n",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "C\u00f4ng vi\u1ec7c",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "M\u1ea1ng x\u00e3 h\u1ed9i",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Ho\u00e1 \u0111\u01a1n",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Kh\u00e1c",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Qu\u1ea3ng c\u00e1o",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message a model": {
      "main": [
        [
          {
            "node": "X\u1eed l\u00fd k\u1ebft qu\u1ea3 AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "T\u1ea1o tin nh\u1eafn Discord": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RAG AI Agent1": {
      "main": [
        [
          {
            "node": "Send a message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RAG PGVector Tool1": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "RAG Embeddings1": {
      "ai_embedding": [
        [
          {
            "node": "RAG PGVector Tool1",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Parse Discord Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Discord Message": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Ph\u00e2n lu\u1ed3ng theo Intent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Postgres Chat Memory": {
      "ai_memory": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "G\u1eedi Gmail": {
      "main": [
        [
          {
            "node": "Th\u00f4ng b\u00e1o Email Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ph\u00e2n lu\u1ed3ng theo Intent": {
      "main": [
        [
          {
            "node": "RAG AI Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "RAG AI Agent2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "RAG AI Agent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "T\u1ea1o draft": {
      "main": [
        [
          {
            "node": "Th\u00f4ng b\u00e1o Draft Created",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript1": {
      "main": [
        [
          {
            "node": "T\u1ea1o draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RAG PGVector Tool": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "RAG Embeddings": {
      "ai_embedding": [
        [
          {
            "node": "RAG PGVector Tool",
            "type": "ai_embedding",
            "index": 0
          }
        ]

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

AI Email Agent - Complete System. Uses gmailTrigger, gmail, vectorStorePGVector, embeddingsOpenAi. Event-driven trigger; 47 nodes.

Source: https://github.com/khoiteychin/ai-email-manager-agent/blob/e627eeebe5136a34bab143e45708869f523b5a28/n8n-workflow — 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

Your AI workforce is ready. Are you?

Google Sheets Tool, Mcp Trigger, Google Drive +29
AI & RAG

This intelligent chatbot leverages cutting-edge financial APIs and AI-driven analysis to deliver comprehensive stock research reports. Get instant access to professional-grade investment analysis that

Tool Think, Supabase Vector Store, OpenAI Embeddings +15
AI & RAG

This advanced n8n workflow automates the full lead enrichment, qualification, and personalized outreach process tailored specifically for the B2B real estate sector. Integrating top platforms like Api

N8N Nodes Fillout, OpenAI Chat, Pinecone Vector Store +11
AI & RAG

This n8n template automatically classifies incoming emails (Sales, Support, Internal, Finance, Promotions) and routes them to a dedicated OpenAI LLM Agent for processing. Depending on the category, th

OpenAI, Gmail, Text Classifier +16
AI & RAG

Automate Outreach Prospect automates finding, enriching, and messaging potential partners (like restaurants, malls, and bars) using Apify Google Maps scraping, Perplexity enrichment, OpenAI LLMs, Goog

@Devlikeapro/N8N Nodes Waha, Google Drive Trigger, @Apify/N8N Nodes Apify +14