{
  "id": "kercCjIToPKMFw9k",
  "meta": {
    "templateId": "4005",
    "templateCredsSetupCompleted": true
  },
  "name": "New - AI LinkedIn Post Generator with Human in Loop v2",
  "tags": [],
  "nodes": [
    {
      "id": "fabbcc53-ffc2-4392-a873-f6dd3841a5c9",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1776,
        240
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "548735f6-2f91-4ef7-9f68-b7819cba2b34",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1120,
        464
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "dfd22fbb-c27d-47b1-81cd-764cdae95d4d",
      "name": "Get Data from Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1472,
        240
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": true
        },
        "filtersUI": {
          "values": [
            {
              "lookupValue": "Ready",
              "lookupColumn": "Status"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OIzLmvlU-aSLMt61gsjUKncxg8h3l43O3LZRaPVPQHo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1OIzLmvlU-aSLMt61gsjUKncxg8h3l43O3LZRaPVPQHo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OIzLmvlU-aSLMt61gsjUKncxg8h3l43O3LZRaPVPQHo/edit?usp=drivesdk",
          "cachedResultName": "LinkedIn Post Automation v1"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "fc8807e0-37ed-481f-9466-71b439c2d58e",
      "name": "Generate Post Content",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -1184,
        240
      ],
      "parameters": {
        "text": "=Post Description:\n{{ $json[\"Post Description\"] }}\n\nInstructions:\n{{ $json[\"Instructions\"] }}",
        "messages": {
          "messageValues": [
            {
              "message": "=### ROLE\nYou are a world-class LinkedIn Ghostwriter for high-growth Founders and Thought Leaders. Your specialty is \"Scroll-Stopping\" content that builds authority without looking like it was written by an AI or a PR firm. And, also something that is fun to read and people might either giggle or want to share with others.\n\n### THE GOAL\nCreate a LinkedIn post based on the user's input that looks 100% human, generates high engagement, and forces the reader to click \"See More.\"\n\n### WRITING STYLE GUIDELINES (STRICT ADHERENCE)\n1. NO \"AI-ISMS\": Avoid words like \"In today\u2019s fast-paced world,\" \"Unlock,\" \"Transformative,\" \"Tapestry,\" \"Hustle,\" or \"Revolutionize.\"\n2. PUNCHY RHYTHM: Use a mix of short and very short sentences. Avoid long, complex paragraphs. \n3. WHITE SPACE: Never more than 2 lines of text per paragraph. Use white space to create a \"slippery slide\" effect.\n4. THE HOOK: The first sentence must be a \"Pattern Interrupt.\" It should be a bold claim, a counter-intuitive truth, or a specific result. \n5. NO FLUFF: Get straight to the point. If a sentence doesn't add value or tension, delete it.\n6. TONE: Assertive, slightly opinionated, yet empathetic. Speak like a practitioner, not a lecturer.\n\n### POST STRUCTURE\n- The Hook: (1 sentence) To stop the scroll.\n- The Re-Hook: (1 sentence) To provide context/tension.\n- The Meat: (3-5 bullet points or short sentences) The \"How-to\" or the \"Value.\"\n- The Insight: (1 sentence) The \"Aha!\" moment.\n- The Call to Action (CTA): A low-friction question or a specific instruction (e.g., \"Connect for more\").\n- 3 lowercase hashtags.\n\n### CONSTRAINTS\n- Max 1300 characters.\n- Output ONLY the post. No \"Here is your post\" or markdown code blocks. \n- Give me well formatted output that can be posted on Linkedin, feel free to use bullet points, etc.\n- Very limited emojis only if required\n- When putting points or list items, use bullet symbol '\u2022' for each list item\n- No em-dashes, use regular dash like this '-'"
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.6
    },
    {
      "id": "b92ad6ce-33f7-461a-bfd0-c4a677b62114",
      "name": "Send Content Confirmation",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -16,
        256
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=Generated Post:\n{{ $node[\"Generate Post Content\"].json[\"text\"] }}\n\n----------\n\nPost Image:\n{{ $node[\"Upload a File\"].json[\"url\"] }}\n\n----------",
        "options": {},
        "subject": "Approval for LinkedIn Post",
        "operation": "sendAndWait",
        "approvalOptions": {
          "values": {
            "approvalType": "double"
          }
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "f24899aa-a9da-445e-aafc-c4da8b9f52c8",
      "name": "Content Confirmation Logic",
      "type": "n8n-nodes-base.switch",
      "position": [
        368,
        256
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Approved",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "99ec185e-80ac-451d-bb69-662f84a7cf52",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.data.approved }}",
                    "rightValue": "Yes"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "No",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "77031007-a912-4b9b-9cca-846c57ffaec8",
                    "operator": {
                      "type": "boolean",
                      "operation": "false",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.data.approved }}",
                    "rightValue": "No"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "ea44561e-61d5-4580-b07c-3502aae3d362",
      "name": "Post With Image",
      "type": "n8n-nodes-base.linkedIn",
      "position": [
        1248,
        -144
      ],
      "parameters": {
        "text": "={{ $('Generate Post Content').item.json.text.replaceAll('\u2014', '-') }}",
        "person": "=",
        "additionalFields": {},
        "shareMediaCategory": "IMAGE"
      },
      "credentials": {
        "linkedInOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e68b6aaf-18d5-46a2-991a-6ae7f046deb6",
      "name": "Update Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1552,
        64
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "=Completed",
            "Post ID": "={{ $json.urn }}",
            "Post Link": "=https://www.linkedin.com/feed/update/{{ $json.urn }}",
            "row_number": "={{ $('Get Data from Sheets').item.json.row_number }}"
          },
          "schema": [
            {
              "id": "Post Description",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Post Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Instructions",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Instructions",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Post ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Post ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Post Link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Post Link",
              "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": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OIzLmvlU-aSLMt61gsjUKncxg8h3l43O3LZRaPVPQHo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1OIzLmvlU-aSLMt61gsjUKncxg8h3l43O3LZRaPVPQHo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OIzLmvlU-aSLMt61gsjUKncxg8h3l43O3LZRaPVPQHo/edit?usp=drivesdk",
          "cachedResultName": "LinkedIn Post Automation v1"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "d281c981-aec1-40bf-86f2-feaa1c4baaea",
      "name": "Update Status to Canceled",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        752,
        272
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "=Canceled",
            "Post ID": "={{ $json.urn }}",
            "Post Link": "=https://www.linkedin.com/feed/update/{{ $json.urn }}",
            "row_number": "={{ $('Get Data from Sheets').item.json.row_number }}"
          },
          "schema": [
            {
              "id": "Post Description",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Post Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Instructions",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Instructions",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Post ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Post ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Post Link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Post Link",
              "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": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OIzLmvlU-aSLMt61gsjUKncxg8h3l43O3LZRaPVPQHo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1OIzLmvlU-aSLMt61gsjUKncxg8h3l43O3LZRaPVPQHo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OIzLmvlU-aSLMt61gsjUKncxg8h3l43O3LZRaPVPQHo/edit?usp=drivesdk",
          "cachedResultName": "LinkedIn Post Automation v1"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "5d4848f8-0e42-4d3e-8272-efaa37c0317e",
      "name": "Post Without Image",
      "type": "n8n-nodes-base.linkedIn",
      "position": [
        1120,
        160
      ],
      "parameters": {
        "text": "={{ $('Generate Post Content').item.json.text }}",
        "person": "=",
        "additionalFields": {}
      },
      "credentials": {
        "linkedInOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5835471d-b2ef-462e-bd22-7a159afe5f74",
      "name": "Is Image Required?",
      "type": "n8n-nodes-base.if",
      "position": [
        624,
        32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "9a78220d-35f5-48b6-9ce3-faecaac24b74",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Get Data from Sheets').item.json['Generate Image (Yes/No)'] }}",
              "rightValue": "Yes"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2f88cae3-0314-4fcf-8c35-b664b37b9e3f",
      "name": "Generate Post Image",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        -496,
        48
      ],
      "parameters": {
        "prompt": "=Task: Generate an interesting image for a LinkedIn post based on the content provided below\n\nPost Idea: {{ $('Get Data from Sheets').item.json['Post Description'] }}\n\n1. IMAGE STYLE GUIDELINES (Choose the best fit based on analysis)\nIf possible, use some cartoons with some texts. Try to be a little creative here\n\n2. TECHNICAL SPECIFICATIONS\nAspect Ratio: 1:1 (Square) or 4:5 (Vertical) for maximum mobile real estate.\n\nQuality: Photorealistic, no distorted limbs or text gibberish.",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-3-pro-image-preview",
          "cachedResultName": "models/gemini-3-pro-image-preview (Nano Banana Pro)"
        },
        "options": {},
        "resource": "image"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "50c2b558-3a6c-40e6-8f16-c40103ae0113",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        -832,
        240
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Image Required",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "0f64ac0c-e6b7-42b3-8cd2-62dc8c5e664a",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Get Data from Sheets').item.json['Generate Image (Yes/No)'] }}",
                    "rightValue": "Yes"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Image Not Required",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "2ee1c442-838f-40e8-b421-bc19e4349a22",
                    "operator": {
                      "type": "string",
                      "operation": "notEquals"
                    },
                    "leftValue": "={{ $('Get Data from Sheets').item.json['Generate Image (Yes/No)'] }}",
                    "rightValue": "Yes"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "17168de3-6335-4f9c-a4c3-2d4e15d38587",
      "name": "Upload a File",
      "type": "n8n-nodes-uploadtourl.uploadToUrl",
      "position": [
        -176,
        48
      ],
      "parameters": {
        "uploadAllBinary": false
      },
      "credentials": {
        "uploadToUrlApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b22d72d8-1c7d-4f57-b0d3-b2e78c59996e",
      "name": "Download a File",
      "type": "n8n-nodes-uploadtourl.uploadToUrl",
      "position": [
        944,
        -144
      ],
      "parameters": {
        "fileUrl": "={{ $('Upload a File').item.json.url }}",
        "operation": "download"
      },
      "credentials": {
        "uploadToUrlApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ea8d6cc6-5edb-47a8-9c3c-d803422b140d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2144,
        -528
      ],
      "parameters": {
        "color": "#E6E88D",
        "width": 896,
        "height": 304,
        "content": "# Workflow Overview\nThis workflow automates LinkedIn post creation from a Google Sheet while keeping a human approval step before publishing.\n\n## How it works\n1. Runs on a schedule\n2. Reads one ready post idea from Google Sheets\n3. Generates LinkedIn post copy using OpenAI\n4. Optionally creates an AI image using Google Gemini\n5. Sends the post and image for human approval via Gmail\n6. Publishes to LinkedIn only after approval\n7. Updates the Google Sheet with the final status and post link\n"
      },
      "typeVersion": 1
    },
    {
      "id": "173f3a84-f50f-46d9-ab23-1b4d8ad020d7",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1904,
        -16
      ],
      "parameters": {
        "color": "#F4CDCD",
        "width": 304,
        "height": 416,
        "content": "# Step 1: Schedule Trigger\n\nThis node starts the workflow automatically based on the schedule you define.\n\n## Purpose\nIt removes the need to manually run the workflow every time a LinkedIn post should be prepared."
      },
      "typeVersion": 1
    },
    {
      "id": "107323b3-b5c6-4774-90d3-c86f2e761d96",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1584,
        -192
      ],
      "parameters": {
        "color": "#EEBEDA",
        "width": 336,
        "height": 592,
        "content": "# Step 2: Get Data from Google Sheets\n\nThis node reads post ideas from the connected Google Sheet.\n\n## What it checks\nIt looks for rows where:\n\n`Status = Ready`\n\n## Columns used\n- Post Description\n- Instructions\n- Generate Image (Yes/No)\n- Status"
      },
      "typeVersion": 1
    },
    {
      "id": "87888b38-285e-44f6-9657-14d7c1aae2e6",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1232,
        -256
      ],
      "parameters": {
        "color": "#D5B9D3",
        "width": 336,
        "height": 656,
        "content": "# Step 3: Generate LinkedIn Post Content\n\nThis node uses OpenAI to turn the sheet input into a polished LinkedIn post.\n\n## Input\nIt receives:\n- Post Description\n- Instructions\n\n## What the AI generates\nA LinkedIn-ready post with:\n- A strong hook\n- Short readable paragraphs\n- Bullet points where useful\n- A clear CTA\n- Relevant hashtags"
      },
      "typeVersion": 1
    },
    {
      "id": "6bec13ee-eb24-44e4-be8a-192ebd75b9e2",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -880,
        -240
      ],
      "parameters": {
        "color": "#E4A8FF",
        "width": 272,
        "height": 640,
        "content": "# Step 4: Route Image Generation\n\nThis node decides whether the workflow should create an AI image for the LinkedIn post.\n\n## Condition checked\nIt reads the Google Sheets column:\n\n`Generate Image (Yes/No)`\n\n## Routes\n- If value is `Yes`, the workflow generates an image\n- If value is not `Yes`, the workflow skips image generation"
      },
      "typeVersion": 1
    },
    {
      "id": "d935a38d-9252-481d-8c63-23efead2e8a1",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -592,
        -304
      ],
      "parameters": {
        "color": "#A9ADE5",
        "width": 304,
        "height": 512,
        "content": "# Step 5: Generate Post Image\n\nThis node creates an AI-generated image using Google Gemini.\n\n## Input\nIt uses the original post idea from Google Sheets as image context.\n\n## What it creates\nA LinkedIn-friendly visual that matches the post topic."
      },
      "typeVersion": 1
    },
    {
      "id": "76add123-93cd-4183-882a-27eb7cad17a3",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -272,
        -384
      ],
      "parameters": {
        "color": "#B7D3E1",
        "width": 352,
        "height": 592,
        "content": "# Step 6: Upload a File\n\nThis node uploads the generated image and converts it into a public image URL.\n\n## Why this is needed\nThe approval email needs a shareable image link so the reviewer can preview the generated visual before approving the post.\n\n## Input\nBinary image data from the Gemini image generation node.\n\n## Output\nA public image URL.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4f910fdc-8f47-4e98-8c45-c99e211aed1a",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        224
      ],
      "parameters": {
        "color": "#E1BEF4",
        "width": 384,
        "height": 592,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n# Step 7: Send Post for Human Approval\n\nThis Gmail node sends the generated LinkedIn post to a human reviewer before publishing.\n\n## What the email includes\n- Generated LinkedIn post text\n- Generated image URL, if an image was created\n- Approval buttons\n\n## Approval options\n- Approve\n- Reject"
      },
      "typeVersion": 1
    },
    {
      "id": "b28dbc74-3a0c-4694-b31f-a1d26b20cb3b",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        224
      ],
      "parameters": {
        "color": "#A5A9DF",
        "width": 352,
        "height": 576,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n# Step 8: Content Confirmation Logic\n\nThis node checks the human approval response from Gmail.\n\n## Condition checked\nIt reads the approval result returned by the Gmail approval step.\n\n## Routes\n- Approved \u2192 Continue to LinkedIn publishing\n- Rejected \u2192 Update the Google Sheet as canceled"
      },
      "typeVersion": 1
    },
    {
      "id": "3cce1b3f-b791-4297-90b0-2bd300701c75",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        -368
      ],
      "parameters": {
        "color": "#CEF0BC",
        "width": 336,
        "height": 544,
        "content": "# Step 9A: Is Image Required?\n\nAfter approval, this node checks whether the final LinkedIn post should be published with an image or as text only.\n\n## Condition checked\nIt reads:\n\n`Generate Image (Yes/No)`\n\n## Routes\n- Yes \u2192 Download image and publish post with image\n- No \u2192 Publish text-only LinkedIn post\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a4d35b78-9d72-45a6-ac3b-b591903fdc64",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        -464
      ],
      "parameters": {
        "color": "#B6D086",
        "width": 336,
        "height": 480,
        "content": "# Step 10: Download a File\n\nThis node downloads the uploaded image again as binary data.\n\n\nLinkedIn requires binary image data during upload.\n\n## What it does\n- Downloads image from public URL\n- Converts it back into binary format\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "6be562b7-3370-4aed-bf13-da7228bc59e0",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        -592
      ],
      "parameters": {
        "color": "#DDCD78",
        "width": 272,
        "height": 608,
        "content": "# Step 11A: Publish LinkedIn Post with Image\n\nThis node publishes the approved LinkedIn post with the generated image attached.\n\n## Input\n- Final LinkedIn post text\n- Downloaded binary image file\n\n## Output\nA live LinkedIn image post."
      },
      "typeVersion": 1
    },
    {
      "id": "94af4117-e8b1-417d-8ea4-62a876ec10b9",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        128
      ],
      "parameters": {
        "color": "#A3D7B5",
        "width": 336,
        "height": 528,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n# Step 11B: Post Without Image\n\nThis node publishes the approved LinkedIn post without an image.\n\n## Input\nFinal LinkedIn post text generated by the AI.\n\n## Output\nA live text-only LinkedIn post.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1b04485c-205b-4e0f-a575-97c29958069d",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1472,
        -224
      ],
      "parameters": {
        "color": "#F5A57A",
        "width": 288,
        "height": 448,
        "content": "# Step 12: Update Google Sheet\n\nThis node updates the original Google Sheet row after the LinkedIn post is successfully published.\n\n## What gets updated\n- Status = Completed\n- Post ID\n- LinkedIn Post Link"
      },
      "typeVersion": 1
    },
    {
      "id": "3ea97602-6a9e-4037-ae55-e872817e03ca",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        608,
        224
      ],
      "parameters": {
        "color": "#EAD5A9",
        "width": 352,
        "height": 544,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n# Step 9B: Update Status to Canceled\n\nThis node updates the Google Sheet when the human reviewer rejects the generated post.\n\n## What gets updated\n- Status = Canceled\n\n## When this runs\nOnly when the approval email response is rejected."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "8469bc60-b77b-4a5d-a592-6729d79212fe",
  "connections": {
    "Switch": {
      "main": [
        [
          {
            "node": "Generate Post Image",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Content Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload a File": {
      "main": [
        [
          {
            "node": "Send Content Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download a File": {
      "main": [
        [
          {
            "node": "Post With Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post With Image": {
      "main": [
        [
          {
            "node": "Update Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Data from Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Post Content",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Is Image Required?": {
      "main": [
        [
          {
            "node": "Download a File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Post Without Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Without Image": {
      "main": [
        [
          {
            "node": "Update Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Post Image": {
      "main": [
        [
          {
            "node": "Upload a File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Google Sheet": {
      "main": [
        []
      ]
    },
    "Get Data from Sheets": {
      "main": [
        [
          {
            "node": "Generate Post Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Post Content": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Content Confirmation": {
      "main": [
        [
          {
            "node": "Content Confirmation Logic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Content Confirmation Logic": {
      "main": [
        [
          {
            "node": "Is Image Required?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Status to Canceled",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}