使用 OpenAI 自动标记和分析 Google Sheets 中的客户反馈
高级
这是一个Market Research, AI Summarization领域的自动化工作流,包含 24 个节点。主要使用 Set, Code, Merge, GoogleSheets, ManualTrigger 等节点。 在 Google Sheets 中批量处理客户反馈,进行情感和情绪分析
前置要求
- •Google Sheets API 凭证
- •OpenAI API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "vt26lV2qI3OlOvin",
"meta": {
"instanceId": "a970479b9b937d4c4802e373a8116e0d4e6c86989709fbee9c5a38c7f63fd033"
},
"name": "使用 OpenAI 自动标记和分析 Google Sheets 中的客户反馈",
"tags": [
{
"id": "GCoQbohMyJ7ZU01a",
"name": "Customer Support",
"createdAt": "2025-10-18T17:05:33.588Z",
"updatedAt": "2025-10-18T17:05:33.588Z"
},
{
"id": "nNjwOWFKi8QHbVYy",
"name": "User Experience",
"createdAt": "2025-10-18T17:05:19.693Z",
"updatedAt": "2025-10-18T17:05:19.693Z"
}
],
"nodes": [
{
"id": "20d919c3-088c-4748-bf11-31a8f1490c24",
"name": "当点击\"执行工作流\"时",
"type": "n8n-nodes-base.manualTrigger",
"position": [
1616,
288
],
"parameters": {},
"typeVersion": 1
},
{
"id": "d9064168-bf99-4066-89a7-0dbe19c8f3ae",
"name": "获取允许的标签",
"type": "n8n-nodes-base.googleSheets",
"position": [
2464,
272
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Tags"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "=GOOGLE_SHEETS_URL"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "YOUR_CREDENTIAL_ID",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "7f0ee6a9-cfd1-449d-96c7-5dcd180fc152",
"name": "获取新反馈",
"type": "n8n-nodes-base.googleSheets",
"position": [
2464,
1152
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupColumn": "Status"
}
]
},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Feedbacks"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "=GOOGLE_SHEETS_URL"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "YOUR_CREDENTIAL_ID",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "dcf3888e-b2f4-4d35-acc2-48798368aee2",
"name": "合并标签和反馈",
"type": "n8n-nodes-base.merge",
"position": [
3136,
720
],
"parameters": {
"mode": "chooseBranch"
},
"typeVersion": 2.1
},
{
"id": "086461e1-dc56-412a-a073-740af265b83e",
"name": "附加标签数组",
"type": "n8n-nodes-base.set",
"position": [
3552,
736
],
"parameters": {
"values": {
"string": [
{
"name": "tags",
"value": "={{ $items('Fetch Allowed Tags').map(i => i.json['Tags']) }}"
}
]
},
"options": {}
},
"typeVersion": 2
},
{
"id": "bce8aee5-89f5-423c-89f9-b6b0705a3d50",
"name": "使用 AI 标记反馈",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
4784,
880
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "=You are a tagging, sentiment, and emotion analysis assistant. \n\nInput format:\n- You will receive multiple feedbacks in an array under `feedbacks`.\n- Each feedback item has: `row_number` and `text`.\n- Feedback text may be multilingual (e.g., Persian/Farsi). Analyze natively.\n- You will also receive an `allowed_tags` array (may be empty).\n\nGeneral rules:\n- Analyze each feedback independently.\n- Detect and describe emotional tone naturally.\n- Identify one **primary emotion** that captures the dominant feeling.\n- Optionally include up to two **secondary emotions** that reflect additional nuances.\n- Output must be a **valid JSON array** only, with **no extra text** before or after.\n- Maintain the original input order.\n\n⚠️ CRITICAL TAGGING RULES (2-tier system with STRONG preference for allowed_tags):\n\n**TIER 1: ALWAYS TRY ALLOWED TAGS FIRST (Your Primary Responsibility)**\n- If `allowed_tags` is provided, you MUST thoroughly examine it for matches.\n- **Be creative and flexible in matching:**\n - Look for direct matches (e.g., \"Bug\" for bug reports)\n - Look for semantic matches (e.g., \"Payment\" tag for \"billing issue\" feedback)\n - Look for category matches (e.g., \"Performance\" for \"slow\", \"lag\", \"loading\")\n - Look for broader themes (e.g., \"User Experience\" for usability complaints)\n- **Think broadly:** A tag doesn't need to be a perfect word-for-word match.\n- Consider the **intent and topic** of the feedback, not just exact keywords.\n- Return up to **3** most relevant tags from `allowed_tags` (sorted by relevance).\n- **Only proceed to Tier 2 if you genuinely cannot find ANY relevant match** after careful analysis.\n\n**TIER 2: AI-Generated Tags (ONLY as a last resort)**\n- Use this ONLY when:\n - `allowed_tags` is completely empty, OR\n - After thorough analysis, absolutely NO tag in `allowed_tags` relates to the feedback topic\n- Generate up to **2 custom, descriptive tags** (short labels like \"UI Bug\", \"Pricing Question\").\n- Put these in `ai_tag_1` and `ai_tag_2`.\n- Use \"\" for empty AI tag fields.\n\n**Decision Flow:**\n1. Read the feedback carefully\n2. Review ALL allowed_tags thoroughly\n3. Can you match any tag semantically or thematically? → YES = Use allowed tags, set ai_tag_1=\"\", ai_tag_2=\"\"\n4. Still no match after careful review? → Use AI tags as fallback\n\nSentiment scale (choose one):\n[\"Very Negative\", \"Negative\", \"Neutral\", \"Positive\", \"Very Positive\"].\n\nEmotions:\n- primary_emotion: one clear emotional label (e.g., \"anger\", \"hope\", \"disappointment\", \"relief\", \"satisfaction\", \"gratitude\").\n- secondary_emotion: optional supporting emotional state (e.g., \"frustration\", \"trust\", \"curiosity\", \"anxiety\"). Use \"\" if none applies.\n\nResponse JSON schema (use exactly these keys):\n[\n {\n \"row_number\": <row_number from input>,\n \"tags\": [\"tag_from_allowed_list_1\", \"tag_from_allowed_list_2\"],\n \"ai_tag_1\": \"\",\n \"ai_tag_2\": \"\",\n \"sentiment\": \"Positive\",\n \"primary_emotion\": \"Gratitude\",\n \"secondary_emotion\": \"Relief\"\n }\n]\n\nExamples of GOOD matching behavior:\n✅ Feedback: \"The app crashes constantly\" + allowed_tags: [\"Bug\", \"Stability\", \"Feature\"] → tags: [\"Bug\", \"Stability\"]\n✅ Feedback: \"Can't complete checkout\" + allowed_tags: [\"Payment\", \"Technical Issue\", \"UI\"] → tags: [\"Payment\", \"Technical Issue\"]\n✅ Feedback: \"Love the new design!\" + allowed_tags: [\"Design\", \"Positive Feedback\", \"UI\"] → tags: [\"Design\", \"Positive Feedback\"]\n✅ Feedback: \"Too expensive for what it offers\" + allowed_tags: [\"Pricing\", \"Value\", \"Feature Request\"] → tags: [\"Pricing\", \"Value\"]\n\nExamples of when to use AI tags:\n❌ Feedback: \"Bug in login\" + allowed_tags: [] → tags: [], ai_tag_1: \"Authentication Bug\", ai_tag_2: \"Login\"\n❌ Feedback: \"Need dark mode\" + allowed_tags: [\"Pricing\", \"Support\", \"Payment\"] → tags: [], ai_tag_1: \"Feature Request\", ai_tag_2: \"UI Customization\"\n\nConstraints:\n- **STRONGLY PREFER allowed_tags** - exhaust all matching possibilities first\n- Do **not** invent tags in the `tags` array — only use exact names from `allowed_tags`\n- Generate creative tags for `ai_tag_1` and `ai_tag_2` ONLY when truly necessary\n- Use ASCII keys exactly as shown. Values must be strings or arrays of strings\n- Do not include reasoning, markdown, or comments — **JSON array only**"
},
{
"content": "={{ JSON.stringify({\n allowed_tags: $json.tags,\n feedbacks: $json.feedbackBatch\n}) }}"
}
]
}
},
"credentials": {
"openAiApi": {
"id": "YOUR_CREDENTIAL_ID",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "ac43582f-ba7e-4941-91d1-e48ecb7e1944",
"name": "更新 Google 表格(已标记)",
"type": "n8n-nodes-base.googleSheets",
"position": [
5760,
1024
],
"parameters": {
"columns": {
"value": {
"Tag 1": "={{ $json.tags[0] || ''}}",
"Tag 2": "={{ $json.tags[1] || ''}}",
"Tag 3": "={{ $json.tags[2] || ''}}",
"Status": "={{ $json.tags && $json.tags.length > 0 ? 'Updated' : 'Needs Review' }}",
"AI Tag 1": "={{ $json.ai_tag_1 }}",
"AI Tag 2": "={{ $json.ai_tag_2 }}",
"Sentiment": "={{ $json.sentiment }}",
"row_number": "={{ $json.row_number }}",
"Primary Emotion": "={{ $json.primary_emotion }}",
"Secondary Emotion": "={{ $json.secondary_emotion }}",
"Updated Date (N8N)": "={{ new Date().toISOString().split('T')[0] }}"
},
"schema": [
{
"id": "Sentiment",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Sentiment",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Feedbacks",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Feedbacks",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Tag 1",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Tag 1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Tag 2",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Tag 2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Tag 3",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Tag 3",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "AI Tag 1",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "AI Tag 1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "AI Tag 2",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "AI Tag 2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Primary Emotion",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Primary Emotion",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Secondary Emotion",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Secondary Emotion",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Updated Date (N8N)",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Updated Date (N8N)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"row_number"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "=Feedbacks"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "=GOOGLE_SHEETS_URL"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "YOUR_CREDENTIAL_ID",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "1234a97c-f663-454c-abd7-9e64b3098ef4",
"name": "批量处理反馈",
"type": "n8n-nodes-base.splitInBatches",
"position": [
3936,
848
],
"parameters": {
"options": {},
"batchSize": "=10"
},
"typeVersion": 3
},
{
"id": "12824491-a5d8-42ba-b602-5ad577d0108c",
"name": "聚合批次项目",
"type": "n8n-nodes-base.code",
"position": [
4352,
864
],
"parameters": {
"jsCode": "// Aggregate all items in the current batch into a single item\nconst feedbackBatch = $input.all().map((item, index) => ({\n id: index,\n row_number: item.json.row_number,\n text: item.json.Feedbacks\n}));\n\nconst tags = $input.first().json.tags;\n\nreturn {\n json: {\n feedbackBatch,\n tags\n }\n};"
},
"typeVersion": 2
},
{
"id": "54ebf56d-27ec-411d-9973-10a717921e47",
"name": "拆分批次结果",
"type": "n8n-nodes-base.code",
"position": [
5312,
864
],
"parameters": {
"jsCode": "// Parse the OpenAI response and split it back into individual items\nconst response = JSON.parse($input.first().json.message.content);\n\n// Handle both array format and object with results property\nconst results = Array.isArray(response) ? response : response.results || [];\n\nreturn results.map(result => ({\n json: {\n row_number: result.row_number,\n tags: result.tags || [],\n sentiment: result.sentiment || \"\",\n ai_tag_1: result.ai_tag_1 || \"\",\n ai_tag_2: result.ai_tag_2 || \"\",\n primary_emotion: result.primary_emotion || \"\",\n secondary_emotion: result.secondary_emotion || \"\"\n }\n}));"
},
"typeVersion": 2
},
{
"id": "3240b804-444e-42ce-b594-166a7f41db4f",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
640,
16
],
"parameters": {
"width": 768,
"height": 976,
"content": "## 💬 **使用 OpenAI 情感分析自动标记 Google Sheets 中的客户反馈**"
},
"typeVersion": 1
},
{
"id": "22e35300-b79f-4b21-b2fb-47ee274141e2",
"name": "由 Github 模型提供支持",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
1600,
832
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 60
}
]
}
},
"typeVersion": 1.2
},
{
"id": "beb9af83-71d0-4cf1-8c33-3d891564d0ba",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2240,
80
],
"parameters": {
"color": 4,
"width": 560,
"height": 352,
"content": "### 🏷️ **获取允许的标签**"
},
"typeVersion": 1
},
{
"id": "cc4985d4-7dfd-4efb-965c-125f3ed881c9",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2256,
672
],
"parameters": {
"color": 4,
"width": 560,
"height": 656,
"content": "## 💬 **获取新反馈**"
},
"typeVersion": 1
},
{
"id": "f91dc3c9-4fc3-4f78-8cc2-f0e4a777d2e5",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
4656,
544
],
"parameters": {
"color": 6,
"width": 448,
"height": 480,
"content": "## 🤖 **使用 OpenAI 标记反馈**"
},
"typeVersion": 1
},
{
"id": "a8f0f7a3-2c1a-4e8f-a2f0-295cf7332b24",
"name": "便签5",
"type": "n8n-nodes-base.stickyNote",
"position": [
5648,
656
],
"parameters": {
"color": 4,
"width": 336,
"height": 576,
"content": "## 📊 **更新 Google 表格(已标记)**"
},
"typeVersion": 1
},
{
"id": "1a484a39-d4ad-4bb5-8a91-81aea0b218f1",
"name": "### 需要帮助?",
"type": "n8n-nodes-base.stickyNote",
"position": [
3840,
544
],
"parameters": {
"color": 7,
"width": 320,
"height": 480,
"content": "## 🔁 **分批处理**"
},
"typeVersion": 1
},
{
"id": "e97af0f1-1446-4c9a-9363-cb2674a1d211",
"name": "## 试试看!",
"type": "n8n-nodes-base.stickyNote",
"position": [
3040,
368
],
"parameters": {
"color": 7,
"width": 320,
"height": 512,
"content": "## 🔗 **合并标签和反馈**"
},
"typeVersion": 1
},
{
"id": "20a6d6be-273c-48db-9a53-6dab6a0d6318",
"name": "GET 模型",
"type": "n8n-nodes-base.stickyNote",
"position": [
3440,
544
],
"parameters": {
"color": 7,
"width": 320,
"height": 336,
"content": "## 🧩 **附加标签数组**"
},
"typeVersion": 1
},
{
"id": "640e7cd5-b2a8-4b5e-9b38-4b0e6f7f583a",
"name": "## 1. 创建新的自定义 OpenAI 凭据",
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
80
],
"parameters": {
"color": 7,
"width": 352,
"height": 368,
"content": "## 🖱️ **手动触发器**"
},
"typeVersion": 1
},
{
"id": "d9ac75a8-f4e1-463b-83ce-2c41519f38c3",
"name": "便签10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
656
],
"parameters": {
"color": 7,
"width": 352,
"height": 336,
"content": "## ⏰ **计划触发器**"
},
"typeVersion": 1
},
{
"id": "9a24cb7c-fd3b-4e74-ab5c-95457d2658c3",
"name": "便签 11",
"type": "n8n-nodes-base.stickyNote",
"position": [
6032,
1152
],
"parameters": {
"width": 336,
"height": 80,
"content": "**创建者:** [Parhum Khoshbakht](https://www.linkedin.com/in/parhumm/)"
},
"typeVersion": 1
},
{
"id": "fe170993-5489-4cbf-9489-bd622ca646a3",
"name": "便签 12",
"type": "n8n-nodes-base.stickyNote",
"position": [
4224,
544
],
"parameters": {
"color": 7,
"width": 336,
"height": 480,
"content": "## 📦 **聚合批次项目**"
},
"typeVersion": 1
},
{
"id": "0ba2d396-07e4-45b5-aebd-7b2b23758630",
"name": "便签 13",
"type": "n8n-nodes-base.stickyNote",
"position": [
5200,
560
],
"parameters": {
"color": 7,
"width": 336,
"height": 448,
"content": "## 🔀 **拆分批次结果**"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "4213cde2-0655-4e7a-ad52-47b312aacb8c",
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Fetch Allowed Tags",
"type": "main",
"index": 0
},
{
"node": "Fetch New Feedbacks",
"type": "main",
"index": 0
}
]
]
},
"Attach Tags Array": {
"main": [
[
{
"node": "Process Feedbacks in Batches",
"type": "main",
"index": 0
}
]
]
},
"Fetch Allowed Tags": {
"main": [
[
{
"node": "Merge Tags & Feedbacks",
"type": "main",
"index": 1
}
]
]
},
"Fetch New Feedbacks": {
"main": [
[
{
"node": "Merge Tags & Feedbacks",
"type": "main",
"index": 0
}
]
]
},
"Split Batch Results": {
"main": [
[
{
"node": "Update Google Sheet (Tagged)",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Batch Items": {
"main": [
[
{
"node": "Tag Feedbacks with AI",
"type": "main",
"index": 0
}
]
]
},
"Tag Feedbacks with AI": {
"main": [
[
{
"node": "Split Batch Results",
"type": "main",
"index": 0
}
]
]
},
"Merge Tags & Feedbacks": {
"main": [
[
{
"node": "Attach Tags Array",
"type": "main",
"index": 0
}
]
]
},
"Process Feedbacks in Batches": {
"main": [
[],
[
{
"node": "Aggregate Batch Items",
"type": "main",
"index": 0
}
]
]
},
"Update Google Sheet (Tagged)": {
"main": [
[
{
"node": "Process Feedbacks in Batches",
"type": "main",
"index": 0
}
]
]
},
"When clicking 'Execute workflow'": {
"main": [
[
{
"node": "Fetch Allowed Tags",
"type": "main",
"index": 0
},
{
"node": "Fetch New Feedbacks",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 市场调研, AI 摘要总结
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
广告分析
基于GPT-4和Gemini AI对比的Meta广告效果分析
If
Set
Code
+10
25 节点Kirill Khatkevich
市场调研
源发现 - 自动搜索更及时的信息源
多平台源发现系统,集成 SerpAPI、DuckDuckGo、GitHub、Reddit 和 Bluesky
Set
Code
Limit
+18
68 节点Hybroht
市场调研
使用 Bright Data API 和 AI 抓取分析 Google 广告并发送邮件报告
使用 Bright Data API 和 AI 抓取分析 Google 广告并发送邮件报告
Set
Code
Gmail
+15
45 节点Zacharia Kimotho
市场调研
每周SEO监控清单审计至Google Sheets(使用Gemini和Decodo)
每周SEO监控清单审计至Google Sheets(使用Gemini和Decodo)
Set
Code
Merge
+9
19 节点Fahmi Fahreza
市场调研
潜在客户开发与邮件工作流
使用Google Maps、SendGrid和AI自动化B2B潜在客户开发与邮件营销
If
Set
Code
+21
141 节点Ezema Kingsley Chibuzo
潜在客户开发
每日 WhatsApp 群组智能分析:GPT-4.1 分析与语音消息转录
每日 WhatsApp 群组智能分析:GPT-4.1 分析与语音消息转录
If
Set
Code
+20
52 节点Daniel Lianes
杂项