邮件支持路由模板V3

中级

这是一个自动化工作流,包含 14 个节点。主要使用 Code、Dart、GmailTrigger、Agent、LmChatOpenAi 等节点。 使用AI分类支持邮件并在Dart中创建任务

前置要求
  • Google 账号和 Gmail API 凭证
  • OpenAI API Key

分类

未分类
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "gPmiDOmZMrVDuuV7",
  "meta": {
    "instanceId": "95aec2483358dfb72046fc8ddb61b3dd82dea7a959f9c8b9db2d9f673d857a0f",
    "templateCredsSetupCompleted": true
  },
  "name": "Email support routing template V3",
  "tags": [],
  "nodes": [
    {
      "id": "1c626123-f1d6-45fd-8519-ac5342b4b38c",
      "name": "检索现有dartboard",
      "type": "n8n-nodes-dart.dart",
      "position": [
        880,
        -96
      ],
      "parameters": {
        "id": "K7jRC0JC2Wxz",
        "resource": "Dartboard",
        "operation": "Get Dartboard",
        "requestOptions": {}
      },
      "credentials": {
        "dartApi": {
          "id": "bzHVCZ0maSiWGdRo",
          "name": "Dart account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "99aea42e-4e2f-476c-96b0-de382b83922e",
      "name": "创建新任务",
      "type": "n8n-nodes-dart.dart",
      "position": [
        1312,
        32
      ],
      "parameters": {
        "item": "={\n  \"title\": \"{{ $('Launch workflow on email receive').item.json.subject }}\",\n  \"priority\": \"{{ $('Parsing stage for logic result').item.json.priority }}\",\n  \"tags\": [\"{{ $('Parsing stage for logic result').item.json.category }}\"],\n\n  \"description\": \"Rationale: {{ $('Parsing stage for logic result').item.json.rationale }}\\n\\n Confidence lvl: {{ $('Parsing stage for logic result').item.json.confidence }}\\n\\n Summary: {{ $('Parsing stage for logic result').item.json.summary }}\\n \\n Full email: \\n \\n  {{ $('Cleaning up full text of email').item.json.cleanText }}\"\n}\n",
        "resource": "Task",
        "operation": "Create Task",
        "requestOptions": {}
      },
      "credentials": {
        "dartApi": {
          "id": "bzHVCZ0maSiWGdRo",
          "name": "Dart account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6496bb73-0007-4b60-84cc-7e1268e85146",
      "name": "Create a new comment",
      "type": "n8n-nodes-dart.dart",
      "position": [
        1536,
        32
      ],
      "parameters": {
        "item": "={ \"taskId\": \"{{ $json.item.id }}\",\n  \"text\":\"Sender: {{ $('Launch workflow on email receive').item.json.from.value[0].name }} - {{ $('Launch workflow on email receive').item.json.from.value[0].address }}\"\n}",
        "resource": "Comment",
        "operation": "Add Task Comment",
        "requestOptions": {}
      },
      "credentials": {
        "dartApi": {
          "id": "bzHVCZ0maSiWGdRo",
          "name": "Dart account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "36935d91-24c5-4338-b766-5f58d092053e",
      "name": "Cleaning up full text of email",
      "type": "n8n-nodes-base.code",
      "position": [
        464,
        -80
      ],
      "parameters": {
        "jsCode": "// Safely get the Gmail HTML body\nconst html = $('Launch workflow on email receive').first().json.textAsHtml || \"\";\n\n// --- CLEAN TEXT FROM HTML ---\n\n// Step 1: Normalize line breaks for <p>, <br>, and <div> tags\nlet clean = html\n  .replace(/<(?:br|div)\\s*\\/?>/gi, '\\n')\n  .replace(/<\\/p>/gi, '\\n');\n\n// Step 2: Remove anchor tags but keep inner text\nclean = clean.replace(/<a[^>]*>(.*?)<\\/a>/gi, '$1');\n\n// Step 3: Remove scripts, styles, and comments\nclean = clean\n  .replace(/<script[\\s\\S]*?<\\/script>/gi, '')\n  .replace(/<style[\\s\\S]*?<\\/style>/gi, '')\n  .replace(/<!--[\\s\\S]*?-->/g, '');\n\n// Step 4: Remove <img> tags and Gmail-style [image: ...] placeholders\nclean = clean\n  .replace(/<img[^>]*>/gi, '')\n  .replace(/\\[image:\\s*.*?\\]/gi, '');\n\n// Step 5: Strip remaining HTML tags\nclean = clean.replace(/<[^>]+>/g, ' ');\n\n// Step 6: Remove plain text URLs\nclean = clean.replace(/\\b(?:https?:\\/\\/|ftp:\\/\\/|www\\.|mailto:)\\S+\\b/gi, '');\n\n// Step 7: Decode basic HTML entities\nclean = clean\n  .replace(/&nbsp;/gi, ' ')\n  .replace(/&amp;/gi, '&')\n  .replace(/&lt;/gi, '<')\n  .replace(/&gt;/gi, '>')\n  .replace(/&quot;/gi, '\"')\n  .replace(/&#39;/gi, \"'\");\n\n// Step 8: Clean up whitespace\nclean = clean\n  .replace(/\\r/g, '')\n  .replace(/[ \\t]+\\n/g, '\\n')\n  .replace(/\\n{3,}/g, '\\n\\n')\n  .replace(/\\s+/g, ' ')\n  .trim();\n\n// Step 9: Remove potentially problematic symbols and quotes\nclean = clean\n  .replace(/['\"`]/g, '')          // remove single, double, and back quotes\n  .replace(/[<>\\\\]/g, '')         // remove angle brackets and backslashes\n  .replace(/[{}[\\]]/g, '')        // remove braces and brackets\n  .replace(/[^\\x20-\\x7E\\n]/g, ''); // remove non-printable characters (safe ASCII only)\n\n// --- RETURN CLEAN TEXT AS OUTPUT ---\n\nreturn [\n  {\n    json: {\n      cleanText: clean,\n    },\n  },\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "9e25bad8-5f56-49b8-aa69-42fa0faaf489",
      "name": "Email triage assistant logic",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -352,
        96
      ],
      "parameters": {
        "text": "=[System instruction]\nYou are a concise email triage assistant whose sole job is to read a user email and pick the best single category from {Billing, Feature Request, Support Help Request, App Feedback, Bug Report, Task Updates, Unrelated}. Use the definitions and output schema provided below. Output only valid JSON that matches the schema exactly.\n\nDefinitions\n- Billing: Questions or disputes about charges, invoices, subscriptions, refunds, payment failures, billing address, tax, pricing plan changes, or account credits.\n- Feature Request: Suggestions for new features, changes to product behavior, wishlist items, or requests to add/change functionality.\n- Support Help Request: User reports of problems, errors, account access issues, setup/installation help, crashes, or anything asking for a fix or step-by-step assistance.\n- App Feedback: General feedback about experience, UI/UX suggestions not asking for a new feature, praise, complaints about design/tone/performance that do not request a fix or new functionality.\n- Bug Report: Reports describing reproducible software defects, unexpected behavior, incorrect outputs, or developer-facing error traces that require debugging and may need code fixes.\n- Task Updates: Notifications or status updates related to tasks, assignments, or workflow progress—especially from Dart or similar systems.\n- Unrelated: Emails that do not fit any of the above categories, such as promotions, marketing material, job applications, newsletters, or personal messages.\n\nRequired JSON output schema (must be followed exactly)\n{\n  \"category\": \"<one of: Billing|Feature Request|Support Help Request|App Feedback|Bug Report|Task Updates|Unrelated>\",\n  \"confidence\": <number between 0.0 and 1.0, strictly in numbers>,\n  \"rationale\": \"<one-sentence explanation of why this category was chosen>\",\n  \"summary\": \"<one-line summary of the user's request>\",\n  \"priority\": \"<low|medium|high|critical>\"\n}\n\n\n\nExample 1\nEmail: \"I was charged twice this month for my subscription. Please refund the duplicate charge and confirm when it’s processed.\"\nCategory: Billing\nConfidence: 0.96\nRationale: \"Mentions duplicate charge and explicitly requests a refund.\"\nSummary: \"User reports duplicate charge and requests refund confirmation.\"\nPriority: high\n\nExample 2\nEmail: \"It would be great if we could export project timelines as CSV and include custom fields.\"\nCategory: Feature Request\nConfidence: 0.92\nRationale: \"User asks for new export feature and specific fields to include.\"\nSummary: \"Request to add CSV export for timelines with custom fields.\"\nPriority: low\n\nExample 3\nEmail: \"App crashes every time I click Save on long tasks; I need help getting my data back.\"\nCategory: Support Help Request\nConfidence: 0.98\nRationale: \"Reports a reproducible crash and asks for help retrieving data.\"\nSummary: \"App crashes on Save for long tasks; user needs data recovery help.\"\nPriority: high\n\nExample 4\nEmail: \"Love the new color theme but the contrast on small text feels low; overall experience is much improved.\"\nCategory: App Feedback\nConfidence: 0.85\nRationale: \"Gives UI feedback and praise without requesting changes or fixes.\"\nSummary: \"Positive feedback on theme with a note about low contrast on small text.\"\nPriority: low\n\nExample 5\nEmail: \"When running the Code node, I get a stack trace: Error: Code doesn't return items properly at validateRunCodeAllItems ... Please advise.\"\nCategory: Bug Report\nConfidence: 0.95\nRationale: \"Provides a developer-facing stack trace and describes a reproducible failure in node execution.\"\nSummary: \"Code node throws validateRunCodeAllItems error with full stack trace.\"\nPriority: high\n\nExample 6\nEmail: \"Task #3421 has been marked complete. Please review the final notes and close the loop.\"\nCategory: Task Updates\nConfidence: 0.93\nRationale: \"Mentions a specific task ID and status update, typical of automated workflow notifications.\"\nSummary: \"Task #3421 marked complete; user asked to review and finalize.\"\nPriority: medium\n\nExample 7\nEmail: \"We’re hiring! Check out our open roles and apply today to join our team.\"\nCategory: Unrelated\nConfidence: 0.90\nRationale: \"Promotional job application email not related to product, support, or user feedback.\"\nSummary: \"Marketing email promoting open job roles.\"\nPriority: low\n\nInstructions\n- Read the email and map it to exactly one category.\n\n- If the email contains both billing and a technical problem, prioritize Billing if a payment dispute or refund is explicitly requested; otherwise prioritize Support Help Request.\n\n- Confidence Calibration\n0.95–1.00: Explicit intent (e.g., “refund,” “add feature,” “crash”).\n0.85–0.94: Strongly implied intent with supporting context.\n0.75–0.84: Somewhat implied or ambiguous.\n<0.75: Weak or uncertain match.\n\n- Priority Rules\ncritical – Use only when the issue completely prevents the user (or all users) from accessing core features, causes total data loss, or exposes a severe security or privacy risk. Typically urgent and business-blocking.\nExamples – “The app won’t load at all for any of our users.” / “All my project data disappeared after the update.” / “Sensitive user info is visible to others.”\n\nhigh – The issue directly affects core functionality, payments, or productivity but does not fully block all access. Includes reproducible crashes, failed payments, or broken workflows with financial or time impact.\nExamples – “I was charged twice this month for my subscription.” / “The app crashes whenever I click Save.” / “Checkout form gives an error and I can’t complete my purchase.”\n\nmedium – The issue or update affects secondary features, task progress, or non-critical operations. The user can still perform main tasks but with inconvenience or delay. Also applies to workflow notifications and status updates.\nExamples – “Task #2341 marked complete — please review.” / “The report export takes longer than usual.” / “Notifications stopped appearing, but the app still works.”\n\nlow – Minor or non-urgent matters that don’t affect functionality or access. Includes suggestions, praise, design opinions, and promotional or unrelated content.\nExamples – “Love the new theme, but text contrast is low.” / “It would be great if you could add dark mode.” / “We’re hiring! Apply today.”\n\n- Output only the JSON object and nothing else, matching the schema exactly.\n\nEmail: {{ $json.text }}",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "f0ff7c52-ab08-4179-a606-7c26dac2be67",
      "name": "Parsing stage for logic result",
      "type": "n8n-nodes-base.code",
      "position": [
        80,
        -80
      ],
      "parameters": {
        "jsCode": "// Get raw input\nlet rawString = $input.first().json.output;\n\n// Clean up markdown formatting if present\nrawString = rawString\n  .trim()\n  .replace(/^```(json)?/i, '')  // remove leading ``` or ```json\n  .replace(/```$/i, '')         // remove trailing ```\n  .trim();\n\n// Try parsing the cleaned string\nlet parsed;\ntry {\n  parsed = JSON.parse(rawString);\n} catch (error) {\n  throw new Error(`Failed to parse JSON. Cleaned input was:\\n${rawString}\\n\\nError: ${error.message}`);\n}\n\nreturn parsed;"
      },
      "typeVersion": 2
    },
    {
      "id": "f4494b77-af5f-491a-a879-35626a4a53c1",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -576,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 880,
        "content": "## 1. 通过邮件捕获启动工作流"
      },
      "typeVersion": 1
    },
    {
      "id": "6ee8c2c2-ae3e-4b3e-9c3c-64c22b75f575",
      "name": "收到邮件时启动工作流",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -528,
        96
      ],
      "parameters": {
        "simple": false,
        "filters": {},
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "Ebl93tRE6i7EYQt1",
          "name": "Gmail account"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "4d05284b-c32c-4976-a288-eae436031618",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1200,
        -400
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 592,
        "content": "## 5. 在 Dart 中创建分类任务"
      },
      "typeVersion": 1
    },
    {
      "id": "ab0ce8ce-5e7c-4ea1-884c-04e29e4085c0",
      "name": "OpenAI 聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -384,
        272
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "jojaGItsUqzNt9V6",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "2511dbfe-0144-4732-a774-8aadeced4b3d",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1040,
        -384
      ],
      "parameters": {
        "width": 400,
        "height": 544,
        "content": "## 支持邮件路由模板"
      },
      "typeVersion": 1
    },
    {
      "id": "75fed5e4-c0c8-4ce8-a6a7-17802648187c",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -16,
        -368
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 448,
        "content": "## 2. 解析 AI 输出"
      },
      "typeVersion": 1
    },
    {
      "id": "3c97d14f-68a1-490a-8038-108067275ff9",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        -336
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 416,
        "content": "## 3. 完整邮件正文清理"
      },
      "typeVersion": 1
    },
    {
      "id": "ba98569a-e446-4aef-88c7-d529b233f180",
      "name": "便签5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        -352
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 448,
        "content": "## 4. 检索目标看板"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "27f135de-6b55-42ad-8a04-f8cc67fc925f",
  "connections": {
    "Create a new task": {
      "main": [
        [
          {
            "node": "Create a new comment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Email triage assistant logic",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Email triage assistant logic": {
      "main": [
        [
          {
            "node": "Parsing stage for logic result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cleaning up full text of email": {
      "main": [
        [
          {
            "node": "Retrieve an existing dartboard",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parsing stage for logic result": {
      "main": [
        [
          {
            "node": "Cleaning up full text of email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve an existing dartboard": {
      "main": [
        [
          {
            "node": "Create a new task",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Launch workflow on email receive": {
      "main": [
        [
          {
            "node": "Email triage assistant logic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

这是一个中级难度的通用自动化工作流。适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量14
分类-
节点类型6
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

作者

The only truly AI-native project management tool

外部链接
在 n8n.io 上查看 →

分享此工作流