AutomationFlowsAI & RAG › Generate Social Content Pillars, Calendars and Posts Using Google Sheets and…

Generate Social Content Pillars, Calendars and Posts Using Google Sheets and…

Original n8n title: Generate Social Content Pillars, Calendars and Posts Using Google Sheets and Openai

ByAvkash Kakdiya @itechnotion on n8n.io

This workflow turns a single planning row in Google Sheets into a fully structured content engine. It generates weighted content pillars, builds a rule-based posting calendar, and then creates publish-ready social posts using AI. The workflow strictly controls format routing,…

Event trigger★★★★☆ complexityAI-powered18 nodesGoogle Sheets TriggerGoogle SheetsOpenAI
AI & RAG Trigger: Event Nodes: 18 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Google Sheets → Googlesheetstrigger 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": "AO3VyGvES7FYXDiP",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Smart Content Calendar Orchestration Workflow",
  "tags": [],
  "nodes": [
    {
      "id": "04b04cd0-3c4e-41ba-9f4c-0e0f5547220a",
      "name": "Google Sheets Trigger",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "position": [
        928,
        416
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyHour"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "your_google_sheet_id_here",
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        },
        "includeInOutput": "both"
      },
      "typeVersion": 1
    },
    {
      "id": "5b9976be-a203-4a5d-9fb9-f5cb4e3938a8",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1136,
        416
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "your_google_sheet_id_here",
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "e86df2d7-2b26-4987-93e1-be9e37f664ef",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1968,
        416
      ],
      "parameters": {
        "columns": {
          "value": {
            "Platform": "={{ $json.Platform }}",
            "Weight (%)": "={{ $json[\"Weight (%)\"] }}",
            "CTA Allowed": "={{ $json[\"CTA Allowed\"] }}",
            "Pillar Name": "={{ $json[\"Pillar Name\"] }}",
            "Allowed Formats": "={{ $json[\"Allowed Formats\"] }}",
            "Primary Purpose": "={{ $json[\"Primary Purpose\"] }}"
          },
          "schema": [
            {
              "id": "Pillar Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Pillar Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Primary Purpose",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Primary Purpose",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Platform",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Platform",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Weight (%)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Weight (%)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Allowed Formats",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Allowed Formats",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "CTA Allowed",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "CTA Allowed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 467688910,
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "your_google_sheet_id_here",
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "f97be825-9e96-48a1-88a1-d974eb7f6af4",
      "name": "Append row in sheet6",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2896,
        416
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $json.Date }}",
            "Sr No": "={{ $json[\"Sr No\"] }}",
            "Format": "={{ $json.Format }}",
            "Status": "={{ $json.Status }}",
            "CTA Type": "={{ $json[\"CTA Type\"] }}",
            "Platform": "={{ $json.Platform }}",
            "Pillar ID": "={{ $json[\"Pillar ID\"] }}",
            "Hook Angle": "={{ $json[\"Hook Angle\"] }}",
            "Post Intent": "={{ $json[\"Post Intent\"] }}"
          },
          "schema": [
            {
              "id": "Sr No",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sr No",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Platform",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Platform",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pillar ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Pillar ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Format",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Format",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Post Intent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Post Intent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Hook Angle",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Hook Angle",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "CTA Type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "CTA Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1387629362,
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "your_google_sheet_id_here",
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "0e032038-22f4-4e44-a92f-7d7a7fa67de6",
      "name": "Switch By Format",
      "type": "n8n-nodes-base.switch",
      "position": [
        3104,
        416
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "811ebd09-8ccb-460a-8f73-77f2e5291aab",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.Format }}",
                    "rightValue": "Video"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "f48fef92-01ed-4518-a669-6731d5dd09bd",
                    "operator": {
                      "type": "string",
                      "operation": "notEquals"
                    },
                    "leftValue": "={{ $json.Format }}",
                    "rightValue": "Video"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "b6661718-aba7-4fd9-8259-43e2aa2dc390",
      "name": "Append row in sheet7",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4112,
        448
      ],
      "parameters": {
        "columns": {
          "value": {
            "CTA": "={{ $json.CTA }}",
            "Date": "={{ $json.Date }}",
            "Sr No": "={{ $json[\"Sr No\"] }}",
            "Hashtags": "={{ $json.Hashtags }}",
            "Main Content": "={{ $json[\"Main Content\"] }}",
            "Hook (Option 1)": "={{ $json[\"Hook Option 1\"] }}",
            "Hook (Option 2)": "={{ $json[\"Hook Option 2\"] }}",
            "Platform Variant": "={{ $json[\"Platform Variant\"] }}"
          },
          "schema": [
            {
              "id": "Sr No",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sr No",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Hook (Option 1)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Hook (Option 1)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Hook (Option 2)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Hook (Option 2)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Main Content",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Main Content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "CTA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "CTA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Hashtags",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Hashtags",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Platform Variant",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Platform Variant",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1093465678,
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "your_google_sheet_id_here",
          "cachedResultUrl": "your-google_sheet_url_here",
          "cachedResultName": "your_google_sheet_name_here"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "954ccf90-59c9-4cbe-a0b5-fc6204c78b22",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        3344,
        432
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "c98a8083-86f6-4557-852d-35f8592ff1fc",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        4320,
        448
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "47209c08-feea-468f-aab3-5e05b19a36ef",
      "name": "Message a model",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1360,
        416
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "GPT-4O"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "role": "system",
              "content": "=You are an expert content strategy architect and marketing automation specialist.\n\nYOUR ROLE:\n- Generate content calendar calculations and platform-specific content pillars\n- Follow strict calculation rules and validation logic\n- Output only valid JSON with no explanations or markdown\n\nCORE RESPONSIBILITIES:\n1. Normalize and validate all input data\n2. Execute calendar calculations deterministically\n3. Generate platform-specific content pillars\n4. Ensure all outputs are production-ready and sheet-compatible\n\nCRITICAL RULES YOU MUST FOLLOW:\n- Output ONLY valid JSON (no code fences, no markdown, no explanations)\n- All Weight (%) values per platform MUST sum to exactly 100\n- Create pillars ONLY for resolved platforms (never invent platforms)\n- Educational content MUST dominate unless Promotion Level is High\n- Pillar names must be concise (2-4 words), actionable, and brand-appropriate\n- Never invent data\u2014use only provided inputs\n- Handle platform resolution strictly:\n  * \"LinkedIn\" \u2192 [\"LinkedIn\"]\n  * \"Instagram\" \u2192 [\"Instagram\"]\n  * \"Both\" \u2192 [\"LinkedIn\", \"Instagram\"]\n\nOUTPUT STRUCTURE:\n{\n  \"calculations\": {\n    \"totalWeeks\": <number>,\n    \"totalPostsPerPlatform\": <number>,\n    \"postsPerWeek\": <number>,\n    \"promotionalPostsPerWeek\": <number>,\n    \"educationalPostsPerWeek\": <number>,\n    \"promotionalRatio\": <decimal>\n  },\n  \"platforms\": [\"<platform1>\", \"<platform2>\"],\n  \"contentPillars\": [\n    {\n      \"pillar_name\": \"<name>\",\n      \"description\": \"<purpose>\",\n      \"pillar_type\": \"<Educational|Promotional|Engagement|Thought Leadership>\",\n      \"Weight (%)\": <number>,\n      \"CTA Allowed\": \"<Yes|Soft|No>\",\n      \"platform\": \"<LinkedIn|Instagram>\"\n    }\n  ],\n  \"metadata\": {\n    \"brandName\": \"<input>\",\n    \"industry\": \"<input>\",\n    \"contentGoal\": \"<input>\",\n    \"tone\": \"<input>\",\n    \"startDate\": \"<YYYY-MM-DD>\",\n    \"endDate\": \"<YYYY-MM-DD>\"\n  }\n}"
            },
            {
              "content": "=TASK: Calculate content calendar metrics and generate platform-specific content pillars for the following brand.\n\nCALCULATION REQUIREMENTS:\n\n1. Time Calculations:\n   - totalWeeks = CEIL(Duration (Days) \u00f7 7)\n   - endDate = Start Date + Duration (Days)\n\n2. Volume Calculations:\n   - postsPerWeek = Posting Frequency / Week\n   - totalPostsPerPlatform = postsPerWeek \u00d7 totalWeeks\n\n3. Platform Resolution:\n   - IF Platform = \"LinkedIn\" \u2192 platforms = [\"LinkedIn\"]\n   - IF Platform = \"Instagram\" \u2192 platforms = [\"Instagram\"]\n   - IF Platform = \"Both\" \u2192 platforms = [\"LinkedIn\", \"Instagram\"]\n\n4. Content Mix:\n   - Promotional Ratio:\n     * \"Low\" = 0.20 (20%)\n     * \"Medium\" = 0.35 (35%)\n     * \"High\" = 0.50 (50%)\n   \n   - promotionalPostsPerWeek = MIN(postsPerWeek \u00d7 promotionalRatio, Max Promo Posts / Week)\n   - educationalPostsPerWeek = MAX(postsPerWeek - promotionalPostsPerWeek, Min Educational Posts / Week)\n\nCONTENT PILLAR GENERATION:\nFor EACH resolved platform, create 3-5 content pillars:\n\nPILLAR STRUCTURE:\n- pillar_name: Short, memorable name (2-4 words)\n- description: Clear primary purpose (1 sentence)\n- pillar_type: \"Educational\", \"Promotional\", \"Engagement\", or \"Thought Leadership\"\n- Weight (%): Percentage of total posts (must sum to 100% per platform)\n- CTA Allowed: \"Yes\" (hard CTA), \"Soft\" (subtle), or \"No\"\n- platform: The specific platform this pillar is for\n\nPILLAR DISTRIBUTION RULES:\n- Educational pillars: 60-80% for Low promotion, 50-65% for Medium, 40-50% for High\n- Include at least 1 promotional pillar if Max Promo Posts / Week > 0\n- Pillars must be distinct, non-overlapping, and industry-relevant\n- Weights must be whole numbers summing to exactly 100%\n\nPLATFORM-SPECIFIC CONSIDERATIONS:\n\nLinkedIn:\n- Focus: Professional development, industry insights, thought leadership\n- Educational: How-to guides, case studies, industry trends\n- Promotional: Service showcases, success stories, testimonials\n\nInstagram:\n- Focus: Visual storytelling, behind-the-scenes, lifestyle\n- Educational: Quick tips, infographics, carousel tutorials\n- Promotional: Product features, offers, user-generated content\n\n---\n\nINPUT DATA:\nBrand Name: {{ $json['Brand Name'] }}\nIndustry: {{ $json['Industry'] }}\nPlatform: {{ $json['Platform'] }}\nTarget Audience: {{ $json['Target Audience'] }}\nContent Goal: {{ $json['Content Goal'] }}\nTone: {{ $json['Tone'] }}\n\nStart Date: {{ $json['Start Date'] }}\nDuration (Days): {{ $json['Duration (Days)'] }}\nPosting Frequency / Week: {{ $json['Posting Frequency / Week'] }}\n\nPromotion Level: {{ $json['Promotion Level'] }}\nMax Promo Posts / Week: {{ $json['Max Promo Posts / Week'] }}\nMin Educational Posts / Week: {{ $json['Min Educational Posts / Week'] }}\nCTA Cooldown (Days): {{ $json['CTA Cooldown (Days)'] }}\n\nMax Same Pillar Streak: {{ $json['Max Same Pillar Streak'] }}\n\n---\n\nExecute the calculations and generate the content pillars. Return ONLY the JSON response."
            }
          ]
        },
        "builtInTools": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "3b4e1674-7265-4203-8ffe-14580272a447",
      "name": "Message a model6",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        3568,
        448
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "GPT-4O"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "role": "system",
              "content": "=You are an expert social media content creator and copywriter specializing in B2B SaaS and marketing automation. You excel at creating platform-optimized, engagement-driven content that balances education with conversion.\n\nYOUR ROLE:\n- Generate complete, platform-ready post content based on calendar entries\n- Write compelling hooks that stop the scroll and drive engagement\n- Create educational yet actionable main content\n- Craft CTAs that feel natural and align with the content pillar\n- Suggest relevant, high-performing hashtags\n\nCORE RESPONSIBILITIES:\n1. Generate TWO distinct hook options for A/B testing\n2. Write complete main content (not outlines or placeholders)\n3. Include platform-specific formatting recommendations\n4. Create CTAs that match the specified type (None/Soft/Hard)\n5. Select hashtags based on platform and industry relevance\n6. Output ONLY valid JSON with no markdown or explanations\n\nCRITICAL RULES:\n- Output ONLY valid JSON (no code fences, no markdown, no explanations)\n- Hooks must be 8-15 words, punchy, and scroll-stopping\n- Main Content must be complete and ready to post (not bullet points)\n- If CTA Type is \"None\", leave CTA field as empty string \"\"\n- If CTA Type is \"Soft\", create subtle, value-first CTAs\n- If CTA Type is \"Hard\", include clear call-to-action with urgency\n- Hashtags must be space-separated string (not array)\n- Platform Variant should note any LinkedIn vs Instagram formatting differences\n- Preserve Sr No exactly as provided\n\nPLATFORM BEST PRACTICES:\n\n**LinkedIn:**\n- Professional, insight-driven tone\n- Longer-form content (150-300 words)\n- Hooks: Question-based, data-driven, or bold statements\n- Formatting: Short paragraphs, line breaks for readability\n- CTAs: Focus on professional growth, learning, or business value\n- Hashtags: 3-5 industry-specific tags\n\n**Instagram:**\n- Conversational, relatable tone\n- Shorter content (100-150 words for feed, 50-75 for Reels)\n- Hooks: Curiosity gaps, personal stories, or visual promises\n- Formatting: Emojis strategically placed, short sentences\n- CTAs: Encourage saves, shares, or profile visits\n- Hashtags: 8-15 mix of broad and niche tags\n\nOUTPUT STRUCTURE:\n{\n  \"Sr No\": <number>,\n  \"Hook (Option 1)\": \"<8-15 words, designed for maximum engagement>\",\n  \"Hook (Option 2)\": \"<8-15 words, alternative angle or approach>\",\n  \"Main Content\": \"<complete post content, platform-optimized, ready to publish>\",\n  \"CTA\": \"<call-to-action based on CTA Type, or empty string if None>\",\n  \"Hashtags\": \"<space-separated hashtags appropriate for platform>\",\n  \"Platform Variant\": \"<brief note on any LinkedIn vs Instagram differences>\"\n}"
            },
            {
              "content": "=Generate complete, platform-ready post content for the following calendar entry.\n\nINPUT DATA:\nSr No: {{$json[\"Sr No\"]}}\nPlatform: {{$json.Platform}}\nPillar: {{$json[\"Pillar ID\"]}}\nPost Intent: {{$json[\"Post Intent\"]}}\nFormat: {{$json.Format}}\nHook Angle: {{$json[\"Hook Angle\"]}}\nCTA Type: {{$json[\"CTA Type\"]}}\n\nCONTENT REQUIREMENTS:\n\n1. **Two Hook Options:**\n   - Hook 1: Use the specified Hook Angle approach\n   - Hook 2: Try an alternative angle for A/B testing\n   - Both should be 8-15 words, punchy, and scroll-stopping\n   - Incorporate the Post Intent theme\n\n2. **Main Content:**\n   - Write COMPLETE content (not outlines or bullet points)\n   - Match the specified Format ({{$json.Format}})\n   - If Carousel/Infographic: Structure in 3-5 clear points\n   - If Video/Reel: Include script-style formatting\n   - If Text Post: Write engaging 150-250 words\n   - If Document: Create educational framework with subheadings\n   - If Poll: Write question and 4 answer options\n   - Align with the Pillar: {{$json[\"Pillar ID\"]}}\n   - Deliver on the Post Intent: {{$json[\"Post Intent\"]}}\n\n3. **CTA Handling:**\n   - CTA Type: {{$json[\"CTA Type\"]}}\n   - If \"None\": Return empty string \"\"\n   - If \"Soft\": Subtle, value-first CTA (e.g., \"What's your experience with this?\", \"Save this for later\", \"Which approach works best for you?\")\n   - If \"Hard\": Clear action with urgency (e.g., \"Book a demo today\", \"Download our free guide\", \"Join 500+ marketers using InboxPlus\")\n\n4. **Hashtags:**\n   - Platform: {{$json.Platform}}\n   - LinkedIn: 3-5 professional, industry-specific tags\n   - Instagram: 8-15 mix of broad and niche tags\n   - Format as space-separated string: \"#Marketing #B2BSaaS #EmailAutomation\"\n\n5. **Platform Variant:**\n   - Note any key differences between LinkedIn and Instagram versions\n   - If content is universal, state \"Universal - no changes needed\"\n   - If platform-specific, explain the variation\n\nVALIDATION CHECKLIST:\n\u2713 Sr No preserved exactly as {{$json[\"Sr No\"]}}\n\u2713 Two distinct hooks provided (8-15 words each)\n\u2713 Main content is complete and ready to publish\n\u2713 CTA matches the specified type\n\u2713 Hashtags formatted as space-separated string\n\u2713 Output is valid JSON only (no markdown, no explanations)\n\nReturn ONLY the JSON response in the exact structure specified."
            }
          ]
        },
        "builtInTools": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "13ef0690-d43f-46f9-a311-3162ac381d05",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        1712,
        416
      ],
      "parameters": {
        "jsCode": "// ============================================================================\n// Content Pillar Response Parser for n8n\n// Purpose: Extract AI-generated content pillars and format for Google Sheets\n// ============================================================================\n\n// Step 1: Extract the AI response\nconst aiResponse = items[0].json;\n\n// Step 2: Navigate to the output_text\nlet responseText;\n\ntry {\n  // Handle the nested structure: output[0].content[0].text\n  const outputArray = aiResponse.output;\n  \n  if (!outputArray || !Array.isArray(outputArray) || outputArray.length === 0) {\n    throw new Error('Output array is missing or empty');\n  }\n  \n  const contentArray = outputArray[0].content;\n  \n  if (!contentArray || !Array.isArray(contentArray) || contentArray.length === 0) {\n    throw new Error('Content array is missing or empty');\n  }\n  \n  // Find the output_text type\n  const textContent = contentArray.find(item => item.type === 'output_text');\n  \n  if (!textContent || !textContent.text) {\n    throw new Error('output_text not found in content array');\n  }\n  \n  responseText = textContent.text;\n  \n} catch (error) {\n  throw new Error(`Failed to extract AI response: ${error.message}`);\n}\n\n// Step 3: Clean the JSON string (remove newlines and extra spaces)\nconst cleanedText = responseText\n  .replace(/```json/gi, '')\n  .replace(/```/g, '')\n  .trim();\n\n// Step 4: Parse the JSON\nlet parsed;\ntry {\n  parsed = JSON.parse(cleanedText);\n} catch (error) {\n  throw new Error(`JSON Parse Error: ${error.message}\\n\\nReceived text: ${cleanedText.substring(0, 500)}`);\n}\n\n// Step 5: Validate the parsed structure\nif (!parsed.contentPillars || !Array.isArray(parsed.contentPillars)) {\n  throw new Error('Invalid AI response: contentPillars array is missing');\n}\n\nif (parsed.contentPillars.length === 0) {\n  throw new Error('No content pillars were generated');\n}\n\nif (!parsed.platforms || !Array.isArray(parsed.platforms)) {\n  throw new Error('Invalid AI response: platforms array is missing');\n}\n\n// Step 6: Transform pillars into Google Sheets rows\nconst rows = parsed.contentPillars.map((pillar, index) => {\n  \n  // Validate required fields\n  if (!pillar.pillar_name) {\n    throw new Error(`Pillar at index ${index} is missing pillar_name`);\n  }\n  \n  if (!pillar.platform) {\n    throw new Error(`Pillar \"${pillar.pillar_name}\" is missing platform`);\n  }\n  \n  if (pillar['Weight (%)'] === undefined || pillar['Weight (%)'] === null) {\n    throw new Error(`Pillar \"${pillar.pillar_name}\" is missing Weight (%)`);\n  }\n  \n  return {\n    json: {\n      // Column A: Pillar Name\n      'Pillar Name': pillar.pillar_name,\n      \n      // Column B: Primary Purpose\n      'Primary Purpose': pillar.description || '',\n      \n      // Column C: Platform\n      'Platform': pillar.platform,\n      \n      // Column D: Weight (%)\n      'Weight (%)': pillar['Weight (%)'],\n      \n      // Column E: Allowed Formats\n      'Allowed Formats': pillar.pillar_type || '',\n      \n      // Column F: CTA Allowed\n      'CTA Allowed': pillar['CTA Allowed'] || 'Soft'\n    }\n  };\n});\n\n// Step 7: Validate weights sum to 100% per platform\nconst platformGroups = {};\n\nrows.forEach(row => {\n  const platform = row.json.Platform;\n  if (!platformGroups[platform]) {\n    platformGroups[platform] = [];\n  }\n  platformGroups[platform].push(row.json['Weight (%)']);\n});\n\n// Check each platform's total weight\nObject.entries(platformGroups).forEach(([platform, weights]) => {\n  const total = weights.reduce((sum, weight) => sum + parseInt(weight), 0);\n  \n  if (total !== 100) {\n    throw new Error(\n      `Weight validation failed for ${platform}: ` +\n      `Total = ${total}% (must equal 100%). ` +\n      `Weights: ${weights.join(', ')}`\n    );\n  }\n});\n\n// Step 8: Log summary for debugging\nconsole.log('\u2713 Successfully parsed AI response');\nconsole.log(`\u2713 Platforms: ${parsed.platforms.join(', ')}`);\nconsole.log(`\u2713 Total pillars generated: ${rows.length}`);\nconsole.log(`\u2713 Calculations: ${JSON.stringify(parsed.calculations, null, 2)}`);\n\nObject.entries(platformGroups).forEach(([platform, weights]) => {\n  console.log(`\u2713 ${platform}: ${weights.length} pillars, ${weights.reduce((a, b) => a + b, 0)}% total weight`);\n});\n\n// Step 9: Return formatted rows for Google Sheets\nreturn rows;"
      },
      "typeVersion": 2
    },
    {
      "id": "6e90cf2e-3ed5-43e0-bccd-3385c7d65981",
      "name": "Code in JavaScript6",
      "type": "n8n-nodes-base.code",
      "position": [
        3920,
        448
      ],
      "parameters": {
        "jsCode": "// n8n Code Node\n// Purpose: Parse post content AI output and format for Google Sheets\n\n// 1\ufe0f\u20e3 Extract raw text from AI response\nconst rawText = items[0].json.output?.[0]?.content?.[0]?.text;\n\nif (!rawText) {\n  throw new Error(\"No text found in AI response\");\n}\n\n// 2\ufe0f\u20e3 Clean markdown/code fences if any\nconst cleanedText = rawText\n  .replace(/```json/g, \"\")\n  .replace(/```/g, \"\")\n  .trim();\n\n// 3\ufe0f\u20e3 Parse JSON safely\nlet parsed;\ntry {\n  parsed = JSON.parse(cleanedText);\n} catch (err) {\n  throw new Error(\"Failed to parse JSON from AI output: \" + err.message);\n}\n\n// 4\ufe0f\u20e3 Get the original calendar data from the previous node\n// This assumes the Loop Over Items node passes the original data\nconst originalData = $('Loop Over Items').item.json;\n\n// 5\ufe0f\u20e3 Return flat structure (1 item = 1 row in Google Sheet)\nreturn [\n  {\n    json: {\n      \"Sr No\": parsed[\"Sr No\"] ?? \"\",\n      \"Date\": originalData[\"Date\"] ?? \"\", // CAPTURE DATE FROM ORIGINAL DATA\n      \"Hook Option 1\": parsed[\"Hook (Option 1)\"] ?? \"\",\n      \"Hook Option 2\": parsed[\"Hook (Option 2)\"] ?? \"\",\n      \"Main Content\": parsed[\"Main Content\"] ?? \"\",\n      \"CTA\": parsed[\"CTA\"] ?? \"\",\n      \"Hashtags\": parsed[\"Hashtags\"] ?? \"\",\n      \"Platform Variant\": parsed[\"Platform Variant\"] ?? \"\"\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "0380e171-b0f8-483e-b1b6-bdc6a92c2d32",
      "name": "Message a model7",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        2272,
        416
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "GPT-4O"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "role": "system",
              "content": "=You are an expert content calendar strategist and social media planner specializing in B2B and SaaS marketing.\n\nYOUR ROLE:\n- Generate a complete, day-by-day content calendar based on provided content pillars\n- Distribute posts strategically across pillars according to their weights\n- Create engaging, platform-optimized post concepts\n- Ensure proper CTA placement and pillar streak management\n- Output only valid JSON with no explanations or markdown\n\nCORE RESPONSIBILITIES:\n1. Calculate exact posting dates based on start date and frequency\n2. Distribute posts across pillars proportionally to their weights\n3. Generate unique, actionable post concepts (Post Intent) for each calendar entry\n4. Create compelling hooks from various angles (Hook Angle)\n5. Manage promotional post limits and CTA cooldown periods\n6. Avoid excessive repetition (respect Max Same Pillar Streak)\n7. Ensure platform-appropriate content formatting\n\nCRITICAL RULES YOU MUST FOLLOW:\n- Output ONLY valid JSON (no code fences, no markdown, no explanations)\n- Never exceed Max Promo Posts / Week limit\n- Respect CTA Cooldown (Days) - track days since last hard CTA\n- Never use the same pillar more than Max Same Pillar Streak consecutive times\n- Distribute posts according to pillar weights (\u00b15% tolerance acceptable)\n- Each post concept must be unique, specific, and actionable\n- Hook angles must be diverse (problem-solving, curiosity, controversial, story-based, data-driven, etc.)\n- Include specific post format recommendations\n- Never invent dates outside the specified duration\n- Pillar ID must reference the exact pillar name from the provided pillars\n\nOUTPUT STRUCTURE:\n{\n  \"calendarMetadata\": {\n    \"totalPosts\": <number>,\n    \"startDate\": \"<YYYY-MM-DD>\",\n    \"endDate\": \"<YYYY-MM-DD>\",\n    \"platform\": \"<platform>\",\n    \"postsPerWeek\": <number>,\n    \"totalWeeks\": <number>\n  },\n  \"pillarDistribution\": {\n    \"<pillar_name>\": {\n      \"targetWeight\": <number>,\n      \"actualPosts\": <number>,\n      \"actualWeight\": <number>\n    }\n  },\n  \"contentCalendar\": [\n    {\n      \"srNo\": <number>,\n      \"date\": \"<YYYY-MM-DD>\",\n      \"platform\": \"<LinkedIn|Instagram>\",\n      \"pillarID\": \"<exact pillar name>\",\n      \"format\": \"<Text Post|Carousel|Video|Infographic|Poll|Document|Story|Reel>\",\n      \"postIntent\": \"<specific, detailed post concept with clear value proposition>\",\n      \"hookAngle\": \"<compelling hook approach: problem-solving, curiosity gap, controversial take, personal story, data-driven, question-based, myth-busting, etc.>\",\n      \"ctaType\": \"<None|Soft|Hard>\",\n      \"status\": \"Pending\"\n    }\n  ]\n}\n\nCONTENT QUALITY STANDARDS:\n- Post Intent must be highly specific, not generic (e.g., \"Share 5 email automation mistakes that cost SaaS businesses $10K+ in lost revenue with real examples\" not \"Post about email automation\")\n- Hook Angle must define the psychological approach, not repeat the content (e.g., \"Curiosity Gap - Start with surprising statistic\" not \"Talk about email mistakes\")\n- Each post should have a clear, measurable value proposition\n- Vary hook angles to maintain engagement and avoid pattern fatigue\n- Include tactical, actionable insights where appropriate\n- Use platform-specific best practices"
            },
            {
              "content": "=TASK: Generate a complete content calendar by distributing posts across the provided content pillars according to their weights.\n\nCALENDAR PARAMETERS:\n\nStart Date: {{ $('Get row(s) in sheet').item.json['Start Date'] }}\nDuration (Days): {{ $('Get row(s) in sheet').item.json['Duration (Days)'] }}\nPosting Frequency / Week: {{ $('Get row(s) in sheet').item.json['Posting Frequency / Week'] }}\n\nMax Promo Posts / Week: {{ $('Get row(s) in sheet').item.json['Max Promo Posts / Week'] }}\nMin Educational Posts / Week: {{ $('Get row(s) in sheet').item.json['Min Educational Posts / Week'] }}\nCTA Cooldown (Days): {{ $('Get row(s) in sheet').item.json['CTA Cooldown (Days)'] }}\nMax Same Pillar Streak: {{ $('Get row(s) in sheet').item.json['Max Same Pillar Streak'] }}\n\nBRAND CONTEXT:\n\nBrand Name: {{ $('Get row(s) in sheet').item.json['Brand Name'] }}\nIndustry: {{ $('Get row(s) in sheet').item.json['Industry'] }}\nTarget Audience: {{ $('Get row(s) in sheet').item.json['Target Audience'] }}\nContent Goal: {{ $('Get row(s) in sheet').item.json['Content Goal'] }}\nTone: {{ $('Get row(s) in sheet').item.json['Tone'] }}\nPlatform: {{ $('Get row(s) in sheet').item.json['Platform'] }}\n\nCONTENT PILLARS (with weights):\n\n{{ JSON.stringify($input.all()) }}\n\n---\n\n[Rest of the prompt remains the same...]"
            }
          ]
        },
        "builtInTools": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "55b6f70f-6ecf-4427-ab90-1f508a9f80a9",
      "name": "Code in JavaScript7",
      "type": "n8n-nodes-base.code",
      "position": [
        2624,
        416
      ],
      "parameters": {
        "jsCode": "// ============================================================================\n// Content Calendar Response Parser for n8n\n// Maps to exact Google Sheets structure: Sr No, Date, Platform, Pillar ID, \n// Format, Post Intent, Hook Angle, CTA Type, Status\n// ============================================================================\n\nconst aiResponse = items[0].json;\n\n// Step 1: Extract the AI response\nlet responseText;\n\ntry {\n  const outputArray = aiResponse.output;\n  \n  if (!outputArray || !Array.isArray(outputArray) || outputArray.length === 0) {\n    throw new Error('Output array is missing or empty');\n  }\n  \n  const contentArray = outputArray[0].content;\n  \n  if (!contentArray || !Array.isArray(contentArray) || contentArray.length === 0) {\n    throw new Error('Content array is missing or empty');\n  }\n  \n  const textContent = contentArray.find(item => item.type === 'output_text');\n  \n  if (!textContent || !textContent.text) {\n    throw new Error('output_text not found in content array');\n  }\n  \n  responseText = textContent.text;\n  \n} catch (error) {\n  throw new Error(`Failed to extract AI response: ${error.message}`);\n}\n\n// Step 2: Clean the JSON string\nconst cleanedText = responseText\n  .replace(/```json/gi, '')\n  .replace(/```/g, '')\n  .trim();\n\n// Step 3: Parse the JSON\nlet parsed;\ntry {\n  parsed = JSON.parse(cleanedText);\n} catch (error) {\n  throw new Error(`JSON Parse Error: ${error.message}\\n\\nReceived: ${cleanedText.substring(0, 500)}`);\n}\n\n// Step 4: Validate structure\nif (!parsed.contentCalendar || !Array.isArray(parsed.contentCalendar)) {\n  throw new Error('Invalid AI response: contentCalendar array is missing');\n}\n\nif (parsed.contentCalendar.length === 0) {\n  throw new Error('No calendar entries were generated');\n}\n\n// Step 5: Transform calendar entries into exact Google Sheets format\nconst rows = parsed.contentCalendar.map((entry, index) => {\n  \n  // Validate required fields\n  if (!entry.date) {\n    throw new Error(`Calendar entry at index ${index} is missing date`);\n  }\n  \n  if (!entry.pillarID) {\n    throw new Error(`Calendar entry for ${entry.date} is missing pillarID`);\n  }\n  \n  if (!entry.postIntent) {\n    throw new Error(`Calendar entry for ${entry.date} is missing postIntent`);\n  }\n  \n  return {\n    json: {\n      // Column A: Sr No\n      'Sr No': entry.srNo || (index + 1),\n      \n      // Column B: Date\n      'Date': entry.date,\n      \n      // Column C: Platform\n      'Platform': entry.platform || '',\n      \n      // Column D: Pillar ID\n      'Pillar ID': entry.pillarID,\n      \n      // Column E: Format\n      'Format': entry.format || 'Text Post',\n      \n      // Column F: Post Intent\n      'Post Intent': entry.postIntent,\n      \n      // Column G: Hook Angle\n      'Hook Angle': entry.hookAngle || '',\n      \n      // Column H: CTA Type\n      'CTA Type': entry.ctaType || 'None',\n      \n      // Column I: Status\n      'Status': entry.status || 'Pending'\n    }\n  };\n});\n\n// Step 6: Validation and logging\nconsole.log('\u2713 Successfully parsed calendar');\nconsole.log(`\u2713 Total posts generated: ${rows.length}`);\nconsole.log(`\u2713 Date range: ${parsed.calendarMetadata?.startDate} to ${parsed.calendarMetadata?.endDate}`);\nconsole.log(`\u2713 Platform: ${parsed.calendarMetadata?.platform}`);\nconsole.log(`\u2713 Posts per week: ${parsed.calendarMetadata?.postsPerWeek}`);\n\nif (parsed.pillarDistribution) {\n  console.log('\\n\u2713 Pillar Distribution:');\n  Object.entries(parsed.pillarDistribution).forEach(([pillar, stats]) => {\n    console.log(`  - ${pillar}: ${stats.actualPosts} posts (${stats.actualWeight}% vs ${stats.targetWeight}% target)`);\n  });\n}\n\n// Step 7: Validate pillar distribution\nconst pillarCounts = {};\nrows.forEach(row => {\n  const pillar = row.json['Pillar ID'];\n  pillarCounts[pillar] = (pillarCounts[pillar] || 0) + 1;\n});\n\nconsole.log('\\n\u2713 Actual Post Distribution:');\nObject.entries(pillarCounts).forEach(([pillar, count]) => {\n  const percentage = ((count / rows.length) * 100).toFixed(1);\n  console.log(`  - ${pillar}: ${count} posts (${percentage}%)`);\n});\n\n// Step 8: Validate CTA spacing (using default cooldown of 5 days)\nconst ctaCooldownDays = 5; // Default cooldown - adjust as needed\nlet lastHardCTAIndex = -999;\nlet ctaViolations = 0;\n\nrows.forEach((row, index) => {\n  if (row.json['CTA Type'] === 'Hard') {\n    const daysSinceLastCTA = index - lastHardCTAIndex;\n    if (daysSinceLastCTA < ctaCooldownDays) {\n      ctaViolations++;\n      console.warn(`\u26a0 CTA spacing violation at post ${index + 1}: only ${daysSinceLastCTA} posts since last hard CTA`);\n    }\n    lastHardCTAIndex = index;\n  }\n});\n\nif (ctaViolations === 0) {\n  console.log('\\n\u2713 CTA cooldown validation passed');\n} else {\n  console.warn(`\\n\u26a0 Found ${ctaViolations} CTA spacing violations`);\n}\n\n// Step 9: Return formatted rows for Google Sheets\nreturn rows;"
      },
      "typeVersion": 2
    },
    {
      "id": "f4ac988c-1854-40a9-998c-c832deddee6d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        96
      ],
      "parameters": {
        "width": 832,
        "height": 640,
        "content": "## Smart Content Calendar Orchestration Workflow\n\nThis workflow is an end-to-end content planning and execution system that automates how brands design, structure, and generate social media content at scale. It transforms simple planning inputs into structured content pillars, a complete posting calendar, and publish-ready posts\u2014without manual ideation or scheduling.\n\n### How it works\n- Triggers when a new or updated row is added in the planning Google Sheet  \n- Reads brand details, platform selection, posting frequency, duration, and promotion rules  \n- Calculates total weeks, posts per week, and promotional vs educational split  \n- Generates platform-specific content pillars with strict weight distribution  \n- Builds a complete day-by-day content calendar with formats, hooks, CTA rules, and status  \n- Routes calendar items based on post format (Video vs Non-Video)  \n- Processes each post individually using a loop to avoid rate limits  \n- Generates final publish-ready content including hooks, captions, CTAs, and hashtags  \n- Stores pillars, calendar entries, and final posts into structured Google Sheets  \n\n### Setup steps\n1. Connect your Google Sheets account and prepare input sheets for brand and schedule data  \n2. Configure the Google Sheets Trigger to detect new or updated rows  \n3. Connect your OpenAI account for pillar, calendar, and post generation  \n4. Map Google Sheets nodes to store pillars, calendar entries, and final posts  \n5. Enable loop and wait nodes to safely process posts one at a time  \n6. Turn the workflow ON and test by adding a new planning row\n"
      },
      "typeVersion": 1
    },
    {
      "id": "2d665b97-3481-472a-a30a-49e0d4708016",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 1264,
        "height": 640,
        "content": "## Step 1: Input Capture & Trigger\nListens for new or updated rows in the planning Google Sheet and captures all brand, platform, scheduling, and promotion inputs that drive the entire workflow.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "20adcc4c-9804-4927-95ab-14cb350a2a6c",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2176,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 1104,
        "height": 640,
        "content": "## Step 2: Calendar Generation & Routing\nGenerates content pillars and a full posting calendar, then routes items by format (Video vs Non-Video) to ensure the correct content creation flow runs.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "95dc9cea-f769-4723-9294-49763d5ddcc0",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3296,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 1216,
        "height": 640,
        "content": "## Step 3: Post Creation & Final Storage\nProcesses each calendar item one by one to generate complete post content and stores publish-ready outputs in the final Google Sheet.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "ffff2763-0b7d-4d31-8dfd-ebf45779791a",
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Message a model6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message a model": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message a model6": {
      "main": [
        [
          {
            "node": "Code in JavaScript6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message a model7": {
      "main": [
        [
          {
            "node": "Code in JavaScript7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch By Format": {
      "main": [
        [],
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet": {
      "main": [
        [
          {
            "node": "Message a model7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript6": {
      "main": [
        [
          {
            "node": "Append row in sheet7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript7": {
      "main": [
        [
          {
            "node": "Append row in sheet6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "Message a model",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet6": {
      "main": [
        [
          {
            "node": "Switch By Format",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet7": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets Trigger": {
      "main": [
        [
          {
            "node": "Get row(s) in sheet",
            "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

This workflow turns a single planning row in Google Sheets into a fully structured content engine. It generates weighted content pillars, builds a rule-based posting calendar, and then creates publish-ready social posts using AI. The workflow strictly controls format routing,…

Source: https://n8n.io/workflows/12294/ — 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

Note: Now includes an Apify alternative for Rapid API (Some users can't create new accounts on Rapid API, so I have added an alternative for you. But immediately you are able to get access to Rapid AP

Form Trigger, Google Sheets Trigger, OpenAI +2
AI & RAG

This system automates LinkedIn lead generation and enrichment in six clear stages: Lead Collection (via Apollo.io) Automatically pulls leads based on keywords, roles, or industries using Apollo’s API.

Form Trigger, OpenAI, Google Sheets Trigger +2
AI & RAG

This n8n workflow automates the process of retrieving products from Printify, generating optimized product titles and descriptions, and updating them back to the platform. It leverages OpenAI for cont

HTTP Request, Tool Calculator, Tool Wikipedia +3
AI & RAG

An n8n-based automation that generates client proposals from a form, lets you review everything in one place, and sends the proposal only when you approve it.

Form Trigger, Google Sheets Trigger, OpenAI +4
AI & RAG

This workflow is designed for content creators, marketers, and automation enthusiasts who want to produce professional AI-generated videos and publish them automatically on social media — without edit

OpenAI, HTTP Request, Google Drive +3