{
  "name": "Support Triage Concierge",
  "nodes": [
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "simple": false,
        "maxResults": 5,
        "filters": {
          "q": "subject:\"[Fortavault Support Demo]\"",
          "readStatus": "both"
        }
      },
      "id": "6febe2e8-11f2-4f7c-b837-1aaa1560f23e",
      "name": "Watch Support Inbox",
      "type": "n8n-nodes-base.gmailTrigger",
      "typeVersion": 1.4,
      "position": [0, 300],
      "credentials": {
        "gmailOAuth2": {
          "name": "Gmail account"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "const items = $input.all();\nconst results = [];\nfor (const item of items) {\n  const text = item.json.text || item.json.snippet || '';\n  const emailMatch = text.match(/Customer Email:\\s*(\\S+)/i);\n  const nameMatch = text.match(/Customer Name:\\s*(.+)/i);\n  const customerEmail = emailMatch ? emailMatch[1].trim() : '';\n  const customerName = nameMatch ? nameMatch[1].trim() : 'Unknown';\n  let bodyText = text;\n  bodyText = bodyText.replace(/Customer Email:.*(\\r?\\n|$)/i, '');\n  bodyText = bodyText.replace(/Customer Name:.*(\\r?\\n|$)/i, '');\n  bodyText = bodyText.trim();\n  results.push({\n    json: {\n      gmailMessageId: item.json.id,\n      subject: item.json.subject || '(no subject)',\n      customerEmail: customerEmail,\n      customerName: customerName,\n      bodyText: bodyText,\n      receivedAt: item.json.date || new Date().toISOString()\n    }\n  });\n}\nreturn results;"
      },
      "id": "92cc1783-def4-4ca5-9d15-6d99105e146c",
      "name": "Parse Simulated Support Email",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [220, 300]
    },
    {
      "parameters": {
        "resource": "search",
        "operation": "query",
        "query": "=SELECT Id, Name, Email, AccountId, Account.Name, Account.AnnualRevenue FROM Contact WHERE Email = '{{ $json.customerEmail }}' LIMIT 1"
      },
      "id": "b6d19060-12ae-45b0-b18c-d931f185ad41",
      "name": "Look Up Customer in Salesforce",
      "type": "n8n-nodes-base.salesforce",
      "typeVersion": 1.1,
      "position": [440, 300],
      "alwaysOutputData": true,
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "Salesforce account"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "const item = $input.first().json;\nconst account = item.Account || {};\nconst revenue = (account.AnnualRevenue === undefined || account.AnnualRevenue === null) ? null : account.AnnualRevenue;\nlet tier = 'SMB';\nif (revenue === null) {\n  tier = 'Unrecognized';\n} else if (revenue >= 300000000) {\n  tier = 'Enterprise';\n} else if (revenue >= 20000000) {\n  tier = 'Mid-Market';\n} else {\n  tier = 'SMB';\n}\nreturn [{\n  json: {\n    contactId: item.Id || null,\n    accountId: item.AccountId || null,\n    accountName: account.Name || 'Unknown (no CRM match)',\n    customerTier: tier,\n    contactName: item.Name || null\n  }\n}];"
      },
      "id": "f73e5080-b3df-4273-8415-1947dfed395f",
      "name": "Determine Customer Tier",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [660, 300]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Incoming support email:\n\nSubject: {{ $('Parse Simulated Support Email').item.json.subject }}\nFrom (customer): {{ $('Parse Simulated Support Email').item.json.customerName }} <{{ $('Parse Simulated Support Email').item.json.customerEmail }}>\nAccount: {{ $('Determine Customer Tier').item.json.accountName }}\nCustomer tier: {{ $('Determine Customer Tier').item.json.customerTier }}\n\nMessage body:\n{{ $('Parse Simulated Support Email').item.json.bodyText }}\n\nClassify this support request.",
        "hasOutputParser": true,
        "options": {
          "systemMessage": "You are a support triage classifier for Fortavault, Inc., a fictional data protection and security platform (cloud backup, ransomware recovery, zero-trust access, and compliance reporting). Products: Fortavault Backup Cloud, Fortavault Shield (ransomware detection + one-click rollback), Fortavault Access (zero-trust), Fortavault Insights (compliance reporting). Key competitors: Veyron Data, Ashcombe Systems, Cyphertide, Northgate Cloud Security, Ridgeline Compliance.\n\nRead the incoming support email and classify it.\n\ncategory: exactly one of \"Security Incident\", \"Technical Issue\", \"Billing/Account\", \"Feature Request/General\". Use \"Security Incident\" only for genuine security concerns - suspected breach, ransomware, unauthorized access, data exposure. Most product-not-working reports are \"Technical Issue\".\n\npriority: exactly one of \"Urgent\", \"High\", \"Normal\", \"Low\", based on the business impact and urgency in the email content alone. Customer tier is handled separately downstream - do not factor it into this field.\n\nsummary: a 1-2 sentence internal case summary a support rep could read at a glance.\n\nrationale: a 1-sentence explanation of why you assigned this category and priority.\n\nRespond with a JSON object with exactly four fields: category, priority, summary, rationale."
        }
      },
      "id": "84d87e8c-53ca-418a-8fb1-eb229dfac471",
      "name": "Support Triage Classifier",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [880, 300]
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-6",
          "cachedResultName": "Claude Sonnet 4.6"
        },
        "options": {
          "temperature": 0.2
        }
      },
      "id": "51a8f1af-8316-4dfe-a7cd-98c4910d2d49",
      "name": "Anthropic Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "typeVersion": 1.5,
      "position": [880, 540],
      "credentials": {
        "anthropicApi": {
          "name": "Anthropic account"
        }
      }
    },
    {
      "parameters": {
        "schemaType": "fromJson",
        "jsonSchemaExample": "{ \"category\": \"Technical Issue\", \"priority\": \"High\", \"summary\": \"brief internal case summary\", \"rationale\": \"brief 1-sentence reasoning\" }",
        "autoFix": false
      },
      "id": "64f7bd65-51a5-4a8d-aedd-e98ea1502f78",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "typeVersion": 1.3,
      "position": [1080, 540]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "const ai = $input.first().json.output;\nconst category = ai.category;\nconst aiPriority = ai.priority;\nconst tier = $('Determine Customer Tier').item.json.customerTier;\n\nlet finalPriority = 'Medium';\nlet pingSlack = true;\nlet slackMention = '';\nlet slaTargetLabel = '4 hours';\nlet queue = 'Standard Support';\nlet caseType = 'Problem';\n\nif (category === 'Billing/Account') {\n  caseType = 'Question';\n} else if (category === 'Feature Request/General') {\n  caseType = 'Feature Request';\n} else {\n  caseType = 'Problem';\n}\n\nif (category === 'Security Incident') {\n  finalPriority = 'High';\n  pingSlack = true;\n  slackMention = '<!here> ';\n  slaTargetLabel = '15 minutes';\n  queue = 'Escalations';\n} else if (tier === 'Enterprise') {\n  queue = 'Enterprise Support';\n  if (aiPriority === 'Urgent' || aiPriority === 'High') {\n    finalPriority = 'High';\n    pingSlack = true;\n    slackMention = '<!here> ';\n    slaTargetLabel = '1 hour';\n  } else {\n    finalPriority = 'Medium';\n    pingSlack = true;\n    slackMention = '';\n    slaTargetLabel = '4 hours';\n  }\n} else if (tier === 'Mid-Market') {\n  queue = 'Standard Support';\n  if (aiPriority === 'Urgent' || aiPriority === 'High') {\n    finalPriority = 'High';\n    pingSlack = true;\n    slackMention = '';\n    slaTargetLabel = '4 hours';\n  } else {\n    finalPriority = 'Medium';\n    pingSlack = true;\n    slackMention = '';\n    slaTargetLabel = '1 business day';\n  }\n} else {\n  queue = 'Self-Serve Queue';\n  if (aiPriority === 'Urgent' || aiPriority === 'High') {\n    finalPriority = 'High';\n    pingSlack = true;\n    slackMention = '';\n    slaTargetLabel = '4 hours';\n  } else {\n    finalPriority = 'Low';\n    pingSlack = false;\n    slackMention = '';\n    slaTargetLabel = '2 business days';\n  }\n}\n\nreturn [{\n  json: {\n    category: category,\n    aiPriority: aiPriority,\n    summary: ai.summary,\n    rationale: ai.rationale,\n    finalPriority: finalPriority,\n    pingSlack: pingSlack,\n    slackMention: slackMention,\n    slaTargetLabel: slaTargetLabel,\n    queue: queue,\n    caseType: caseType\n  }\n}];"
      },
      "id": "7dd3fdc0-11ae-4980-a4ab-0c59c331ce91",
      "name": "Compute Routing & SLA",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [1300, 300]
    },
    {
      "parameters": {
        "resource": "case",
        "operation": "create",
        "type": "={{ $json.caseType }}",
        "additionalFields": {
          "accountId": "={{ $('Determine Customer Tier').item.json.accountId }}",
          "contactId": "={{ $('Determine Customer Tier').item.json.contactId }}",
          "subject": "={{ '[' + $json.queue + '] ' + $('Parse Simulated Support Email').item.json.subject }}",
          "description": "=Customer message:\n{{ $('Parse Simulated Support Email').item.json.bodyText }}\n\n--- AI triage ---\nCategory: {{ $json.category }}\nAI-assessed priority: {{ $json.aiPriority }}\nSummary: {{ $json.summary }}\nRationale: {{ $json.rationale }}\nCustomer tier: {{ $('Determine Customer Tier').item.json.customerTier }}\nTarget SLA: {{ $json.slaTargetLabel }}",
          "origin": "Email",
          "priority": "={{ $json.finalPriority }}",
          "status": "New"
        }
      },
      "id": "67153138-3122-46a3-a825-b6627847fd69",
      "name": "Create Salesforce Case",
      "type": "n8n-nodes-base.salesforce",
      "typeVersion": 1.1,
      "position": [1520, 300],
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "Salesforce account"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ $('Compute Routing & SLA').item.json.pingSlack }}",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "rightValue": true
            }
          ],
          "combinator": "and"
        }
      },
      "id": "8174560b-da78-41b3-bac3-c998f4fd193a",
      "name": "Ping Slack?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [1740, 300]
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "C0BQ3G96HL6"
        },
        "text": "={{ $('Compute Routing & SLA').item.json.slackMention }}New support case — {{ $('Compute Routing & SLA').item.json.queue }}\n\n{{ $('Parse Simulated Support Email').item.json.customerName }} ({{ $('Determine Customer Tier').item.json.accountName }} — {{ $('Determine Customer Tier').item.json.customerTier }})\nCategory: {{ $('Compute Routing & SLA').item.json.category }} | Priority: {{ $('Compute Routing & SLA').item.json.finalPriority }} | SLA target: {{ $('Compute Routing & SLA').item.json.slaTargetLabel }}\n\n{{ $('Compute Routing & SLA').item.json.summary }}\n\nWhy: {{ $('Compute Routing & SLA').item.json.rationale }}\n\nSalesforce Case: {{ $('Create Salesforce Case').item.json.id }}"
      },
      "id": "4791b700-c77e-4a1c-863e-ac87554b05e1",
      "name": "Post Slack Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.7,
      "position": [1960, 180],
      "credentials": {
        "slackApi": {
          "name": "Slack account"
        }
      }
    },
    {
      "parameters": {
        "resource": "row",
        "operation": "insert",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "B822UKLgJVgEHj8q",
          "cachedResultName": "Support Triage Log"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "emailSubject": "={{ $('Parse Simulated Support Email').item.json.subject }}",
            "customerEmail": "={{ $('Parse Simulated Support Email').item.json.customerEmail }}",
            "customerName": "={{ $('Parse Simulated Support Email').item.json.customerName }}",
            "accountName": "={{ $('Determine Customer Tier').item.json.accountName }}",
            "tier": "={{ $('Determine Customer Tier').item.json.customerTier }}",
            "category": "={{ $('Compute Routing & SLA').item.json.category }}",
            "aiPriority": "={{ $('Compute Routing & SLA').item.json.aiPriority }}",
            "finalPriority": "={{ $('Compute Routing & SLA').item.json.finalPriority }}",
            "rationale": "={{ $('Compute Routing & SLA').item.json.rationale }}",
            "summary": "={{ $('Compute Routing & SLA').item.json.summary }}",
            "caseId": "={{ $('Create Salesforce Case').item.json.id }}",
            "queue": "={{ $('Compute Routing & SLA').item.json.queue }}",
            "slaTarget": "={{ $('Compute Routing & SLA').item.json.slaTargetLabel }}",
            "slackPinged": true,
            "loggedAt": "={{ $now.toISO() }}"
          }
        }
      },
      "id": "ba51f7d2-3271-473f-9324-548893cffb1d",
      "name": "Log - Slack Pinged",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [2180, 180]
    },
    {
      "parameters": {
        "resource": "row",
        "operation": "insert",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "B822UKLgJVgEHj8q",
          "cachedResultName": "Support Triage Log"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "emailSubject": "={{ $('Parse Simulated Support Email').item.json.subject }}",
            "customerEmail": "={{ $('Parse Simulated Support Email').item.json.customerEmail }}",
            "customerName": "={{ $('Parse Simulated Support Email').item.json.customerName }}",
            "accountName": "={{ $('Determine Customer Tier').item.json.accountName }}",
            "tier": "={{ $('Determine Customer Tier').item.json.customerTier }}",
            "category": "={{ $('Compute Routing & SLA').item.json.category }}",
            "aiPriority": "={{ $('Compute Routing & SLA').item.json.aiPriority }}",
            "finalPriority": "={{ $('Compute Routing & SLA').item.json.finalPriority }}",
            "rationale": "={{ $('Compute Routing & SLA').item.json.rationale }}",
            "summary": "={{ $('Compute Routing & SLA').item.json.summary }}",
            "caseId": "={{ $('Create Salesforce Case').item.json.id }}",
            "queue": "={{ $('Compute Routing & SLA').item.json.queue }}",
            "slaTarget": "={{ $('Compute Routing & SLA').item.json.slaTargetLabel }}",
            "slackPinged": false,
            "loggedAt": "={{ $now.toISO() }}"
          }
        }
      },
      "id": "579277d9-256b-423f-b03e-d1903942bd69",
      "name": "Log - Queued Silently",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [1960, 420]
    }
  ],
  "connections": {
    "Watch Support Inbox": {
      "main": [[{ "node": "Parse Simulated Support Email", "type": "main", "index": 0 }]]
    },
    "Parse Simulated Support Email": {
      "main": [[{ "node": "Look Up Customer in Salesforce", "type": "main", "index": 0 }]]
    },
    "Look Up Customer in Salesforce": {
      "main": [[{ "node": "Determine Customer Tier", "type": "main", "index": 0 }]]
    },
    "Determine Customer Tier": {
      "main": [[{ "node": "Support Triage Classifier", "type": "main", "index": 0 }]]
    },
    "Support Triage Classifier": {
      "main": [[{ "node": "Compute Routing & SLA", "type": "main", "index": 0 }]]
    },
    "Anthropic Chat Model": {
      "ai_languageModel": [[{ "node": "Support Triage Classifier", "type": "ai_languageModel", "index": 0 }]]
    },
    "Structured Output Parser": {
      "ai_outputParser": [[{ "node": "Support Triage Classifier", "type": "ai_outputParser", "index": 0 }]]
    },
    "Compute Routing & SLA": {
      "main": [[{ "node": "Create Salesforce Case", "type": "main", "index": 0 }]]
    },
    "Create Salesforce Case": {
      "main": [[{ "node": "Ping Slack?", "type": "main", "index": 0 }]]
    },
    "Ping Slack?": {
      "main": [
        [{ "node": "Post Slack Alert", "type": "main", "index": 0 }],
        [{ "node": "Log - Queued Silently", "type": "main", "index": 0 }]
      ]
    },
    "Post Slack Alert": {
      "main": [[{ "node": "Log - Slack Pinged", "type": "main", "index": 0 }]]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}
