AutomationFlowsAI & RAG › Generate Linkedin Posts From Web Pages with Gpt-4 and Human Review

Generate Linkedin Posts From Web Pages with Gpt-4 and Human Review

ByAirtop @cesar-at-airtop on n8n.io

Turn any web page into a compelling LinkedIn post — complete with an AI-generated image. This automation is ideal for sharing content like blog posts, case studies, or product updates in a polished and engaging format.

Event trigger★★★★☆ complexityAI-powered14 nodesForm TriggerOpenAI ChatText ClassifierSlackOpenAIAirtop
AI & RAG Trigger: Event Nodes: 14 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Form Trigger → OpenAI Chat 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": "3RrE9MTfcGIPM4nh",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Generate LinkedIn Post from Web Page - text only",
  "tags": [],
  "nodes": [
    {
      "id": "b019d964-c28f-4685-b1b5-2a7bed8b29dc",
      "name": "On form submission",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -4280,
        1040
      ],
      "parameters": {
        "options": {},
        "formTitle": "LinkedIn Post Generator",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Page URL",
              "placeholder": "https://www.airtop.ai/automations/ai-web-agent-n8n",
              "requiredField": true
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "Instructions"
            }
          ]
        },
        "formDescription": "Fill out these fields and you'll have a full LinkedIn post ready to go in a minute. "
      },
      "typeVersion": 2.2
    },
    {
      "id": "f73c1893-11e6-46a2-8e45-60472c150bc2",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4020,
        820
      ],
      "parameters": {
        "width": 2040,
        "height": 480,
        "content": "# Content Generation & Revisions"
      },
      "typeVersion": 1
    },
    {
      "id": "ebf8a3a0-c823-4384-83c6-f8b7bfb02a84",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4500,
        820
      ],
      "parameters": {
        "color": 6,
        "width": 440,
        "height": 480,
        "content": "# To generate post and visual - start here!"
      },
      "typeVersion": 1
    },
    {
      "id": "ad860e11-b154-4401-8e58-950b6e7a9afb",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -2560,
        1100
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1",
          "cachedResultName": "gpt-4.1"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "5c5e136e-76cb-4747-add1-90e5636f7890",
      "name": "Set Post",
      "type": "n8n-nodes-base.set",
      "position": [
        -3160,
        920
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "346bd2cf-743b-4b13-a34e-528a95e1a617",
              "name": "URL",
              "type": "string",
              "value": "={{ $('Set Params').item.json.URL }}"
            },
            {
              "id": "8430fd16-f865-4b37-b7bc-7e910badbb19",
              "name": "Instructions",
              "type": "string",
              "value": "= - "
            },
            {
              "id": "35a9e113-ea92-438d-ac25-41ed9a74071f",
              "name": "Post",
              "type": "string",
              "value": "={{ $json.output }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "239536cc-62ef-415d-a39f-4e42a583899f",
      "name": "Set Params",
      "type": "n8n-nodes-base.set",
      "position": [
        -3760,
        1040
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "346bd2cf-743b-4b13-a34e-528a95e1a617",
              "name": "URL",
              "type": "string",
              "value": "={{ $('On form submission').item.json['Page URL'] }}"
            },
            {
              "id": "8430fd16-f865-4b37-b7bc-7e910badbb19",
              "name": "Instructions",
              "type": "string",
              "value": "={{ $('On form submission').item.json.Instructions }}"
            },
            {
              "id": "35a9e113-ea92-438d-ac25-41ed9a74071f",
              "name": "Post",
              "type": "string",
              "value": "= - "
            },
            {
              "id": "cd1fac8d-6b57-4072-966f-67e3cf1b9cc4",
              "name": "=Webpage_content",
              "type": "string",
              "value": "={{ $json.data.modelResponse.scrapedContent.text }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "c5b7b602-604b-4176-98b4-2d6d8f433a27",
      "name": "Set Post1",
      "type": "n8n-nodes-base.set",
      "position": [
        -2280,
        580
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "346bd2cf-743b-4b13-a34e-528a95e1a617",
              "name": "URL",
              "type": "string",
              "value": "={{ $('Set Params').item.json.URL }}"
            },
            {
              "id": "8430fd16-f865-4b37-b7bc-7e910badbb19",
              "name": "Instructions",
              "type": "string",
              "value": "={{ $json.data.text }}"
            },
            {
              "id": "35a9e113-ea92-438d-ac25-41ed9a74071f",
              "name": "Post",
              "type": "string",
              "value": "={{ $('Set Post').item.json.Post }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "9498e4b7-187b-42fc-9d37-fc395bbe683d",
      "name": "Check Post Text Feedback",
      "type": "@n8n/n8n-nodes-langchain.textClassifier",
      "position": [
        -2560,
        920
      ],
      "parameters": {
        "options": {
          "multiClass": false
        },
        "inputText": "={{ $json.data.text }}",
        "categories": {
          "categories": [
            {
              "category": "Edit",
              "description": "The email has been reviewed, but the human requests modifications to the post text before it is sent like tweaks, removing parts, rewording, etc. This could include suggested edits, rewording, or major revisions to the post text. |Example phrases include:\"Can we tweak this part of the post?\"\"Needs some changes to this sentence.\"\"I\u2019d like to reword the post.\"\"Not quite right\u2014let\u2019s revise the text.\"\"Can you adjust the text before sending?\"\"Don't mention Make in the text\"\"change the style of the writing\"\"tone of voice is not consistent with our branding\""
            },
            {
              "category": "Approved",
              "description": "The email has been reviewed and accepted as-is. The human explicitly or implicitly expresses approval, indicating that no changes are needed. |Example phrases include:\"Looks good.\"\"Go ahead and send it.\"\"This works for me.\"\"Approved.\"\"No changes needed.\"\"ok\""
            },
            {
              "category": "Declined",
              "description": "The email has been reviewed, but the human requests not to proceed with the post. |Example phrases include:\"Let's cancel this post.\"\"Don't post\""
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8f686580-ae0a-4001-9852-b50efb9d6e03",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1920,
        820
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "height": 480,
        "content": "# Send Final Post"
      },
      "typeVersion": 1
    },
    {
      "id": "268337f8-8ade-45ab-86b3-c4d9a436ed93",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4500,
        -480
      ],
      "parameters": {
        "color": 5,
        "width": 1060,
        "height": 1140,
        "content": "README\n# Generate LinkedIn Posts from Any Webpage (text only)\n## Use Case\nTurn any web page into a compelling LinkedIn post \u2014 complete with an AI-generated image. This automation is ideal for sharing content like blog posts, case studies, or product updates in a polished and engaging format.\n\n## What This Automation Does\nGiven a page URL and optional user instructions, this automation:\n- Scrapes the content of the webpage\n- Uses AI to write a clear, educational, and LinkedIn-optimized post\n- Sends both to Slack for review and approval\n- Handles feedback and revisions via Slack interactions\n\nInput:\n- **Page URL** \u2014 The link to the webpage (required)\n- **Instructions** \u2014 Optional notes on tone, emphasis, or format\n\nOutput:\n- LinkedIn post text\n- Slack message with review/approval options\n\n## How It Works\n1. **Form Submission**: User inputs a web page and optional instructions.\n2. **Web Scraping**: Uses Airtop to extract page content.\n3. **Post Generation**: AI agent writes a post based on the page and instructions.\n4. **Slack Review Flow**:\n   - Post and image sent to Slack for feedback\n   - User can approve, request revisions, or decline\n   - Revisions trigger reprocessing steps automatically\n5. **Final Post Delivery**: Approved post is sent back to Slack, ready to publish.\n\n## Setup Requirements\n1. Airtop API key\n2. OpenAI credentials for post and image prompt generation\n3. Slack OAuth integration with a review channel\n4. A sub-workflow for branded image generation\n\n## Next Steps\n- **Post Directly**: Add LinkedIn publishing to automate the full content workflow.\n- **Template Variations**: Offer post style presets (e.g., technical, story-driven, short-form).\n- **CRM Sync**: Save approved posts and stats in Airtable or Notion for team use.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "32ed47df-d2f2-483a-b011-7adad6559007",
      "name": "Final Version",
      "type": "n8n-nodes-base.slack",
      "position": [
        -1740,
        920
      ],
      "parameters": {
        "text": "=----------------  \nFINAL POST:\n----------------  \n\n{{ $('Set Post').item.json.Post }}\n",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C08QUB9N5FX",
          "cachedResultName": "gen-social-posts"
        },
        "otherOptions": {
          "unfurl_links": false,
          "unfurl_media": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "58845733-16ca-4d29-bc75-f3334cea4be2",
      "name": "Human Revision of Text",
      "type": "n8n-nodes-base.slack",
      "position": [
        -2860,
        920
      ],
      "parameters": {
        "select": "channel",
        "message": "=----------------\n\n{{ $json.Post }}\n\n-----------------\nBased on: {{ $json.URL }}",
        "options": {
          "limitWaitTime": {
            "values": {
              "resumeUnit": "days",
              "resumeAmount": 3
            }
          },
          "appendAttribution": false,
          "responseFormTitle": "Image Feedback"
        },
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C08QUB9N5FX",
          "cachedResultName": "gen-social-posts"
        },
        "operation": "sendAndWait",
        "responseType": "freeText",
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "86e48876-440b-485a-893a-a691424d3dba",
      "name": "Generate Post Text",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        -3540,
        1040
      ],
      "parameters": {
        "text": "=Write a helpful educational, and engaging LinkedIn posts based on a webpage scraped content below or the Post text below and according to the instructions provided by the user.\n\nInstructions: {{ $json.Instructions }}\n\n{{ $json.Post }}\n\n{{ $json.Webpage_content }}",
        "prompt": "define",
        "options": {},
        "resource": "assistant",
        "assistantId": {
          "__rl": true,
          "mode": "list",
          "value": "asst_aYEHuzWeFxMBN2qu4FnXRsJ4",
          "cachedResultName": "Social Media Writer"
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "d6e68ba2-49c2-4e39-806d-4e70fa9f4cac",
      "name": "Get Page",
      "type": "n8n-nodes-base.airtop",
      "position": [
        -3980,
        1040
      ],
      "parameters": {
        "url": "={{ (() => {\n  const url = ($json['Page URL'] || '').trim();\n  return url && (url.startsWith('http://') || url.startsWith('https://')) ? url : 'http://' + url;\n})() }}",
        "resource": "extraction",
        "operation": "scrape",
        "sessionMode": "new"
      },
      "credentials": {
        "airtopApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "e0eb5228-9ec6-465c-b323-fd2ee9962719",
  "connections": {
    "Get Page": {
      "main": [
        [
          {
            "node": "Set Params",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Post": {
      "main": [
        [
          {
            "node": "Human Revision of Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Post1": {
      "main": [
        [
          {
            "node": "Generate Post Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Params": {
      "main": [
        [
          {
            "node": "Generate Post Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Check Post Text Feedback",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Generate Post Text": {
      "main": [
        [
          {
            "node": "Set Post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On form submission": {
      "main": [
        [
          {
            "node": "Get Page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Human Revision of Text": {
      "main": [
        [
          {
            "node": "Check Post Text Feedback",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Post Text Feedback": {
      "main": [
        [
          {
            "node": "Set Post1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Final Version",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Turn any web page into a compelling LinkedIn post — complete with an AI-generated image. This automation is ideal for sharing content like blog posts, case studies, or product updates in a polished and engaging format.

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

Turn any web page into a compelling LinkedIn post — complete with an AI-generated image. This automation is ideal for sharing content like blog posts, case studies, or product updates in a polished an

Form Trigger, OpenAI Chat, OpenAI +3
AI & RAG

Email Automation AI-Powered Operations Internal Productivity Tools

Gmail Trigger, Text Classifier, OpenAI Chat +3
AI & RAG

This n8n template demonstrates how to automate email classification, labeling, draft generation, and logging using Gmail, OpenAI, and Google Sheets. Use cases include customer support management, sale

Gmail Trigger, Gmail, Text Classifier +4
AI & RAG

This n8n template uses AI to automatically classify incoming Gmail messages into five categories and route them to the right people or departments. It can also reply automatically and send WhatsApp al

Gmail Trigger, OpenAI Chat, Gmail +3
AI & RAG

Detects new unread Gmail messages Extracts sender name for personalized replies Classifies the email into one of four categories Applies the correct Gmail label and either sends an auto-reply, creates

Gmail Trigger, OpenAI Chat, Gmail +4