{
  "name": "Route and analyze customer feedback with Qwen3-VL, Tally, PostgreSQL",
  "nodes": [
    {
      "id": "0b32072f-1719-40da-99e4-f4e8b293049b",
      "name": "Tally Trigger",
      "type": "n8n-nodes-tallyforms.tallyTrigger",
      "position": [
        -3184,
        96
      ]
    },
    {
      "id": "9fabd87c-f43a-41c3-b399-c3872ad80e8f",
      "name": "Field Mapping",
      "type": "n8n-nodes-base.set",
      "position": [
        -2992,
        96
      ]
    },
    {
      "id": "34493ab7-6fb2-4a37-bb78-2bca0b2a264b",
      "name": "Sentiment Analysis",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -2400,
        -480
      ]
    },
    {
      "id": "419f51d4-f852-40ad-8eab-8e6a2080348b",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        -2784,
        304
      ]
    },
    {
      "id": "aeaa8d9c-49c6-404d-a211-47c3176681e4",
      "name": "Fetch Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2624,
        160
      ]
    },
    {
      "id": "da7dbeb3-5322-4dca-b537-19dc4d48d19f",
      "name": "Routing LLM",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1280,
        288
      ]
    },
    {
      "id": "a58aa5b2-06b8-4d13-bbd6-febaed4f3c59",
      "name": "#general-inquiries",
      "type": "n8n-nodes-base.set",
      "position": [
        -656,
        -112
      ]
    },
    {
      "id": "02726593-7118-48e6-9609-67d63387a673",
      "name": "#happy-customers",
      "type": "n8n-nodes-base.set",
      "position": [
        -656,
        80
      ]
    },
    {
      "id": "efadbae3-aaab-43f7-9c7a-374164f98702",
      "name": "Decision Logic",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -1248,
        80
      ]
    },
    {
      "id": "d28b483f-6532-41bc-89d1-a44ae3055fae",
      "name": "Send Discord Notification",
      "type": "n8n-nodes-base.discord",
      "position": [
        32,
        80
      ]
    },
    {
      "id": "5ca6bdaa-167c-42f0-b232-061a9e6666d2",
      "name": "Sentiment LLM",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -2432,
        -304
      ]
    },
    {
      "id": "49f4f0c4-dba2-4e52-888b-d2679898eca0",
      "name": "Sentiment Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -2224,
        -304
      ]
    },
    {
      "id": "83088e57-bafe-4db5-a33c-52979054b82a",
      "name": "Text Classification",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -2400,
        -176
      ]
    },
    {
      "id": "c8d310c9-26b0-4f77-b215-c3ea273882a9",
      "name": "Classification LLM",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -2432,
        0
      ]
    },
    {
      "id": "87a73538-5c81-4782-95dc-f93365b47b4a",
      "name": "Classification Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -2224,
        0
      ]
    },
    {
      "id": "fa7ad8ce-a4bc-41ac-95fb-f678c6d7de9c",
      "name": "Image Keyword Extraction",
      "type": "n8n-nodes-base.code",
      "position": [
        -2240,
        160
      ]
    },
    {
      "id": "bb3e6b39-5807-4ae6-ac42-1f0e98f29884",
      "name": "Empty Keywords Handler",
      "type": "n8n-nodes-base.set",
      "position": [
        -2320,
        320
      ]
    },
    {
      "id": "9f3b93cd-a552-40bd-a43d-58a41d2fb33f",
      "name": "Image Results Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        -2016,
        304
      ]
    },
    {
      "id": "474338a3-259d-41f9-85c7-4e7a56eb3aef",
      "name": "AI Results Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        -1808,
        48
      ]
    },
    {
      "id": "59f36ba5-5b5b-4a5d-8c9a-d8c2fec8d0b7",
      "name": "Data Aggregation",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        -1632,
        80
      ]
    },
    {
      "id": "f7dc2af7-bb87-49fe-ad03-19f6a0980f80",
      "name": "Save to PostgreSQL",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -1440,
        80
      ]
    },
    {
      "id": "5c9ccc4a-0b00-4388-a0e4-0f5545281dda",
      "name": "Route Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -1072,
        288
      ]
    },
    {
      "id": "ffdeca2f-317d-43b3-999c-05d57c357598",
      "name": "Channel Router",
      "type": "n8n-nodes-base.switch",
      "position": [
        -928,
        64
      ]
    },
    {
      "id": "8555c825-758e-4543-8360-1c66635dca42",
      "name": "#support-urgent",
      "type": "n8n-nodes-base.set",
      "position": [
        -656,
        272
      ]
    },
    {
      "id": "b6257351-c53d-4655-bd52-e1456d851389",
      "name": "Build Discord Message",
      "type": "n8n-nodes-base.merge",
      "position": [
        -384,
        64
      ]
    },
    {
      "id": "d10f5b49-db45-4099-9cd9-11b487d6d91d",
      "name": "Format Embed Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -192,
        80
      ]
    },
    {
      "id": "e19dedde-5c60-4e93-b634-6e3bb60eeefc",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -960,
        -192
      ],
      "parameters": {
        "width": 1120,
        "height": 624,
        "content": "## 4. Discord Distribution\nThe **Channel Router** sends the data to the correct branch where the final message is formatted as a rich embed for Discord."
      }
    },
    {
      "id": "6f8e88ad-57ec-4680-bd6a-6078d180ef02",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1664,
        -16
      ],
      "parameters": {
        "width": 688,
        "height": 448,
        "content": "## 3. Storage & Logic\nThe aggregated data is committed to the database. The **Decision Logic** and **Routing LLM** then determine which team needs to see this specific feedback."
      }
    },
    {
      "id": "2a5d434a-44d5-4432-a834-8e3e02ed8d0c",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2480,
        -576
      ],
      "parameters": {
        "width": 800,
        "height": 1056,
        "content": "## 2. Multi-Track AI Analysis\nParallel processing for sentiment, category, and visual content. **AI Results Merge** combines these three streams into a single JSON object."
      }
    },
    {
      "id": "a6f80e82-1844-4953-b1d4-311411b81309",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3200,
        80
      ],
      "parameters": {
        "width": 704,
        "height": 400,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## 1. Input & Prep\nCaptures the webhook from Tally and maps the fields. The **Fetch Image** branch ensures binary data is handled only if an attachment exists."
      }
    },
    {
      "id": "55b2da1f-4324-4d25-908c-c1fd90073a39",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1664,
        -160
      ],
      "parameters": {
        "width": 688,
        "height": 128,
        "content": "### ⚠️ Local Inference Setup\n- The nodes **Sentiment LLM**, **Classification LLM**, **Image Keyword Extraction**, and **Routing LLM** all point to a local OpenAI-compatible API.\n- If running n8n in Do"
      }
    },
    {
      "id": "10626d44-3c6c-4c6f-8679-70391ecb5c6d",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3920,
        64
      ],
      "parameters": {
        "width": 704,
        "height": 432,
        "content": "### How it works\nThis workflow provides end-to-end automation for customer feedback. It triggers from a **Tally.so** form, processes the input through a multi-track AI pipeline (Sentiment, Classificat"
      }
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Fetch Image",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Empty Keywords Handler",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Image": {
      "main": [
        [
          {
            "node": "Image Keyword Extraction",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Routing LLM": {
      "ai_languageModel": [
        [
          {
            "node": "Decision Logic",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Route Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Decision Logic",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Field Mapping": {
      "main": [
        [
          {
            "node": "Sentiment Analysis",
            "type": "main",
            "index": 0
          },
          {
            "node": "If",
            "type": "main",
            "index": 0
          },
          {
            "node": "Text Classification",
            "type": "main",
            "index": 0
          },
          {
            "node": "AI Results Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Sentiment LLM": {
      "ai_languageModel": [
        [
          {
            "node": "Sentiment Analysis",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Tally Trigger": {
      "main": [
        [
          {
            "node": "Field Mapping",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Channel Router": {
      "main": [
        [
          {
            "node": "#general-inquiries",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "#happy-customers",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "#support-urgent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Decision Logic": {
      "main": [
        [
          {
            "node": "Channel Router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "#support-urgent": {
      "main": [
        [
          {
            "node": "Build Discord Message",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "#happy-customers": {
      "main": [
        [
          {
            "node": "Build Discord Message",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "AI Results Merge": {
      "main": [
        [
          {
            "node": "Data Aggregation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Data Aggregation": {
      "main": [
        [
          {
            "node": "Save to PostgreSQL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sentiment Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Sentiment Analysis",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Format Embed Data": {
      "main": [
        [
          {
            "node": "Send Discord Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "#general-inquiries": {
      "main": [
        [
          {
            "node": "Build Discord Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classification LLM": {
      "ai_languageModel": [
        [
          {
            "node": "Text Classification",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Save to PostgreSQL": {
      "main": [
        [
          {
            "node": "Decision Logic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sentiment Analysis": {
      "main": [
        [
          {
            "node": "AI Results Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Image Results Merge": {
      "main": [
        [
          {
            "node": "AI Results Merge",
            "type": "main",
            "index": 3
          }
        ]
      ]
    },
    "Text Classification": {
      "main": [
        [
          {
            "node": "AI Results Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Build Discord Message": {
      "main": [
        [
          {
            "node": "Format Embed Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classification Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Text Classification",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Empty Keywords Handler": {
      "main": [
        [
          {
            "node": "Image Results Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Image Keyword Extraction": {
      "main": [
        [
          {
            "node": "Image Results Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}