AutomationFlowsAI & RAG › Sentiment Analytics Visualizer

Sentiment Analytics Visualizer

ByFranz @agents-by-franz on n8n.io

Google Sheets → OpenAI GPT-4o → QuickChart → Gmail Fetches customer reviews from a Google Sheet. Classifies each review as Positive, Neutral or Negative with GPT-4o-mini. Writes the sentiment back to your sheet. Builds a doughnut chart summarising the totals. Emails the chart to…

Event trigger★★★★☆ complexityAI-powered14 nodesSentiment AnalysisOpenAI ChatGoogle SheetsQuick ChartGmail
AI & RAG Trigger: Event Nodes: 14 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #5204 — we link there as the canonical source.

This workflow follows the Gmail → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "4BOP29RhumejWZ6r",
  "name": "Sentiment Analyzer",
  "tags": [],
  "nodes": [
    {
      "id": "cb616bea-a6ad-4864-8169-9b0c24868761",
      "name": "\ud83d\udccb Setup Instructions",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -300,
        40
      ],
      "parameters": {
        "width": 400,
        "height": 460,
        "content": "## \ud83d\udccb SETUP REQUIRED\n\n**This workflow requires the following configurations:**\n\n1. **Google Sheets Connection**: Update all Google Sheets nodes with your spreadsheet ID\n2. **OpenAI API**: Add your OpenAI API credentials\n3. **Gmail Account**: Configure Gmail OAuth2 for email notifications\n4. **Email Recipient**: Update the email address in the Gmail node\n\n**Expected Sheet Structure:**\n- Column A: Review title\n- Column B: Review text\n- Column C: Sentiment (will be populated by workflow)\n\n**Before running:** Make sure your Google Sheet has the columns 'Review title' and 'Review text' with your data."
      },
      "typeVersion": 1
    },
    {
      "id": "da05ebb8-6027-43d9-8c56-42d33d6d5f78",
      "name": "\ud83d\udd27 Configure Google Sheets",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        300,
        -160
      ],
      "parameters": {
        "width": 300,
        "height": 340,
        "content": "## \ud83d\udd27 CUSTOMIZE THIS NODE\n\n**Google Sheets Configuration:**\n1. Replace the documentId with your Google Sheets ID\n2. Select the correct sheet name\n3. Ensure your sheet has 'Review title' and 'Review text' columns\n\n**To get your Sheet ID:**\n- Copy from URL: docs.google.com/spreadsheets/d/[SHEET_ID]/edit"
      },
      "typeVersion": 1
    },
    {
      "id": "a07f32b5-1f38-4f61-b2c4-1e91b0df9512",
      "name": "\ud83e\udd16 Configure OpenAI",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        740
      ],
      "parameters": {
        "width": 420,
        "height": 200,
        "content": "## \ud83e\udd16 CUSTOMIZE THIS NODE\n\n**OpenAI Configuration:**\n1. Add your OpenAI API credentials\n2. Model is set to gpt-4o-mini (cost-effective)\n3. You can change to gpt-4o for higher accuracy\n\n**Required:** Valid OpenAI API key with sufficient credits"
      },
      "typeVersion": 1
    },
    {
      "id": "370277f5-8a80-4dc8-aff8-f025d6123356",
      "name": "\ud83d\udce7 Configure Gmail",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1520,
        -60
      ],
      "parameters": {
        "width": 340,
        "height": 220,
        "content": "## \ud83d\udce7 CUSTOMIZE THIS NODE\n\n**Gmail Configuration:**\n1. Replace email address with your recipient\n2. Configure Gmail OAuth2 credentials\n3. Customize email subject and message\n\n**Current recipient:** [YOUR_EMAIL_HERE]"
      },
      "typeVersion": 1
    },
    {
      "id": "bccef3f8-801b-421a-8865-00064fc313f2",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        620,
        200
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "76118dc2-c52d-4a1a-aba2-981a62d4a28a",
      "name": "Sentiment Analysis",
      "type": "@n8n/n8n-nodes-langchain.sentimentAnalysis",
      "position": [
        820,
        360
      ],
      "parameters": {
        "options": {
          "categories": "Positive, Neutral, Negative",
          "enableAutoFixing": true,
          "systemPromptTemplate": "You are highly intelligent and accurate sentiment analyzer. Analyze the sentiment of the provided text. Categorize it into one of the following: {categories}. Use the provided formatting instructions. Only output the JSON.",
          "includeDetailedResults": false
        },
        "inputText": "=Title: {{ $json['Review title'] }}\nText: {{ $json['Review text'] }}"
      },
      "retryOnFail": false,
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "c34c8c45-fd8e-4cef-8156-6a5658c48c46",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        820,
        540
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "7bd27f43-9207-40f4-9c6a-bea0be03a6fc",
      "name": "When clicking 'Test workflow'",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        180,
        200
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "c2c21691-fd21-4afe-a60d-08c6399372e5",
      "name": "Select Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        400,
        200
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "REPLACE_WITH_YOUR_GOOGLE_SHEETS_ID",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit",
          "cachedResultName": "Your Customer Reviews Sheet"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "4a4b2f78-d043-4853-980d-f24c3f5139dd",
      "name": "Update Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1180,
        520
      ],
      "parameters": {
        "columns": {
          "value": {
            "Sentiment": "={{ $json.sentimentAnalysis.category }}"
          },
          "schema": [
            {
              "id": "Review title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Review title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Review text",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Review text",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sentiment",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Sentiment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sentimentAnalysis",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "sentimentAnalysis",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "cellFormat": "USER_ENTERED"
        },
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "REPLACE_WITH_YOUR_GOOGLE_SHEETS_ID",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit",
          "cachedResultName": "Your Customer Reviews Sheet"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "e8af1018-02ea-4961-be63-4ac7e0b2db4a",
      "name": "Read Data from Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        980,
        180
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "REPLACE_WITH_YOUR_GOOGLE_SHEETS_ID",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit",
          "cachedResultName": "Your Customer Reviews Sheet"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.5
    },
    {
      "id": "58cfddb4-cc28-451a-a4ec-f8d391c7b198",
      "name": "Extract Number of Answers per Sentiment",
      "type": "n8n-nodes-base.code",
      "position": [
        1200,
        180
      ],
      "parameters": {
        "jsCode": "const comments = $input.all();\nlet sentimentCount = { Positive: 0, Negative: 0, Neutral: 0 };\n\ncomments.forEach((comment) => {\n  const sentiment = comment?.json?.sentimentAnalysis;\n  if (sentiment.includes(\"Positive\")) {\n    sentimentCount.Positive++;\n  } else if (sentiment.includes(\"Negative\")) {\n    sentimentCount.Negative++;\n  } else if (sentiment.includes(\"Neutral\")) {\n    sentimentCount.Neutral++;\n  }\n});\n\nreturn {\n  labels: [\"Positive\", \"Neutral\", \"Negative\"],\n  values: [\n    sentimentCount.Positive,\n    sentimentCount.Neutral,\n    sentimentCount.Negative,\n  ],\n};\n"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "fa766ee4-8dff-44cd-b2a5-9c2f079ab160",
      "name": "Generate QuickChart",
      "type": "n8n-nodes-base.quickChart",
      "position": [
        1380,
        180
      ],
      "parameters": {
        "data": "={{ $json.values }}",
        "output": "=data",
        "labelsMode": "array",
        "labelsArray": "={{ $json.labels }}",
        "chartOptions": {},
        "datasetOptions": {}
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "952e3afc-c5a3-4faf-92e1-a467399bc7c8",
      "name": "Send Gmail with Sentiment Chart",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1600,
        180
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=Dear Team,\n\nPlease find attached the sentiment analysis summary of recent customer reviews.\n\nBest regards,\nAutomated Sentiment Analysis System",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          }
        },
        "subject": "Sentiment Analysis Summary",
        "emailType": "text"
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "894d1878-53b7-4efd-a542-b2851424e27c",
  "connections": {
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Read Data from Google Sheet",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sentiment Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Sentiment Analysis",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Sentiment Analysis": {
      "main": [
        [
          {
            "node": "Update Google Sheet",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Google Sheet",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate QuickChart": {
      "main": [
        [
          {
            "node": "Send Gmail with Sentiment Chart",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Google Sheet": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Google Sheet": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Data from Google Sheet": {
      "main": [
        [
          {
            "node": "Extract Number of Answers per Sentiment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking 'Test workflow'": {
      "main": [
        [
          {
            "node": "Select Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Number of Answers per Sentiment": {
      "main": [
        [
          {
            "node": "Generate QuickChart",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Google Sheets → OpenAI GPT-4o → QuickChart → Gmail Fetches customer reviews from a Google Sheet. Classifies each review as Positive, Neutral or Negative with GPT-4o-mini. Writes the sentiment back to your sheet. Builds a doughnut chart summarising the totals. Emails the chart to…

Source: https://n8n.io/workflows/5204/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Eliminate 90% of manual work in procurement by automating quote requests, response tracking, price extraction, and supplier follow-ups. This complete automation handles everything from sending persona

Gmail, Google Sheets, Information Extractor +2
AI & RAG

This n8n template demonstrates how to automate email classification, labeling, draft generation, and logging using Gmail, OpenAI, and Google Sheets. Use cases include customer support management, sale

Gmail Trigger, Gmail, Text Classifier +4
AI & RAG

Transform your Gmail sent folder into a comprehensive, enriched contact database automatically. This workflow processes hundreds or thousands of sent emails, extracting and enriching contact informati

HTTP Request, @Brave/N8N Nodes Brave Search, Gmail +3
AI & RAG

Author: CSChin Example Source: https://www.ncl.ac.uk/singapore/staff/profile/chengchin.html#publications

HTTP Request, OpenAI Chat, Form Trigger +3
AI & RAG

Detects new unread Gmail messages Extracts sender name for personalized replies Classifies the email into one of four categories Applies the correct Gmail label and either sends an auto-reply, creates

Gmail Trigger, OpenAI Chat, Gmail +4