{
  "name": "FD-AutoPilot \u5de5\u5355\u81ea\u52a8\u5904\u7406",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "\u5b9a\u65f6\u89e6\u53d1\uff08\u6bcf15\u5206\u949f\uff09",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        300
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "fd-new-tickets",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-trigger",
      "name": "Webhook \u89e6\u53d1\uff08\u5b9e\u65f6\uff09",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "content": "## \u5de5\u5355\u81ea\u52a8\u5904\u7406\u5de5\u4f5c\u6d41\n\n### \u6d41\u7a0b\n1. \u767b\u5f55\u83b7\u53d6 JWT\n2. \u83b7\u53d6\u5f85\u7ffb\u8bd1\u5de5\u5355\n3. \u5faa\u73af\u9010\u4e2a\u5904\u7406\u6bcf\u4e2a\u5de5\u5355\uff1a\n   - \u8c03\u7528\u7ffb\u8bd1 Agent \u2192 \u4fdd\u5b58\u7ffb\u8bd1\u7ed3\u679c\n   - \u8c03\u7528\u56de\u590d Agent \u2192 \u4fdd\u5b58\u56de\u590d\u7ed3\u679c\n   - \u63a8\u9001\u5ba1\u6838\u901a\u77e5\n4. \u5faa\u73af\u7ed3\u675f \u2192 \u6c47\u603b\u7ed3\u679c\n\n### \u8bbe\u8ba1\u539f\u5219\n- Agent \u7aef\u70b9\u7eaf\u900f\u4f20\uff0c\u4e0d\u542b\u4e1a\u52a1\u903b\u8f91\n- Prompt \u6784\u5efa\u3001\u6570\u636e\u6821\u9a8c\u5728\u5de5\u4f5c\u6d41\u8282\u70b9\u4e2d\u5b8c\u6210\n- \u7ecf Sync Bridge \u8def\u7531\u5230\u5ba2\u6237\u7aef\u6267\u884c",
        "height": 300,
        "width": 340
      },
      "id": "sticky-note",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -100
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:9988/api/v1/auth/login",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "{\n  \"username\": \"n8n-service\",\n  \"password\": \"n8n-service\"\n}",
        "options": {}
      },
      "id": "login",
      "name": "\u767b\u5f55\u83b7\u53d6 JWT",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        300,
        150
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "http://localhost:9988/api/v1/n8n/tickets/pending",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $json.data.accessToken }}"
            }
          ]
        },
        "options": {}
      },
      "id": "fetch-pending",
      "name": "\u83b7\u53d6\u5f85\u5904\u7406\u5de5\u5355",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        550,
        150
      ]
    },
    {
      "parameters": {
        "fieldToSplitOut": "data",
        "options": {}
      },
      "id": "split-tickets",
      "name": "\u5c55\u5f00\u5de5\u5355\u6570\u7ec4",
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        780,
        150
      ]
    },
    {
      "parameters": {
        "batchSize": 1,
        "options": {}
      },
      "id": "loop-tickets",
      "name": "\u9010\u4e2a\u5904\u7406\u5de5\u5355",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 2,
      "position": [
        1020,
        150
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:9988/api/v1/n8n/agents/ticket-translate/execute",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('\u767b\u5f55\u83b7\u53d6 JWT').item.json.data.accessToken }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ input: { prompt: 'You are a professional customer support translator. Translate the following support ticket into Simplified Chinese (zh-CN).\\n\\nSTRICT OUTPUT FORMAT:\\n- Output ONLY a raw JSON object. Start your response with { and end with }.\\n- Do NOT wrap in markdown code fences (```). Do NOT add any text before or after the JSON.\\n\\nTRANSLATION RULES:\\n1. Translate \"subject\" and \"description\" fields into Simplified Chinese.\\n2. For each item in \"conversations\", translate the \"bodyText\" field. Keep \"id\" unchanged.\\n3. All translated text must be natural Simplified Chinese.\\n\\nREQUIRED JSON STRUCTURE (use exactly these key names):\\n{\"subject\":\"\u7ffb\u8bd1\u540e\u7684\u6807\u9898\",\"description\":\"\u7ffb\u8bd1\u540e\u7684\u6b63\u6587\",\"conversations\":[{\"id\":123,\"bodyText\":\"\u7ffb\u8bd1\u540e\u7684\u6d88\u606f\"}]}\\n\\n=== TICKET DATA ===\\nSubject: ' + ($json.subject || '') + '\\nContent (JSON):\\n' + ($json.content || ''), models: ['gemini-2.5-flash'] }, refType: 'ticket', refId: String($json.id), timeoutMs: 300000 }) }}",
        "options": {
          "timeout": 300000
        }
      },
      "id": "call-translate",
      "name": "\u8c03\u7528\u7ffb\u8bd1 Agent",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1280,
        150
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=http://localhost:9988/api/v1/n8n/tickets/{{ $('\u9010\u4e2a\u5904\u7406\u5de5\u5355').item.json.id }}/save-translation",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('\u767b\u5f55\u83b7\u53d6 JWT').item.json.data.accessToken }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ (() => { let raw = ($json.data && $json.data.output) || ''; const fm = raw.match(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/); if (fm) raw = fm[1]; raw = raw.trim(); let p = {}; try { p = JSON.parse(raw); } catch(e) {} const desc = p.description || p.descriptionText || p.description_text || ''; const convs = (p.conversations || []).map(c => ({ id: c.id, bodyText: c.bodyText || c.body_text || '' })); return JSON.stringify({ translatedTitle: p.subject || '', translatedContent: JSON.stringify({ description: desc, conversations: convs }), targetLang: 'zh-CN' }); })() }}",
        "options": {}
      },
      "id": "save-translation",
      "name": "\u4fdd\u5b58\u7ffb\u8bd1\u7ed3\u679c",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1540,
        150
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:9988/api/v1/n8n/agents/ticket-reply/execute",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('\u767b\u5f55\u83b7\u53d6 JWT').item.json.data.accessToken }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ input: { ticket: { id: $('\u9010\u4e2a\u5904\u7406\u5de5\u5355').item.json.id, subject: $('\u9010\u4e2a\u5904\u7406\u5de5\u5355').item.json.subject || '', content: $('\u9010\u4e2a\u5904\u7406\u5de5\u5355').item.json.content || '' }, lastAuditRemark: $('\u9010\u4e2a\u5904\u7406\u5de5\u5355').item.json.lastAuditRemark || '' }, refType: 'ticket', refId: String($('\u9010\u4e2a\u5904\u7406\u5de5\u5355').item.json.id), timeoutMs: 300000 }) }}",
        "options": {
          "timeout": 300000
        }
      },
      "id": "call-reply",
      "name": "\u8c03\u7528\u56de\u590d Agent",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1800,
        150
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=http://localhost:9988/api/v1/n8n/tickets/{{ $('\u9010\u4e2a\u5904\u7406\u5de5\u5355').item.json.id }}/save-reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('\u767b\u5f55\u83b7\u53d6 JWT').item.json.data.accessToken }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ (() => { let raw = ($json.data && $json.data.output) || ''; const fm = raw.match(/```(?:\\w+)?\\s*([\\s\\S]*?)\\s*```/); if (fm) raw = fm[1]; raw = raw.trim(); let targetReply = raw; let zhReply = raw; try { const arr = JSON.parse(raw); if (Array.isArray(arr)) { targetReply = arr[0] || ''; zhReply = arr[1] || arr[0] || ''; } else if (typeof arr === 'string') { targetReply = arr; zhReply = arr; } } catch(e) {} return JSON.stringify({ targetReply, zhReply }); })() }}",
        "options": {}
      },
      "id": "save-reply",
      "name": "\u4fdd\u5b58\u56de\u590d\u7ed3\u679c",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2060,
        150
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=http://localhost:9988/api/v1/n8n/tickets/{{ $('\u9010\u4e2a\u5904\u7406\u5de5\u5355').item.json.id }}/notify-audit",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('\u767b\u5f55\u83b7\u53d6 JWT').item.json.data.accessToken }}"
            }
          ]
        },
        "options": {}
      },
      "id": "notify-audit",
      "name": "\u63a8\u9001\u5ba1\u6838\u901a\u77e5",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2320,
        150
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={\n  \"success\": true,\n  \"message\": \"Webhook received\"\n}",
        "options": {}
      },
      "id": "webhook-response",
      "name": "Webhook \u54cd\u5e94",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "values": {
          "number": [
            {
              "name": "processedCount",
              "value": "={{ $items().length }}"
            }
          ],
          "string": [
            {
              "name": "summary",
              "value": "=n8n \u5de5\u5355\u81ea\u52a8\u5904\u7406\u5b8c\u6210: \u5171\u5904\u7406 {{ $items().length }} \u4e2a\u5de5\u5355"
            }
          ]
        },
        "options": {}
      },
      "id": "summary",
      "name": "\u6c47\u603b\u7ed3\u679c",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1020,
        400
      ]
    }
  ],
  "connections": {
    "\u5b9a\u65f6\u89e6\u53d1\uff08\u6bcf15\u5206\u949f\uff09": {
      "main": [
        [
          {
            "node": "\u767b\u5f55\u83b7\u53d6 JWT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook \u89e6\u53d1\uff08\u5b9e\u65f6\uff09": {
      "main": [
        [
          {
            "node": "Webhook \u54cd\u5e94",
            "type": "main",
            "index": 0
          },
          {
            "node": "\u767b\u5f55\u83b7\u53d6 JWT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook \u54cd\u5e94": {
      "main": [
        []
      ]
    },
    "\u767b\u5f55\u83b7\u53d6 JWT": {
      "main": [
        [
          {
            "node": "\u83b7\u53d6\u5f85\u5904\u7406\u5de5\u5355",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u83b7\u53d6\u5f85\u5904\u7406\u5de5\u5355": {
      "main": [
        [
          {
            "node": "\u5c55\u5f00\u5de5\u5355\u6570\u7ec4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5c55\u5f00\u5de5\u5355\u6570\u7ec4": {
      "main": [
        [
          {
            "node": "\u9010\u4e2a\u5904\u7406\u5de5\u5355",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u9010\u4e2a\u5904\u7406\u5de5\u5355": {
      "main": [
        [
          {
            "node": "\u8c03\u7528\u7ffb\u8bd1 Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u6c47\u603b\u7ed3\u679c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u8c03\u7528\u7ffb\u8bd1 Agent": {
      "main": [
        [
          {
            "node": "\u4fdd\u5b58\u7ffb\u8bd1\u7ed3\u679c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4fdd\u5b58\u7ffb\u8bd1\u7ed3\u679c": {
      "main": [
        [
          {
            "node": "\u8c03\u7528\u56de\u590d Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u8c03\u7528\u56de\u590d Agent": {
      "main": [
        [
          {
            "node": "\u4fdd\u5b58\u56de\u590d\u7ed3\u679c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4fdd\u5b58\u56de\u590d\u7ed3\u679c": {
      "main": [
        [
          {
            "node": "\u63a8\u9001\u5ba1\u6838\u901a\u77e5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u63a8\u9001\u5ba1\u6838\u901a\u77e5": {
      "main": [
        [
          {
            "node": "\u9010\u4e2a\u5904\u7406\u5de5\u5355",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "tags": [
    {
      "name": "FD-AutoPilot"
    }
  ]
}