Étiquetage et analyse automatiques des retours clients dans Google Sheets avec OpenAI
Ceci est unMarket Research, AI Summarizationworkflow d'automatisation du domainecontenant 24 nœuds.Utilise principalement des nœuds comme Set, Code, Merge, GoogleSheets, ManualTrigger. Traitement groupé des retours clients dans Google Sheets, avec analyse de sentiment et émotion
- •Informations d'identification Google Sheets API
- •Clé API OpenAI
Nœuds utilisés (24)
Catégorie
{
"id": "vt26lV2qI3OlOvin",
"meta": {
"instanceId": "a970479b9b937d4c4802e373a8116e0d4e6c86989709fbee9c5a38c7f63fd033"
},
"name": "Auto-tag and analyze customer feedback in Google Sheets with OpenAI",
"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": "Au clic sur 'Exécuter le workflow'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
1616,
288
],
"parameters": {},
"typeVersion": 1
},
{
"id": "d9064168-bf99-4066-89a7-0dbe19c8f3ae",
"name": "Récupérer les tags autorisés",
"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": "Récupérer les nouveaux retours",
"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": "Fusionner tags et retours",
"type": "n8n-nodes-base.merge",
"position": [
3136,
720
],
"parameters": {
"mode": "chooseBranch"
},
"typeVersion": 2.1
},
{
"id": "086461e1-dc56-412a-a073-740af265b83e",
"name": "Joindre le tableau de tags",
"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": "Marquer les retours avec l'IA",
"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": "Mettre à jour la feuille Google (marquée)",
"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": "Traiter les retours par lots",
"type": "n8n-nodes-base.splitInBatches",
"position": [
3936,
848
],
"parameters": {
"options": {},
"batchSize": "=10"
},
"typeVersion": 3
},
{
"id": "12824491-a5d8-42ba-b602-5ad577d0108c",
"name": "Agréger les éléments du lot",
"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": "Diviser les résultats du lot",
"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": "Note adhésive",
"type": "n8n-nodes-base.stickyNote",
"position": [
640,
16
],
"parameters": {
"width": 768,
"height": 976,
"content": "## 💬 **Auto-tag customer feedback in Google Sheets with OpenAI sentiment analysis**\n\nThis workflow automatically tags user feedback stored in Google Sheets using OpenAI with sentiment and emotion analysis. \nIt reads new feedback, analyzes them in **batches** with a single AI call, and returns relevant tags with detailed insights.\n\n---\n\n### 🧠 What It Does\n- Fetches **allowed tags** from a Tags Sheet \n- Reads **new feedback** (Status = empty) from a Feedbacks Sheet \n- **Sends entire batches (e.g., 10 items) to OpenAI as a single request** 🚀\n- Returns up to **3 most relevant tags** from allowed list (or AI-generated tags as fallback)\n- Analyzes **sentiment** (Very Negative to Very Positive)\n- Detects **emotions** (primary & secondary feelings)\n- Writes all results back to Google Sheets (tags, sentiment, emotions, status, timestamp)\n\n---\n\n### 🚀 How to Set Up \n1. Duplicate the provided [Google Sheet template](https://docs.google.com/spreadsheets/d/1y7B3u5vgQLDidf-NdfPgAiBuQxP9Qa7RvdgsTPG14Fs/edit?usp=sharing).\n2. Connect your **Google Sheets** and **OpenAI** credentials in n8n. \n3. Update the Sheet URLs in the **Fetch Allowed Tags**, **Fetch New Feedbacks**, and **Update Google Sheet** nodes. \n4. Run manually with the **Manual Trigger** or enable the **Schedule Trigger** (runs every 60 minutes). \n\n---\n\n### 🎨 How to Customize \n- Adjust the **System Prompt** in the \"Tag Feedbacks with AI\" node to change tagging rules. \n- Edit the **batch size** (default: 10) in the \"Process Feedbacks in Batches\" node for performance optimization. \n- Change the **schedule interval** in the \"Schedule Trigger\" node (default: 60 minutes). \n- Extend the workflow to send results to Notion, Slack, or Airtable for real-time reporting.\n\n---\n\n#### 💡 Example Use Case\nIdeal for product and research teams who collect customer feedback and want to categorize it automatically into clear, actionable topics with sentiment and emotional insights."
},
"typeVersion": 1
},
{
"id": "22e35300-b79f-4b21-b2fb-47ee274141e2",
"name": "Déclencheur planifié",
"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": "Note adhésive 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2240,
80
],
"parameters": {
"color": 4,
"width": 560,
"height": 352,
"content": "### 🏷️ **Fetch Allowed Tags**\n\nReads the list of available tag names from your **Tags Sheet**. \nEach tag is stored in an array and later passed to OpenAI as `allowed_tags`.\n\n✅ Make sure your Tags sheet has a single column named `Tags`."
},
"typeVersion": 1
},
{
"id": "cc4985d4-7dfd-4efb-965c-125f3ed881c9",
"name": "Note adhésive 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2256,
672
],
"parameters": {
"color": 4,
"width": 560,
"height": 656,
"content": "## 💬 **Fetch New Feedbacks**\n\nReads feedback entries from **Feedbacks Sheet** where `Status` is empty.\n\n### Expected Columns\n- **Feedbacks:** The feedback text\n- **Status:** Empty = new | \"Updated\" = tagged | \"Needs Review\" = no tags found\n- **Tag 1, Tag 2, Tag 3:** Up to 3 tags from allowed list\n- **AI Tag 1, AI Tag 2:** Fallback tags when no allowed tags match\n- **Sentiment:** Very Negative to Very Positive\n- **Primary Emotion:** Dominant feeling (e.g., frustration, gratitude)\n- **Secondary Emotion:** Optional secondary feeling\n- **Updated Date (N8N):** Processing timestamp\n\n✅ All columns must exist with exact names."
},
"typeVersion": 1
},
{
"id": "f91dc3c9-4fc3-4f78-8cc2-f0e4a777d2e5",
"name": "Note adhésive 4",
"type": "n8n-nodes-base.stickyNote",
"position": [
4656,
544
],
"parameters": {
"color": 6,
"width": 448,
"height": 480,
"content": "## 🤖 **Tag Feedbacks with OpenAI**\n\nSends entire batch (10 items) as ONE OpenAI request. 🚀\n\n**Output per feedback:**\n- Up to 3 tags from allowed_tags (preferred)\n- Up to 2 AI-generated tags (fallback only)\n- Sentiment: Very Negative to Very Positive\n- Primary & secondary emotions\n- Multilingual support (including Persian/Farsi)\n\n✅ Returns valid JSON array."
},
"typeVersion": 1
},
{
"id": "a8f0f7a3-2c1a-4e8f-a2f0-295cf7332b24",
"name": "Note adhésive 5",
"type": "n8n-nodes-base.stickyNote",
"position": [
5648,
656
],
"parameters": {
"color": 4,
"width": 336,
"height": 576,
"content": "## 📊 **Update Google Sheet (Tagged)**\n\nUpdates **Feedbacks Sheet** with:\n- `Tag 1-3` (from allowed list)\n- `AI Tag 1-2` (fallback tags)\n- `Sentiment`\n- `Primary Emotion` & `Secondary Emotion`\n- `Status` (\"Updated\" or \"Needs Review\")\n- `Updated Date (N8N)`\n\n✅ Ensure columns exist with exact names."
},
"typeVersion": 1
},
{
"id": "1a484a39-d4ad-4bb5-8a91-81aea0b218f1",
"name": "Note adhésive 6",
"type": "n8n-nodes-base.stickyNote",
"position": [
3840,
544
],
"parameters": {
"color": 7,
"width": 320,
"height": 480,
"content": "## 🔁 **Split In Batches**\n\nBreaks large feedback lists into smaller batches to avoid API rate limits. \nAfter each batch is processed, the loop continues automatically until all rows are tagged.\n\n💡 Default batch size = 10 (you can adjust in config sheet)."
},
"typeVersion": 1
},
{
"id": "e97af0f1-1446-4c9a-9363-cb2674a1d211",
"name": "Note adhésive 7",
"type": "n8n-nodes-base.stickyNote",
"position": [
3040,
368
],
"parameters": {
"color": 7,
"width": 320,
"height": 512,
"content": "## 🔗 **Merge Tags & Feedbacks**\n\nThis node combines two input streams:\n- **Input 1:** Feedback items fetched from the Feedbacks Sheet \n- **Input 2:** Allowed tag list fetched from the Tags Sheet \n\nMode: `Choose Branch` \nOutput: Keeps Feedback data (Input 1) while waiting for Tags (Input 2) to arrive. \nEnsures each feedback item can access the full tag list before analysis."
},
"typeVersion": 1
},
{
"id": "20a6d6be-273c-48db-9a53-6dab6a0d6318",
"name": "Note adhésive 8",
"type": "n8n-nodes-base.stickyNote",
"position": [
3440,
544
],
"parameters": {
"color": 7,
"width": 320,
"height": 336,
"content": "## 🧩 **Attach Tags Array**\n\nAdds the list of tags from the Tags Sheet to each feedback item. \nThe result includes a field named `tags`, used by OpenAI for tagging."
},
"typeVersion": 1
},
{
"id": "640e7cd5-b2a8-4b5e-9b38-4b0e6f7f583a",
"name": "Note adhésive 9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
80
],
"parameters": {
"color": 7,
"width": 352,
"height": 368,
"content": "## 🖱️ **Manual Trigger**\n\nRuns the workflow manually when you click **\"Execute Workflow\"** inside n8n. \nUse this for quick testing or when setting up new credentials and connections.\n\n💡 Best for testing small batches before enabling the automatic schedule."
},
"typeVersion": 1
},
{
"id": "d9ac75a8-f4e1-463b-83ce-2c41519f38c3",
"name": "Note adhésive 10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
656
],
"parameters": {
"color": 7,
"width": 352,
"height": 336,
"content": "## ⏰ **Schedule Trigger**\n\nRuns every **60 minutes** automatically.\n\nProcesses all feedback where Status = empty/blank."
},
"typeVersion": 1
},
{
"id": "9a24cb7c-fd3b-4e74-ab5c-95457d2658c3",
"name": "Note adhésive 11",
"type": "n8n-nodes-base.stickyNote",
"position": [
6032,
1152
],
"parameters": {
"width": 336,
"height": 80,
"content": "**Created by:** [Parhum Khoshbakht](https://www.linkedin.com/in/parhumm/)\nProduct Manager & Leadership Coach"
},
"typeVersion": 1
},
{
"id": "fe170993-5489-4cbf-9489-bd622ca646a3",
"name": "Note adhésive 12",
"type": "n8n-nodes-base.stickyNote",
"position": [
4224,
544
],
"parameters": {
"color": 7,
"width": 336,
"height": 480,
"content": "## 📦 **Aggregate Batch Items**\n\n**Collects all feedback items in the current batch and combines them into a single item.**\n\nThis allows us to send all 10 feedbacks (or configured batch size) as ONE request to OpenAI instead of 10 separate requests.\n\n💰 **Cost savings:** ~90% reduction in API calls!"
},
"typeVersion": 1
},
{
"id": "0ba2d396-07e4-45b5-aebd-7b2b23758630",
"name": "Note adhésive 13",
"type": "n8n-nodes-base.stickyNote",
"position": [
5200,
560
],
"parameters": {
"color": 7,
"width": 336,
"height": 448,
"content": "## 🔀 **Split Batch Results**\n\n**Parses the OpenAI response and splits it back into individual feedback items.**\n\nEach item contains:\n- `row_number`: To match with the original Google Sheet row\n- `tags`: Array of tag names (up to 3)\n- `sentiment`: Sentiment classification\n\nThese items are then sent to the Google Sheet update node one by one."
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "4213cde2-0655-4e7a-ad52-47b312aacb8c",
"connections": {
"22e35300-b79f-4b21-b2fb-47ee274141e2": {
"main": [
[
{
"node": "d9064168-bf99-4066-89a7-0dbe19c8f3ae",
"type": "main",
"index": 0
},
{
"node": "7f0ee6a9-cfd1-449d-96c7-5dcd180fc152",
"type": "main",
"index": 0
}
]
]
},
"086461e1-dc56-412a-a073-740af265b83e": {
"main": [
[
{
"node": "1234a97c-f663-454c-abd7-9e64b3098ef4",
"type": "main",
"index": 0
}
]
]
},
"d9064168-bf99-4066-89a7-0dbe19c8f3ae": {
"main": [
[
{
"node": "dcf3888e-b2f4-4d35-acc2-48798368aee2",
"type": "main",
"index": 1
}
]
]
},
"7f0ee6a9-cfd1-449d-96c7-5dcd180fc152": {
"main": [
[
{
"node": "dcf3888e-b2f4-4d35-acc2-48798368aee2",
"type": "main",
"index": 0
}
]
]
},
"54ebf56d-27ec-411d-9973-10a717921e47": {
"main": [
[
{
"node": "ac43582f-ba7e-4941-91d1-e48ecb7e1944",
"type": "main",
"index": 0
}
]
]
},
"12824491-a5d8-42ba-b602-5ad577d0108c": {
"main": [
[
{
"node": "bce8aee5-89f5-423c-89f9-b6b0705a3d50",
"type": "main",
"index": 0
}
]
]
},
"bce8aee5-89f5-423c-89f9-b6b0705a3d50": {
"main": [
[
{
"node": "54ebf56d-27ec-411d-9973-10a717921e47",
"type": "main",
"index": 0
}
]
]
},
"dcf3888e-b2f4-4d35-acc2-48798368aee2": {
"main": [
[
{
"node": "086461e1-dc56-412a-a073-740af265b83e",
"type": "main",
"index": 0
}
]
]
},
"1234a97c-f663-454c-abd7-9e64b3098ef4": {
"main": [
[],
[
{
"node": "12824491-a5d8-42ba-b602-5ad577d0108c",
"type": "main",
"index": 0
}
]
]
},
"ac43582f-ba7e-4941-91d1-e48ecb7e1944": {
"main": [
[
{
"node": "1234a97c-f663-454c-abd7-9e64b3098ef4",
"type": "main",
"index": 0
}
]
]
},
"20d919c3-088c-4748-bf11-31a8f1490c24": {
"main": [
[
{
"node": "d9064168-bf99-4066-89a7-0dbe19c8f3ae",
"type": "main",
"index": 0
},
{
"node": "7f0ee6a9-cfd1-449d-96c7-5dcd180fc152",
"type": "main",
"index": 0
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Avancé - Étude de marché, Résumé IA
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
Partager ce workflow