This workflow corresponds to n8n.io template #7067 — we link there as the canonical source.
This workflow follows the Agent → 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "5cba784b-170f-4aa5-861c-1af04f5ecced",
"name": "PrepareForFirstGen - OPM",
"type": "n8n-nodes-base.set",
"position": [
256,
832
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f94c3091-aec9-40ec-a028-f0b15c656042",
"name": "=Original Prompt ID",
"type": "number",
"value": "={{ $json[\"Original Prompt ID\"] }}"
},
{
"id": "ff9f7965-6c0f-416b-8a76-f1c6ee03f5a6",
"name": "chatInput",
"type": "string",
"value": "={{ $json.chatInput }}"
},
{
"id": "2024e446-f2dc-4664-8574-1a6260ce5050",
"name": "=isProcessed",
"type": "boolean",
"value": false
},
{
"id": "801ba818-932c-4ba9-8a30-2db9bb8d7296",
"name": "sessionId",
"type": "number",
"value": 0
},
{
"id": "11c635c0-afad-464b-87cf-a83bddf303b9",
"name": "systemMessage",
"type": "string",
"value": "={{ $json.systemMessage }}"
}
]
}
},
"typeVersion": 3.4,
"alwaysOutputData": false
},
{
"id": "5b32a6db-37a2-4543-893b-6b121f0ac6b9",
"name": "ChatHistory - PM",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
304,
1152
],
"parameters": {
"contextWindowLength": 4
},
"typeVersion": 1.3
},
{
"id": "05a52264-3b2e-4496-b00d-f99fcaccc7e7",
"name": "Qwen3 - PM",
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"position": [
32,
1152
],
"parameters": {
"model": "qwen/qwen3-32b",
"options": {}
},
"credentials": {
"groqApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "2c9db4c8-d635-47ba-8104-f487aa1228d8",
"name": "Gemini - PM",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
160,
1152
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "5efd00fe-369b-4a15-a1d9-261596e59c1e",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
256,
640
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "468c52f0-a7f3-4a20-93b4-a5de341a3163",
"name": "PromptModifer",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
80,
1008
],
"parameters": {
"options": {
"systemMessage": "={{$json.systemMessage}}"
},
"needsFallback": true
},
"typeVersion": 2.1
},
{
"id": "f938cf7e-27c3-42d3-80a8-28dc2450a40e",
"name": "Parse AI Chat",
"type": "n8n-nodes-base.code",
"position": [
400,
1008
],
"parameters": {
"jsCode": "// AI Response Parser for Prompt Refiner Workflow\n// This script parses AI agent output and extracts structured data\n\nconst outputItems = []; // Array to store our final, precisely structured items\n\nfor (const item of items) {\n const inputItem = item.json; // The combined item from the Merge node\n \n // Initialize parsed data with defaults - MOVED OUTSIDE TRY BLOCK\n let parsedData = {\n \"Original Prompt ID\": $getWorkflowStaticData(\"global\")[\"Original Prompt ID\"] || null,\n \"Prompt Title\": \"\",\n \"Topic\": \"\",\n \"Topic Categories\": \"\",\n \"Modified Prompt\": \"ERROR: Could not parse AI response\",\n \"Prompt Type\": \"Error\",\n \"Last Updated\": new Date().toISOString(),\n \"Improvement Notes\": \"\",\n \"Raw AI Output Length\": 0,\n \"Parsing Success\": false,\n \"Operation Counts\": $getWorkflowStaticData(\"global\").opm_counts || 0\n };\n \n try {\n // Get the AI output from the response\n let aiOutput = inputItem.output || inputItem.text || '';\n // console.log(aiOutput)\n parsedData[\"Raw AI Output Length\"] = aiOutput.length;\n \n // Try different methods to extract JSON from AI response\n let jsonData = null;\n \n // Method 1: Look for JSON block between ```json and ```\n const jsonBlockMatch = aiOutput.match(/```json\\s*([\\s\\S]*?)\\s*```/);\n if (jsonBlockMatch) {\n try {\n jsonData = JSON.parse(jsonBlockMatch[1].trim());\n } catch (e) {\n console.log('Failed to parse JSON block:', e.message);\n }\n }\n \n // Method 2: Look for JSON object starting with { and ending with }\n if (!jsonData) {\n const jsonObjectMatch = aiOutput.match(/\\{[\\s\\S]*\\}/);\n if (jsonObjectMatch) {\n try {\n jsonData = JSON.parse(jsonObjectMatch[0]);\n } catch (e) {\n console.log('Failed to parse JSON object:', e.message);\n }\n }\n }\n \n // Method 3: Try to parse the entire output as JSON\n if (!jsonData) {\n try {\n jsonData = JSON.parse(aiOutput.trim());\n } catch (e) {\n console.log('Failed to parse entire output as JSON:', e.message);\n }\n }\n \n // If we successfully parsed JSON, extract the data\n if (jsonData) {\n parsedData[\"sessionId\"] = $('PrepareForFirstGen - OPM').first().json.sessionId\n parsedData[\"Modified Prompt\"] = jsonData.modified_prompt || jsonData.modifiedPrompt || \"ERROR: No modified prompt found\";\n parsedData[\"Prompt Type\"] = jsonData.prompt_type || jsonData.promptType || \"\";\n parsedData[\"Prompt Title\"] = jsonData.prompt_title || jsonData.promptTitle || \"\";\n parsedData[\"Topic\"] = jsonData.topic || jsonData[\"Topic\"] || \"\";\n parsedData[\"Topic Categories\"] = jsonData.topic_categories || jsonData.topicCategory || \"\";\n parsedData[\"Parsing Success\"] = true;\n \n // Extract additional fields\n parsedData[\"Improvement Notes\"] = jsonData.improvement_notes || jsonData.improvementNotes || null;\n \n // If we have a valid modified prompt, change type from Error\n if (parsedData[\"Modified Prompt\"] !== \"ERROR: No modified prompt found\") {\n // Keep the prompt type from JSON, but default to \"Text\" if it's still \"Error\"\n if (parsedData[\"Prompt Type\"] === \"Error\") {\n parsedData[\"Prompt Type\"] = \"Text\";\n }\n } else {\n parsedData[\"Prompt Type\"] = \"Error\";\n }\n } else {\n // If no JSON found, try to extract some basic info from text\n parsedData[\"Modified Prompt\"] = \"ERROR: AI output format unexpected (no JSON block).\";\n parsedData[\"Improvement Notes\"] = \"AI did not respond in expected JSON format. Raw output length: \" + aiOutput.length + \" characters\";\n }\n \n \n } catch (error) {\n // Handle any unexpected errors - parsedData is already defined above\n parsedData[\"Modified Prompt\"] = `ERROR: Parsing failed - ${error.message}`;\n parsedData[\"Prompt Type\"] = \"Error\";\n parsedData[\"Improvement Notes\"] = `Parsing error: ${error.message}`;\n parsedData[\"Parsing Success\"] = false;\n }\n \n outputItems.push(parsedData);\n}\n\nreturn outputItems;"
},
"typeVersion": 2
},
{
"id": "ab9752f1-c69a-43f7-ac14-1a57294d0b6f",
"name": "ExecutionController",
"type": "n8n-nodes-base.code",
"position": [
80,
832
],
"parameters": {
"jsCode": "// Fixed ExecutionController for n8n - Prevents Duplicate AI Executions\n// This code prevents duplicate AI agent executions by tracking processed prompts\n// Fixing loop, proccess twice at the same time, and limiting the number of executions for a single prompt\n\n// Get input data\nconst input = $input.first();\n\n// Check if input is existing and there is json in input\nif (!input || !input.json) {\n throw new Error(\"No input data for AI Agent\");\n}\nconsole.log(\"From OPG - Execution Controller: \\n\", input);\n\n//-------------Global---Variables---Init--------------//\n// Prevent multiple executions\n// Initialize Execution Key use to track if the prompt has already executed.\nconst staticData = $getWorkflowStaticData(\"global\");\nconst promptId = input.json[\"Original Prompt ID\"];\nconst timestamp = new Date().toISOString();\nconst agentKey = `exec_prompt_#${promptId}_${timestamp}`;\nconst EXEC_KEY = \"lastAgentExecutionKey\";\nconst MAX_OPM_COUNTS = staticData.MAX_OPM_COUNTS || 3;\nlet systemMessage = \"\";\nlet opm_counts = staticData.opm_counts || 1;\n\n// 1) Duplicate prevention\n// Check if agent processes the input twice at the time.\nif (staticData[EXEC_KEY] === agentKey) {\n console.log(\"Skipping duplicate AI execution\");\n return [input];\n}\n\nstaticData[EXEC_KEY] = agentKey;\n\n// 2) Track how many times we've run for this prompt\nif (staticData[\"Original Prompt ID\"] === promptId) {\n opm_counts += 1;\n} else {\n staticData[\"Original Prompt ID\"] = promptId;\n opm_counts = 1;\n}\n\nstaticData.opm_counts = opm_counts;\n\n// check if agent processes the same prompt and if it not exeeds opm limits ,meaning: Do not let the OPM Agent run more than 3 times for 1 prompt.\n\n// 4) Now check against your limit\nif (opm_counts > MAX_OPM_COUNTS) {\n throw new Error(\"Exceeded Original Prompt Modifier Limits!\");\n}\nconst buildSystemMessage = () => {\n let message = \"\"\n // Check if from isMissingFields Node, if yes means regenerate with all missing data.\n if (opm_counts > 1) {\n message = `\n# Prompt Regeneration Agent (Retry ${opm_counts}/${MAX_OPM_COUNTS})\n\nYou are handling a REGENERATION task. The previous attempt didn't complete all required fields. Your job is to COMPLETE the missing data while preserving any good existing content.\n\n## CRITICAL REQUIREMENTS\n\u26a0\ufe0f **This is attempt ${opm_counts} of ${MAX_OPM_COUNTS}** - YOU MUST generate ALL fields this time.\n\n## Context Information\n- **Original User Prompt**: {{ $json[\"Original Prompt\"] || $json.chatInput }}\n- **Current Modified Prompt**: {{ $json[\"Modified Prompt\"] || \"None generated yet\" }}\n- **Missing Fields**: {{ JSON.stringify($json[\"Missing Fields\"] || []) }}\n- **Previous Attempt Quality**: {{ $json[\"Previous Quality Score\"] || \"Unknown\" }}\n\n## Your Regeneration Task\n1. **PRESERVE** any existing good content from the current modified prompt\n2. **COMPLETE** all missing fields with high-quality data\n3. **IMPROVE** the overall prompt structure and clarity\n4. **ENSURE** all required fields have meaningful, non-empty values\n5. **FOCUS** on fixing the specific issues from the previous attempt\n\n## Field Requirements (ALL MUST BE COMPLETED)\n- **modified_prompt**: Enhanced, detailed prompt (not empty, not \"Unknown\")\n- **prompt_type**: Exactly one of: Code|Text|Image|Analysis|Creative|Query\n- **prompt_title**: Descriptive, specific title (not generic)\n- **topic**: Clear main subject matter (not vague)\n- **topic_categories**: 2-3 relevant categories, comma-separated\n- **input_variables**: Array of meaningful variable names (if applicable)\n- **improvement_notes**: Specific details about what was enhanced\n\n## Quality Standards\n- **No empty values** - every field must have meaningful content\n- **No generic responses** - be specific and relevant\n- **No \"Unknown\" or error values** - generate real data\n- **Professional quality** - this is the final attempt\n\n## Your Response Format\nYou MUST respond ONLY with a complete JSON object containing ALL fields:\n\n\\`\\`\\`json\n{\n \"modified_prompt\": \"Comprehensive enhanced prompt with all details\",\n \"prompt_type\": \"Choose from: Code|Text|Image|Analysis|Creative|Query\",\n \"prompt_title\": \"Specific, descriptive title\",\n \"topic\": \"Clear, specific main topic\",\n \"topic_categories\": \"Category1, Category2, Category3\",\n \"input_variables\": [\"variable1\", \"variable2\", \"variable3\"],\n \"improvement_notes\": \"Detailed explanation of all enhancements made\"\n}\n\\`\\`\\`\n\n## \u26a0\ufe0f CRITICAL WARNING\nIf you fail to complete ALL fields properly this time, the workflow will terminate with an error. This is your final opportunity to create a complete, high-quality enhanced prompt.\n`;\n } else {\n message = `\n# Prompt Modifier Agent\n\nYou are the first agent in a prompt refinement pipeline. Your job is to take a basic user prompt and enhance it with more details and clarity.\n\n## Your Task\n1. **Analyze** the original prompt for intent and context\n2. **Add specificity** - make vague requests more specific\n3. **Add structure** - break down complex requests into clear steps\n4. **Identify variables** - parts that could be parameterized for reuse\n5. **Maintain intent** - don't change what the user actually wants\n\n## Enhancement Guidelines\n- Add context clues and examples where helpful\n- Specify expected output format if unclear\n- Add relevant constraints or requirements\n- Keep the core request unchanged\n- Make it more actionable and clear\n\n## Your Response Format\nYou MUST respond ONLY with a JSON object:\n\n\\`\\`\\`json\n{\n \"modified_prompt\": \"Enhanced version with more detail and context\",\n \"prompt_type\": \"Code|Text|Image|Analysis|Creative|Query\",\n \"prompt_title\": \"\",\n \"topic\": \"Main topic...\",\n \"topic_categories\": \"Comma-separated categories...\",\"\n \"improvement_notes\": \"What was added/changed\"\n}\n\\`\\`\\`\n\n## Original Prompt:\n{{ $json.chatInput }}\n`;\n }\n return message\n};\n\nsystemMessage = buildSystemMessage()\n\n// \u2705 FIXED: Always return array of objects in proper n8n format\nreturn [\n {\n json: {\n sessionId: input.json.sessionId || 0,\n chatInput: input.json[\"Original Prompt\"] || input.json[\"Modified Prompt\"] || \"\",\n systemMessage: systemMessage,\n isProcessed: input.json.isProcessed || false,\n \"Original Prompt ID\": staticData[\"Original Prompt ID\"],\n opm_counts: opm_counts,\n processedAt: new Date().toISOString(),\n },\n },\n];\n"
},
"typeVersion": 2
},
{
"id": "7f7a76cd-d4a9-4e5f-a800-966ea30c5cc3",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
48
],
"parameters": {
"width": 624,
"height": 512,
"content": "## \ud83e\udd16 AI-Powered Prompt Enhancement Assistant using Google Sheets\n### \u26a1 Quick Demo\n**Input**: \"Create a marketing strategy\" \n**Output**: \"Develop a comprehensive digital marketing strategy for a [business_type] targeting [target_audience]. Include market analysis, channel selection, budget allocation, timeline, and KPIs. Focus on [primary_goals] and consider [constraints].\"\n### \ud83d\udcca What You Get\n\u2705 Enhanced prompts with clear structure \n\u2705 Extracted input variables for reusability \n\u2705 Topic classification and categories \n\u2705 Professional improvement notes \n\u2705 Complete audit trail in Google Sheets\n### \ud83c\udfac Perfect For\n- Content creation workflows\n- AI chatbot prompt optimization \n- Marketing copy enhancement\n- Technical documentation prompts\n- Educational prompt examples\n---\n\ud83d\udca1 **Ready to transform your prompts?** Follow the setup steps in the white notes below!\u2b07\ufe0f"
},
"typeVersion": 1
},
{
"id": "6d1e6e53-2ca4-4c58-bc99-14adcf38978c",
"name": "Send Success Message To User",
"type": "n8n-nodes-base.telegram",
"position": [
496,
640
],
"parameters": {
"text": "=\ud83e\udd16 **Prompt Refiner Complete!** \n\n\u2705 **\"{{ $('Create/Upate Modified Prompt').item.json['Prompt Title'] }}\"**\n\n\ud83d\udcdd **Topic**: {{ $('Create/Upate Modified Prompt').item.json.Topic }} \n\n\ud83c\udff7\ufe0f **Type**: {{ $('Create/Upate Modified Prompt').item.json['Prompt Type'] }} \n\n\ud83c\udfaf **Categories**: {{ $('Create/Upate Modified Prompt').item.json['Topic Categories'] }} \n\n\ud83d\udea8**Enhanced Prompt Preview:** {{ $('Create/Upate Modified Prompt').item.json['Modified Prompt'].substring(0, 150) }}... \n\n\u26a1 **Processed by**: {{ $('Create/Upate Modified Prompt').item.json['Model Used'] }} \n\n\ud83d\udd52 **Completed**: {{ $now.toFormat('HH:mm') }} View full results in your Google Sheet! \ud83d\udcca",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "0ea36662-9d9f-4fe2-97e3-a4d22b10a518",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
592
],
"parameters": {
"color": 5,
"width": 624,
"height": 736,
"content": "## \ud83d\udee0\ufe0f STEP-BY-STEP SETUP GUIDE\n### 1\ufe0f\u20e3 Create Google Sheets (5 minutes)\nCreate a new Google Spreadsheet with 2 tabs:\n\n**\ud83d\udccaMain Sheet** (Input prompts):\n- Columns: Original Prompt ID | Model | Original Prompt | Created Time\n**\ud83d\udcddModified Prompt Sheet** (Results):\n- Columns: Modified Prompt ID | Original Prompt ID | Topic | Topic Categories | Modified Prompt | Prompt Title | Prompt Type | Model Used | Improvement Notes | Updated Time | Created Time | isProcessed\n\n### 2\ufe0f\u20e3 Configure n8n Credentials\nAdd these in **Settings > Credentials**:\n- Gemini API credential\n- Telegram API credential \n- Groq API credential\n- Google Sheets OAuth2 credential\n\n### 3\ufe0f\u20e3 Update Workflow Settings\n- Replace ALL Google Sheets node **Document IDs** with your spreadsheet ID\n- Update **Chat ID** in Telegram node (optional notification)\n- Test API connections in each AI Chat node\n\n### 4\ufe0f\u20e3 Test Your Setup\n1. Add test prompt to Main sheet: \"Explain machine learning\"\n2. Run workflow manually\n3. Check ModifiedPrompt sheet for results\n4. Monitor Logging sheet for any errors\n\n\u2705 **Setup complete!** Your workflow will now process prompts automatically every minute."
},
"typeVersion": 1
},
{
"id": "afeb8497-4ec5-4891-8a9b-17305058c33c",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"color": 5,
"width": 624,
"height": 512,
"content": "## \ud83d\udd04 WORKFLOW FLOW EXPLAINED\n### \ud83d\udce5 **INPUT STAGE**\n**Google Sheets Trigger** \u2192 **Loop Over Items** \u2192 **ProcessController**\n- Processes one prompt at a time to prevent overload\n- Sets up global variables for execution tracking\n### \ud83e\udd16 **AI ENHANCEMENT STAGE** \n**ExecutionController** \u2192 **PromptModifier (AI Agent)** \u2192 **Parse AI Chat**\n- **Gemini / Groq AI** analyzes and enhances basic prompts\n- **Smart parsing** extracts JSON data with 3 fallback methods\n### \u2705 **QUALITY ASSURANCE STAGE**\n**isMissingFields** \u2192 **Finalize Data** \u2192 **Create/Update Google Sheets** \u2192 **Telegram Notification**\n- **Validates** all required fields are complete and accurate\n- **Formats** final data structure for storage\n- **Stores** enhanced prompt with full metadata\n- **Notifies** user via Telegram with result summary\n### \ud83d\udee1\ufe0f **ERROR HANDLING**\n- **Execution limits** prevent infinite loops (max 3 OPM)\n- **Graceful fallbacks** handle API failures and parsing errors"
},
"typeVersion": 1
},
{
"id": "d4e42dd5-59b6-4599-b572-deb9b2ef078d",
"name": "Finalize ModifiedPrompt DataModel",
"type": "n8n-nodes-base.set",
"position": [
736,
816
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f6605c6c-29ff-4916-ac5a-1b0f3fe6dc86",
"name": "Original Prompt ID",
"type": "string",
"value": "={{ $json[\"Original Prompt ID\"] }}"
},
{
"id": "24a66be5-64d9-4700-b05d-c01f1cae58e5",
"name": "isProcessed",
"type": "boolean",
"value": true
},
{
"id": "52150325-d494-4898-8564-1e38a7edeea7",
"name": "Prompt Title",
"type": "string",
"value": "={{ $json[\"Prompt Title\"] }}"
},
{
"id": "2c2a145b-2d97-44ae-8eae-32a6e1f3b45c",
"name": "Topic",
"type": "string",
"value": "={{ $json.Topic }}"
},
{
"id": "ed392bfe-04cb-4f90-819b-23d0a8dc3b80",
"name": "Topic Categories",
"type": "string",
"value": "={{ $json[\"Topic Categories\"] }}"
},
{
"id": "a2eb11e6-9aae-4b44-9c11-c3bf02313557",
"name": "Modified Prompt",
"type": "string",
"value": "={{ $json[\"Modified Prompt\"] }}"
},
{
"id": "5a8f69aa-5026-4435-8dc0-6cd2ac99bd80",
"name": "Prompt Type",
"type": "string",
"value": "={{ $json[\"Prompt Type\"] }}"
},
{
"id": "03510c85-ccc8-4237-a3a7-508d00eaf2e6",
"name": "Last Updated",
"type": "string",
"value": "={{ $now.toISO() }}"
},
{
"id": "ed43101a-4553-4233-8eab-8db63673833d",
"name": "Improvement Notes",
"type": "string",
"value": "={{ $json[\"Improvement Notes\"] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "3dc0613c-39e1-4034-bffb-a797090e8cd7",
"name": "Send Exceed Limits Error",
"type": "n8n-nodes-base.telegram",
"position": [
736,
1136
],
"parameters": {
"text": "=\u274c **PromptRefiner Processing Failed**\n\n**Prompt ID**: {{ $('GetNewPrompt').item.json['Original Prompt ID'] }}\n**Original Prompt**: \"{{ $('GetNewPrompt').item.json['Original Prompt'].substring(0, 80) }}...\"\n\n\ud83d\udd04 **Issue**: Maximum retry attempts reached (3/3)\n\ud83d\udca1 **Reason**: AI agents couldn't complete all required fields after multiple attempts\n\n**What happened:**\nOur system tried 3 times to enhance your prompt but encountered persistent issues with field completion. This might be due to:\n\u2022 Complex or unclear original prompt\n\u2022 AI service temporary limitations\n\u2022 Missing context information\n\n**Next steps:**\n\u2705 Try rephrasing your prompt more clearly\n\u2705 Check if your prompt has sufficient detail\n\u2705 Wait a few minutes and try again\n\u2705 Contact support if issue persists\n\n\ud83d\udccb **Check your Google Sheets Logging tab for detailed error information**\n\n\u23f0 **Failed at**: {{ $now.toFormat('HH:mm') }}",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "0a9c62fe-e25a-4eba-94f5-21fe0210bef2",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
544
],
"parameters": {
"color": 7,
"width": 1152,
"height": 784,
"content": "## Main Workflow"
},
"typeVersion": 1
},
{
"id": "f01a9c3a-5a44-45b8-b762-25fabf960cb0",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1184,
480
],
"parameters": {
"color": 5,
"width": 608,
"height": 848,
"content": "## \ud83d\udd27 CUSTOMIZATION OPTIONS\n### \ud83c\udfa8 **Modify AI Behavior**\n- **Change AI prompts**: Edit system messages in ExecutionController nodes\n- **Custom enhancement logic**: Update Code nodes with your rules\n### \ud83d\udcca **Add Custom Fields**\n- **Custom validation**: Modify field checking logic \n- **Extended output**: Add columns to Google Sheets + parsing logic\n### \u2699\ufe0f **Performance Tuning**\n- **Retry limits**: Change MAX_OPM_COUNTS (default: 3)\n- **Processing speed**: Adjust polling interval in Google Sheets Trigger\n- **Batch size**: Modify Loop Over Items batch settings\n---\n\n## \ud83e\ude7a TROUBLESHOOTING\n### \u274c **Common Issues**\n- **\"Workflow keeps running infinitely\"** \n\u2192 Check Eorkflow's logs for stuck executions, disable Loop Over Items temporarily\n\n- **\"AI agent returns ERROR responses\"** \n\u2192 Verify API credentials, check rate limits, review system prompts\n\n- **\"Missing fields not generated\"** \n\u2192 Ensure EmptyFieldsExtractor code matches your field names exactly\n\n- **\"Google Sheets sync issues\"** \n\u2192 Refresh OAuth tokens, verify spreadsheet permissions\n### \ud83d\udccb **Debug Checklist**\n\u2705 All API credentials valid and connected \n\u2705 Google Sheets Document IDs updated correctly \n\u2705 Spreadsheet has all 2 required tabs with correct column names \n\u2705 Test prompts added to Main sheet follow the expected format \n### \ud83d\udca1 **Performance Tips** \n- Monitor API usage to avoid rate limits\n- Set up error alerts via Telegram notifications\n- Regular cleanup of old execution logs"
},
"typeVersion": 1
},
{
"id": "6bc3e24c-5a3d-4aa3-a53e-3a9f106bd72d",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
576,
992
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "allDatavalid",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "95bda34b-9a58-4039-b520-0d6088619481",
"operator": {
"type": "boolean",
"operation": "false",
"singleValue": true
},
"leftValue": "={{ \n (\n !$json[\"Original Prompt ID\"] ||\n !$json[\"Topic\"] || \n !$json[\"Prompt Title\"] || \n !$json[\"Topic Categories\"] || \n !$json[\"Prompt Type\"] || \n !$json[\"Improvement Notes\"]\n ) && \n ($json[\"Operation Counts\"] <= 2)\n}}\n",
"rightValue": 1
}
]
},
"renameOutput": true
},
{
"outputKey": "missingData",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "ee181ecc-a353-4209-8dab-9da3fa775481",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ (!$json[\"Original Prompt ID\"] || !$json[\"Topic\"] || !$json[\"Prompt Title\"] || !$json[\"Topic Categories\"] || !$json[\"Prompt Type\"] || !$json[\"Improvement Notes\"]) && ($json[\"Operation Counts\"] <= 2) }}",
"rightValue": ""
}
]
},
"renameOutput": true
},
{
"outputKey": "exceedLimits",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "a2b258da-c5c6-4258-89a4-fdb749c7aeef",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json[\"Operation Counts\"] }}",
"rightValue": 3
}
]
},
"renameOutput": true
}
]
},
"options": {},
"looseTypeValidation": true
},
"typeVersion": 3.2
},
{
"id": "e9fd333b-8539-44f4-83a7-124ada5cda92",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
128
],
"parameters": {
"width": 496,
"height": 384,
"content": "## \ud83d\ude4f Thank You for Trying This Workflow\n\nYour time and trust mean a lot, I truly appreciate you giving Prompt Refiner a try.\n\nYour feedback is the key to making this project better, more effective, and more useful for everyone. \nIf you have:\n- Suggestions for improvement\n- Ideas for new features\n- Requests for other automation workflows\n\nPlease share them with me! Every idea helps shape the next update.\n\n**Thank you again for being part of this journey.**\n**Author:** EoCi Mr.Eo\n"
},
"typeVersion": 1
},
{
"id": "92aaabd8-5ac0-487a-a0c9-ab0da3c9eca4",
"name": "GetNewPrompt",
"type": "n8n-nodes-base.googleSheetsTrigger",
"position": [
80,
640
],
"parameters": {
"options": {
"columnsToWatch": [
"Original Prompt ID",
"Original Prompt"
]
},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultUrl": "",
"cachedResultName": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"credentials": {
"googleSheetsTriggerOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "58c627e9-93ed-418a-88bd-4fece09a5098",
"name": "Workflow Complete",
"type": "n8n-nodes-base.noOp",
"position": [
928,
992
],
"parameters": {},
"typeVersion": 1
},
{
"id": "a341fc41-09ac-476b-8e48-cee26225d7eb",
"name": "Exit By Error",
"type": "n8n-nodes-base.noOp",
"position": [
928,
1136
],
"parameters": {},
"typeVersion": 1
},
{
"id": "fc51bff6-74a6-40bc-819d-a78870b639e8",
"name": "Successfully Sent Message To User",
"type": "n8n-nodes-base.noOp",
"position": [
720,
640
],
"parameters": {},
"typeVersion": 1
},
{
"id": "ec7116f8-87f8-472d-a3d7-b9e6b1a851d1",
"name": "Create/Upate Modified Prompt",
"type": "n8n-nodes-base.googleSheets",
"position": [
928,
816
],
"parameters": {
"columns": {
"value": {
"Topic": "={{ $json.Topic }}",
"Model Used": "Gemini Pro 2.5",
"Prompt Type": "={{ $json[\"Prompt Type\"] }}",
"isProcessed": "={{ $json[\"Parsing Success\"] }}",
"Created Time": "={{ $now.toISO() }}",
"Prompt Title": "={{ $json[\"Prompt Title\"] }}",
"Updated Time": "={{ $json[\"Last Updated\"] }}",
"Modified Prompt": "={{ $json[\"Modified Prompt\"] }}",
"Topic Categories": "={{ $json[\"Topic Categories\"] }}",
"Improvement Notes": "={{ $json[\"Improvement Notes\"] }}",
"Original Prompt ID": "={{ $json[\"Original Prompt ID\"] }}"
},
"schema": [
{
"id": "Modified Prompt ID",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Modified Prompt ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Original Prompt ID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Original Prompt ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "isProcessed",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "isProcessed",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Topic",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Topic",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Topic Categories",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Topic Categories",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Modified Prompt",
"type": "string",
"display": true,
"required": false,
"displayName": "Modified Prompt",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Prompt Title",
"type": "string",
"display": true,
"required": false,
"displayName": "Prompt Title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Prompt Type",
"type": "string",
"display": true,
"required": false,
"displayName": "Prompt Type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Input Variables",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Input Variables",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Model Used",
"type": "string",
"display": true,
"required": false,
"displayName": "Model Used",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Improvement Notes",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Improvement Notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Updated Time",
"type": "string",
"display": true,
"required": false,
"displayName": "Updated Time",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Created Time",
"type": "string",
"display": true,
"required": false,
"displayName": "Created Time",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Original Prompt ID"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1751172685,
"cachedResultUrl": "https://docs.google.YOUR_AWS_SECRET_KEY_HERE-a7JsxHtFswS4_phjIv_wSA/edit#gid=1751172685",
"cachedResultName": "ModifiedPrompt"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
}
],
"connections": {
"Switch": {
"main": [
[
{
"node": "Finalize ModifiedPrompt DataModel",
"type": "main",
"index": 0
}
],
[
{
"node": "ExecutionController",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Exceed Limits Error",
"type": "main",
"index": 0
}
]
]
},
"Qwen3 - PM": {
"ai_languageModel": [
[
{
"node": "PromptModifer",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Gemini - PM": {
"ai_languageModel": [
[
{
"node": "PromptModifer",
"type": "ai_languageModel",
"index": 1
}
]
]
},
"GetNewPrompt": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Parse AI Chat": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"PromptModifer": {
"main": [
[
{
"node": "Parse AI Chat",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Send Success Message To User",
"type": "main",
"index": 0
}
],
[
{
"node": "ExecutionController",
"type": "main",
"index": 0
}
]
]
},
"ChatHistory - PM": {
"ai_memory": [
[
{
"node": "PromptModifer",
"type": "ai_memory",
"index": 0
}
]
]
},
"ExecutionController": {
"main": [
[
{
"node": "PrepareForFirstGen - OPM",
"type": "main",
"index": 0
}
]
]
},
"PrepareForFirstGen - OPM": {
"main": [
[
{
"node": "PromptModifer",
"type": "main",
"index": 0
}
]
]
},
"Send Exceed Limits Error": {
"main": [
[
{
"node": "Exit By Error",
"type": "main",
"index": 0
}
]
]
},
"Create/Upate Modified Prompt": {
"main": [
[
{
"node": "Workflow Complete",
"type": "main",
"index": 0
}
]
]
},
"Send Success Message To User": {
"main": [
[
{
"node": "Successfully Sent Message To User",
"type": "main",
"index": 0
}
]
]
},
"Finalize ModifiedPrompt DataModel": {
"main": [
[
{
"node": "Create/Upate Modified Prompt",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googlePalmApigoogleSheetsOAuth2ApigoogleSheetsTriggerOAuth2ApigroqApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
Source: https://n8n.io/workflows/7067/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This automation is designed to help you generate AI-powered music tracks, cover art, and fully rendered music videos — all triggered from a simple Telegram chat and managed via Google Sheets.
This workflow is designed for marketers, content creators, agencies, and solo founders who want to publish long‑form posts with visuals on autopilot using n8n and AI agents.
BoomerBobBot.TP. Uses agent, telegramTrigger, telegram, memoryBufferWindow. Event-driven trigger; 95 nodes.
This workflow is for beauty salons who want consistent, high‑quality social media content without writing every post manually. It also suits agencies and automation builders who manage multiple beauty
> AI-powered nutrition assistant for Telegram — log meals, set goals, and get personalized daily reports with Google Sheets integration.