{
  "id": "IHGYM0xJj3MySPBg",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Sentiment Analysis",
  "tags": [],
  "nodes": [
    {
      "id": "85e90e1b-d214-4e9b-a199-785df5bf7a56",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1152,
        -656
      ],
      "parameters": {
        "width": 384,
        "height": 624,
        "content": "## SENTIMENT ANALYSIS WORKFLOW\nThis workflow analyzes multiple text inputs and classifies them into Positive, Neutral or Negative using the Hugging Face sentiment model. Each input is processed individually, scores are compared and the highest score determines the sentiment with a confidence check for accuracy.\n\n### How it works:\n\nWebhook receives input data\nText is split and sent to the model\nScores are returned and merged with original text\nSentiment is computed and routed\nResults are stored in Google Sheets\nNegative feedback triggers Jira ticket\n\n### Setup:\n\nAdd Hugging Face API token in HTTP node\nConfigure Google Sheets (3 tabs: Positive, Neutral, Negative)\nAdd Jira credentials for ticket creation\n\nThis workflow enables automated sentiment tracking and issue escalation."
      },
      "typeVersion": 1
    },
    {
      "id": "074ed1a8-615a-445c-bae0-74d8762c63dc",
      "name": "Receive Feedback",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -592,
        -112
      ],
      "parameters": {
        "path": "sentiment-input",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "d5bdebd7-fa3e-4956-bca9-74bdb23237b0",
      "name": "Split Text Items",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -400,
        -112
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "data"
      },
      "typeVersion": 1
    },
    {
      "id": "6817cd77-9b87-45b1-9381-e3aa1e823526",
      "name": "Rate Limit Control",
      "type": "n8n-nodes-base.wait",
      "position": [
        -176,
        -112
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "ff0c7c83-49d5-4384-9eeb-e67f879fe82a",
      "name": "Preserve Input Text",
      "type": "n8n-nodes-base.set",
      "position": [
        48,
        -112
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "91a90188-c914-4704-8abc-659ce07b9f9c",
              "name": "text",
              "type": "string",
              "value": "={{$json[\"text\"]}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "02de6def-0d01-4c33-9da5-415253a835d6",
      "name": "Get Sentiment Scores",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        272,
        -48
      ],
      "parameters": {
        "url": "https://router.huggingface.co/hf-inference/models/cardiffnlp/twitter-roberta-base-sentiment",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"inputs\": \"{{$json['text']}}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3,
      "alwaysOutputData": true
    },
    {
      "id": "1c4237ad-4f01-4b21-8043-86844cf8ed55",
      "name": "Merge Text & Scores",
      "type": "n8n-nodes-base.merge",
      "position": [
        496,
        -112
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "c362a2a5-44c6-4fae-8045-09ceb6b97742",
      "name": "Compute Sentiment",
      "type": "n8n-nodes-base.set",
      "position": [
        720,
        -112
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "81f3dbca-6106-4196-8243-8bd8ac7a4271",
              "name": "text",
              "type": "string",
              "value": "={{$json[\"text\"]}}"
            },
            {
              "id": "79ab41f4-609d-43c3-ba18-8d12eac092d6",
              "name": "sentiment",
              "type": "string",
              "value": "={{\n  Object.values($json)\n    .sort((a, b) => b.score - a.score)[0].label === \"LABEL_2\"\n    && Object.values($json)\n        .sort((a, b) => b.score - a.score)[0].score > 0.9\n    ? \"Positive\"\n    : Object.values($json)\n        .sort((a, b) => b.score - a.score)[0].label === \"LABEL_0\"\n      && Object.values($json)\n          .sort((a, b) => b.score - a.score)[0].score > 0.9\n    ? \"Negative\"\n    : \"Neutral\"\n}}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "3a2b9c11-c191-4d7f-b7c7-9573fd22839e",
      "name": "Route by Sentiment",
      "type": "n8n-nodes-base.switch",
      "position": [
        944,
        -128
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "fa3a5eee-6fb4-4f4d-8dbf-7ecbbc65a345",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json[\"sentiment\"]}}",
                    "rightValue": "Positive"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "265e8950-d4a8-40a7-9480-627a8362b831",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json[\"sentiment\"]}}",
                    "rightValue": "Neutral"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "87ac609b-0627-4f12-bc3c-ceb4b27f27b1",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json[\"sentiment\"]}}",
                    "rightValue": "Negative"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "44d65e48-8ada-47d2-9a28-66737526e67e",
      "name": "Store Positive Feedback",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1168,
        -304
      ],
      "parameters": {
        "columns": {
          "value": {
            "Text ": "={{$json[\"text\"]}}",
            "Time ": "={{$now}}",
            "Sentiment": "={{$json[\"sentiment\"]}}"
          },
          "schema": [
            {
              "id": "Text ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Text ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sentiment",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sentiment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Time ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Time ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ioRrakDQyMd6puq5WytgFbwhlwqFNEczLK_PBTEB6a4/edit#gid=0",
          "cachedResultName": "Positive"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1ioRrakDQyMd6puq5WytgFbwhlwqFNEczLK_PBTEB6a4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ioRrakDQyMd6puq5WytgFbwhlwqFNEczLK_PBTEB6a4/edit?usp=drivesdk",
          "cachedResultName": "Sentiment Analysis"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "21c74da3-b7a2-44a4-9ac0-1ad73d483a92",
      "name": "Store Neutral Feedback",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1168,
        -112
      ],
      "parameters": {
        "columns": {
          "value": {
            "Text ": "={{$json[\"text\"]}}",
            "Time ": "={{$now}}",
            "Sentiment": "={{$json[\"sentiment\"]}}"
          },
          "schema": [
            {
              "id": "Text ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Text ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sentiment",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sentiment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Time ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Time ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1123224451,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ioRrakDQyMd6puq5WytgFbwhlwqFNEczLK_PBTEB6a4/edit#gid=1123224451",
          "cachedResultName": "Neutral"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1ioRrakDQyMd6puq5WytgFbwhlwqFNEczLK_PBTEB6a4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ioRrakDQyMd6puq5WytgFbwhlwqFNEczLK_PBTEB6a4/edit?usp=drivesdk",
          "cachedResultName": "Sentiment Analysis"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "7cd22a9d-1bfe-499c-8246-f382f2fbbecf",
      "name": "Store Negative Feedback",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1168,
        80
      ],
      "parameters": {
        "columns": {
          "value": {
            "Text ": "={{$json[\"text\"]}}",
            "Time ": "={{$now}}",
            "Sentiment": "={{$json[\"sentiment\"]}}"
          },
          "schema": [
            {
              "id": "Text ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Text ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sentiment",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sentiment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Time ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Time ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1999713849,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ioRrakDQyMd6puq5WytgFbwhlwqFNEczLK_PBTEB6a4/edit#gid=1999713849",
          "cachedResultName": "Negative"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1ioRrakDQyMd6puq5WytgFbwhlwqFNEczLK_PBTEB6a4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ioRrakDQyMd6puq5WytgFbwhlwqFNEczLK_PBTEB6a4/edit?usp=drivesdk",
          "cachedResultName": "Sentiment Analysis"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "ccdedc51-2be7-4de3-bc87-999ee13b51f4",
      "name": "Create Jira Ticket",
      "type": "n8n-nodes-base.jira",
      "position": [
        1392,
        80
      ],
      "parameters": {
        "project": {
          "__rl": true,
          "mode": "list",
          "value": "10001",
          "cachedResultName": "My Software Team"
        },
        "summary": "Negative Feedback Received",
        "issueType": {
          "__rl": true,
          "mode": "list",
          "value": "10007",
          "cachedResultName": "Task"
        },
        "additionalFields": {
          "priority": {
            "__rl": true,
            "mode": "list",
            "value": "2",
            "cachedResultName": "High"
          },
          "description": "=Text: {{$json[\"text\"]}}  Sentiment: {{$json[\"sentiment\"]}}  Time: {{$now}}"
        }
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5c93ce3b-ab24-4ece-be4b-dde1fbff02a1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 880,
        "height": 352,
        "content": "## DATA PROCESSING\nSplits input into individual items and sends each text to the Hugging Face model.\nScores are returned and merged with original text for further processing."
      },
      "typeVersion": 1
    },
    {
      "id": "ae9b554b-cf91-41f8-8143-268102b52a7f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        224,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 448,
        "content": "## SENTIMENT LOGIC\nCompares model scores and selects the highest value.\nApplies confidence check to avoid incorrect classification and assigns final sentiment."
      },
      "typeVersion": 1
    },
    {
      "id": "d0ff406b-2090-4ad2-b842-6d581bd9fba0",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        -496
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 736,
        "content": "## STORAGE & ACTION\nRoutes data based on sentiment.\nStores results in Google Sheets and creates Jira tickets for negative feedback."
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "bd87cc34-831d-4d52-861e-6e525fa5d208",
  "connections": {
    "Receive Feedback": {
      "main": [
        [
          {
            "node": "Split Text Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Text Items": {
      "main": [
        [
          {
            "node": "Rate Limit Control",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compute Sentiment": {
      "main": [
        [
          {
            "node": "Route by Sentiment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Jira Ticket": {
      "main": [
        []
      ]
    },
    "Rate Limit Control": {
      "main": [
        [
          {
            "node": "Preserve Input Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Sentiment": {
      "main": [
        [
          {
            "node": "Store Positive Feedback",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Store Neutral Feedback",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Store Negative Feedback",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Text & Scores": {
      "main": [
        [
          {
            "node": "Compute Sentiment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preserve Input Text": {
      "main": [
        [
          {
            "node": "Get Sentiment Scores",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Text & Scores",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Sentiment Scores": {
      "main": [
        [
          {
            "node": "Merge Text & Scores",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Store Neutral Feedback": {
      "main": [
        []
      ]
    },
    "Store Negative Feedback": {
      "main": [
        [
          {
            "node": "Create Jira Ticket",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store Positive Feedback": {
      "main": [
        []
      ]
    }
  }
}