This workflow corresponds to n8n.io template #11386 — we link there as the canonical source.
This workflow follows the Agent → OpenAI Embeddings recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "ded81242-91f9-48b2-92e7-93b5c427c22c",
"name": "5",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1184,
3104
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5",
"cachedResultName": "gpt-5"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "db3f31ca-0104-4484-a5a3-718a05e6db9a",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
-128,
3728
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "c2a21f68-1dd7-4614-be11-45c3f2129a63",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json['Article Link'].isUrl() }}",
"rightValue": true
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "b79d6081-d689-4a93-b927-64060828aac0",
"name": "Extract Details",
"type": "n8n-nodes-base.code",
"position": [
336,
3696
],
"parameters": {
"jsCode": "const { Readability } = require(\"@mozilla/readability\");\nconst { JSDOM } = require(\"jsdom\");\n\ntry {\n const inputData = items[0].json;\n const html = inputData.data;\n const url = inputData.url\n\n if (!html || html.trim().length === 0) {\n throw new Error(\"No HTML content found\");\n }\n\n const dom = new JSDOM(html, { \n url,\n contentType: \"text/html\"\n });\n\n const document = dom.window.document;\n const reader = new Readability(dom.window.document);\n const article = reader.parse();\n\n if (!article) {\n return [{\n json: {\n error: \"Readability could not extract article content\",\n reason: \"The page may not contain article-like content or structure\",\n url,\n htmlLength: html.length\n }\n }];\n }\n\n let imageUrl = null;\n \n const ogImage = document.querySelector('meta[property=\"og:image\"]');\n if (ogImage) imageUrl = ogImage.getAttribute('content');\n \n if (!imageUrl) {\n const twitterImage = document.querySelector('meta[name=\"twitter:image\"]');\n if (twitterImage) imageUrl = twitterImage.getAttribute('content');\n }\n \n if (!imageUrl && article.content) {\n const contentDom = new JSDOM(article.content);\n const firstImg = contentDom.window.document.querySelector('img');\n if (firstImg) imageUrl = firstImg.getAttribute('src');\n }\n \n if (imageUrl && !imageUrl.startsWith('http')) {\n try {\n imageUrl = new URL(imageUrl, url).href;\n } catch (e) {\n // Invalid URL, keep as is\n }\n }\n \n return [{\n json: {\n title: article.title || \"No title found\",\n author: article.byline || \"Unknown\",\n contentText: article.textContent || \"\",\n wordCount: article.length || 0,\n siteName: article.siteName || \"Unknown site\",\n excerpt: article.excerpt || \"\",\n imageUrl: imageUrl || null,\n }\n }];\n\n} catch (error) {\n return [{\n json: {\n error: error.message,\n stack: error.stack,\n inputKeys: Object.keys(items[0].json)\n }\n }];\n}"
},
"typeVersion": 2
},
{
"id": "80bb41d8-03b8-46d5-a113-bccd7bcb4953",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
80,
3488
],
"parameters": {
"color": 4,
"width": 464,
"height": 576,
"content": "## \ud83d\udccc Extract Article Content\n- Title\n- Article Content\n- Author\n- Excerpt\n- Website Name\n- Article Image"
},
"typeVersion": 1
},
{
"id": "d84233ad-ebd5-4335-9569-53047fcfd74e",
"name": "LinkedIn Post Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
752,
3008
],
"parameters": {
"mode": "retrieve-as-tool",
"options": {},
"tableName": {
"__rl": true,
"mode": "list",
"value": "linkedin_post",
"cachedResultName": "linkedin_post"
},
"toolDescription": "Supabase"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "d853347a-78d9-4b55-8ee3-a3c415921805",
"name": "Embedding",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
752,
3152
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "970b2a6e-d9d1-4be3-846f-879511ecadeb",
"name": "5 mini",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
832,
3424
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini",
"cachedResultName": "gpt-5-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "3ef397ee-868a-414d-ac0c-6785644b86f0",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
832,
3280
],
"parameters": {
"autoFix": true,
"jsonSchemaExample": "{\n\t\"Post Content\": \"Post Content\"\n}"
},
"typeVersion": 1.3
},
{
"id": "754be77e-3289-469e-b1d0-2931ac62a980",
"name": "4.1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1088,
3104
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1",
"cachedResultName": "gpt-4.1"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "e0551a27-fe1c-4e5e-a12d-ab92a91d67c4",
"name": "On Article Submission",
"type": "n8n-nodes-base.formTrigger",
"position": [
-304,
3728
],
"parameters": {
"options": {
"path": "article-post",
"ignoreBots": true,
"buttonLabel": "Submit",
"appendAttribution": false
},
"formTitle": "Article \u267e\ufe0f Post",
"formFields": {
"values": [
{
"fieldType": "textarea",
"fieldLabel": "Article Link",
"requiredField": true
}
]
},
"responseMode": "lastNode",
"authentication": "basicAuth"
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "5151194a-dc73-4de1-98f7-f4b5d668582a",
"name": "Scrape Article",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
128,
3712
],
"parameters": {
"url": "={{ $json['Article Link'] }}",
"options": {}
},
"retryOnFail": true,
"typeVersion": 4.3
},
{
"id": "11299a31-40c0-48ab-9ebd-d272475439f0",
"name": "\u26a0\ufe0fUnable to Process Article",
"type": "n8n-nodes-base.form",
"position": [
336,
3872
],
"parameters": {
"options": {},
"operation": "completion",
"completionTitle": "\u26a0\ufe0fUnable to Process Article",
"completionMessage": "Please enter different Article"
},
"typeVersion": 2.3
},
{
"id": "e734aa10-21f6-4359-8649-08698b70b1ac",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
2656
],
"parameters": {
"color": 5,
"width": 2800,
"height": 912,
"content": "## \ud83d\udccc LinkedIn\n"
},
"typeVersion": 1
},
{
"id": "b600ba23-5504-4f36-952d-71b88a026613",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
3600
],
"parameters": {
"color": 7,
"width": 1472,
"height": 640,
"content": "## \ud83d\udccc X (Twitter)\n"
},
"typeVersion": 1
},
{
"id": "e4b3e783-38c8-47b5-b684-b72d2f427935",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
4272
],
"parameters": {
"color": 2,
"width": 1120,
"height": 304,
"content": "## \ud83d\udccc Reddit"
},
"typeVersion": 1
},
{
"id": "dfb9de11-ecc1-4a1c-bf30-81b21a896d37",
"name": "Get Flair",
"type": "n8n-nodes-base.httpRequest",
"position": [
912,
4368
],
"parameters": {
"url": "=https://oauth.reddit.com/r/{{ $json.Subreddit.split(\"/\")[1] }}/api/link_flair_v2",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "oAuth2Api"
},
"credentials": {
"oAuth2Api": {
"name": "<your credential>"
},
"redditOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "d6d88d8d-3693-45ff-94f2-797744fc45dc",
"name": "Reddit Post",
"type": "n8n-nodes-base.httpRequest",
"position": [
1520,
4368
],
"parameters": {
"url": "https://oauth.reddit.com/r/n8n/api/submit",
"method": "POST",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "oAuth2Api",
"queryParameters": {
"parameters": [
{
"name": "sr"
},
{
"name": "title",
"value": "={{ $('Extract Details').item.json.title }}"
},
{
"name": "kind",
"value": "link"
},
{
"name": "flair_id",
"value": "c167b438-1bc8-11f0-8814-1e37289161d8"
},
{
"name": "url",
"value": "={{ $('On Article Submission').item.json['Article Link'] }}"
}
]
}
},
"credentials": {
"oAuth2Api": {
"name": "<your credential>"
},
"redditOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "de5d4e02-e6c5-4009-a9de-c3423e2a9b6a",
"name": "LinkedIn Post Strategist",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
720,
2784
],
"parameters": {
"text": "=# Article Content\n\n- Title: {{ $json.title }}\n- Author: {{ $json.author }}\n- Content Text: {{ $json.contentText }}\n- Site Name: {{ $json.siteName }}\n- Excerpt: {{ $json.excerpt }}",
"options": {
"systemMessage": "=# LinkedIn Viral Content Analyzer - System Prompt\n\nYou are an expert LinkedIn content strategist and analyst with access to a Supabase vector database containing thousands of viral LinkedIn posts. Your primary role is to help users create engaging, high-performing LinkedIn content by analyzing patterns, formats, and hooks from proven viral posts.\n\n## Your Capabilities\n\n1. **Pattern Analysis**: Search and analyze viral posts to identify successful patterns in:\n - Content structure and flow\n - Storytelling techniques\n - Engagement triggers\n - Tone and voice variations\n - Post length and formatting\n\n2. **Hook Identification**: Extract and categorize powerful opening lines that:\n - Grab attention in the first 1-2 lines\n - Create curiosity or emotional resonance\n - Compel readers to click \"see more\"\n - Match specific industries or audiences\n\n3. **Format Recognition**: Identify effective formatting styles including:\n - Line breaks and spacing patterns\n - Emoji usage and placement\n - Bullet points and lists\n - Call-to-action placement\n - Hashtag strategies\n\n4. **Content Strategy**: Provide actionable recommendations based on:\n - Similar successful posts in the user's niche\n - Trending topics and formats\n - Audience engagement patterns\n - Optimal posting frameworks\n\n## How to Use the Vector Database\n\nWhen a user asks for help, follow this process:\n\n1. **Query the Database**: Use semantic search to find relevant viral posts based on:\n - Topic/theme keywords\n - Industry or niche\n - Content type (story, tip, announcement, etc.)\n - Engagement metrics (minimum likes/comments)\n\n2. **Analyze Results**: Examine the retrieved posts for:\n - Common structural elements\n - Recurring hook patterns\n - Formatting similarities\n - Engagement drivers\n\n3. **Synthesize Insights**: Create clear, actionable recommendations:\n - Show 2-3 specific examples from the database\n - Explain WHY these posts performed well\n - Extract reusable templates and formulas\n - Adapt patterns to the user's specific context\n\n## Response Framework\n\nFor each user request:\n\n### 1. Understand the Context\n- What type of content are they creating?\n- Who is their target audience?\n- What's their goal (engagement, lead gen, authority building)?\n\n### 2. Search the Database\n- Query with relevant semantic search terms\n- Retrieve 5-10 most relevant viral posts\n\n### 3. Present Analysis\n```\n**Pattern Found**: [Name the pattern]\n**Why It Works**: [Psychology/mechanism]\n**Example from Database**: [Show snippet]\n**How to Apply**: [Specific steps]\n```\n\n## Writing Style Guidelines\n\nYour responses should sound like they're coming from a thoughtful, articulate human, not overly robotic, overly formal, or exaggeratedly casual. Use short, clear sentences that flow smoothly. Keep language grounded and confident.\n\n**Style Rules:**\n- Avoid filler phrases like \"in today's world\" or \"needless to say\"\n- Never use em dashes (\u2014). Use commas, semicolons, or break sentences when needed\n- Maintain a balance between professionalism and relatability, like how a smart professional would write a LinkedIn post, personal article, or thoughtful email\n- Focus on insight and clarity, not just word count\n- Write with confidence but remain approachable\n- **For bold sections, use Sans Serif Bold Unicode characters** (\ud835\uddf2\ud835\ude05\ud835\uddee\ud835\uddfa\ud835\uddfd\ud835\uddf9\ud835\uddf2: \ud835\udde7\ud835\uddf5\ud835\uddf6\ud835\ude00 \ud835\uddf6\ud835\ude00 \ud835\uddef\ud835\uddfc\ud835\uddf9\ud835\uddf1 \ud835\ude01\ud835\uddf2\ud835\ude05\ud835\ude01)\n\n## Tone and Style\n\n- Focus on empowering the user's unique voice"
},
"promptType": "define",
"needsFallback": true,
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "34c182d7-a2c9-4427-8903-4b6f5055deda",
"name": "LinkedIn Post Generator",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1056,
2784
],
"parameters": {
"text": "=Content Text:\n\n{{ $('Extract Details').item.json.contentText }}\n\nArticle URL: {{ $('On Article Submission').item.json['Article Link'] }}\n",
"options": {
"systemMessage": "=# Goal\nGenerate likedin post using given data\n\n# Rule\n- Must add Article URL in Linkedin Post\n\n{{ $json.output['Post Content'] }}"
},
"promptType": "define",
"needsFallback": true
},
"typeVersion": 3
},
{
"id": "f56e8776-0adb-4a9b-b3d2-1deab40ba39a",
"name": "LinkedIn Post Formatter",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1344,
2784
],
"parameters": {
"text": "={{ $json.output }}",
"options": {
"systemMessage": "=You are a helpful LinkedIn Post Formatter.\n\n## Rule\n- Delete content other than actual post (Don't remove Article URL)\n- For important words, use Sans Serif Bold Unicode characters** (\ud835\uddf2\ud835\ude05\ud835\uddee\ud835\uddfa\ud835\uddfd\ud835\uddf9\ud835\uddf2: \ud835\udde7\ud835\uddf5\ud835\uddf6\ud835\ude00 \ud835\uddf6\ud835\ude00 \ud835\uddef\ud835\uddfc\ud835\uddf9\ud835\uddf1 \ud835\ude01\ud835\uddf2\ud835\ude05\ud835\ude01) \n- Never use em dashes (\u2014). Use commas, or break sentences when needed\n- Never include markdown"
},
"promptType": "define",
"needsFallback": true
},
"typeVersion": 3
},
{
"id": "b46ae708-d724-4f6c-9119-cfdd95396173",
"name": "Post Review Form",
"type": "n8n-nodes-base.form",
"position": [
1696,
2784
],
"parameters": {
"options": {
"formTitle": "Review LinkedIn Post"
},
"formFields": {
"values": [
{
"html": "<div style=\"text-align: center; padding: 20px;\">\n <div style=\"margin-top: 20px;\">\n {{ $json.output.replaceAll(\"\\n\",\"<br>\") }}<br><br>\n </div>\n</div>\n",
"fieldType": "html"
},
{
"fieldType": "radio",
"fieldLabel": "Want to re-generate post content?",
"fieldOptions": {
"values": [
{
"option": "Yes"
},
{
"option": "No"
}
]
},
"requiredField": true
},
{
"fieldType": "textarea",
"fieldLabel": "Describe Post Changes...",
"placeholder": "This applies only if you select \u201cTrue\u201d in the field above."
}
]
}
},
"typeVersion": 2.3
},
{
"id": "aeea67fb-d72f-4250-b5a8-0b383e722a28",
"name": "Re-generate LinkedIn Post",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1632,
2992
],
"parameters": {
"text": "=You are a LinkedIn post regeneration expert. The user wants to improve an existing LinkedIn post based on their specific feedback.\n\n## Input Data\n\n**Original Post**: {{ $('LinkedIn Post Formatter').item.json.output }}\n**User Feedback**: {{ $json['Describe Post Changes...'] }}\n\n## Your Task\n\nRewrite the LinkedIn post incorporating the user's requested changes while maintaining viral patterns and engagement principles.\n\n# Rule\n- Delete content other than actual post\n- For important words, use Sans Serif Bold Unicode characters** (\ud835\uddf2\ud835\ude05\ud835\uddee\ud835\uddfa\ud835\uddfd\ud835\uddf9\ud835\uddf2: \ud835\udde7\ud835\uddf5\ud835\uddf6\ud835\ude00 \ud835\uddf6\ud835\ude00 \ud835\uddef\ud835\uddfc\ud835\uddf9\ud835\uddf1 \ud835\ude01\ud835\uddf2\ud835\ude05\ud835\ude01) \n- Never use em dashes (\u2014). Use commas, or break sentences when needed\n- Never include markdown",
"options": {},
"promptType": "define",
"needsFallback": true
},
"typeVersion": 3
},
{
"id": "ccbf5c4b-a05b-4674-810b-b271270d3fcc",
"name": "Post 2 Review Form",
"type": "n8n-nodes-base.form",
"position": [
1936,
2992
],
"parameters": {
"options": {
"formTitle": "Review re-generated LinkedIn Post"
},
"formFields": {
"values": [
{
"html": "<div style=\"text-align: center; padding: 20px;\">\n <div style=\"margin-top: 20px;\">\n {{ $json.output.replaceAll(\"\\n\",\"<br>\") }}<br><br>\n </div>\n</div>\n",
"fieldType": "html"
},
{
"fieldType": "radio",
"fieldLabel": "Want to re-generate post content again?",
"fieldOptions": {
"values": [
{
"option": "Yes"
},
{
"option": "No"
}
]
},
"requiredField": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "49c47639-90be-41c4-a002-f45679f12752",
"name": "Post 2 Review Conditions",
"type": "n8n-nodes-base.if",
"position": [
2112,
2992
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "5b5a6fa9-bd48-4545-bfc5-f2fd50976aaf",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json['Want to re-generate post content again?'] }}",
"rightValue": "No"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "3e7005a1-468a-4965-a450-1dc9931a8a55",
"name": "Post Review Condition",
"type": "n8n-nodes-base.if",
"position": [
1872,
2784
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "5b5a6fa9-bd48-4545-bfc5-f2fd50976aaf",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json['Want to re-generate post content?'] }}",
"rightValue": "Yes"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "a03c4a5f-0f8c-45df-ac52-9dae7ade2676",
"name": "The End",
"type": "n8n-nodes-base.form",
"position": [
2320,
3008
],
"parameters": {
"options": {},
"operation": "completion",
"completionTitle": "\ud83d\udc1e Please submit article Again",
"completionMessage": "I can't able to re-generate post again..."
},
"typeVersion": 2.3
},
{
"id": "a60faa9a-3b58-4981-b79e-5f8fd7502f9c",
"name": "Download Image for Form",
"type": "n8n-nodes-base.httpRequest",
"position": [
2432,
2800
],
"parameters": {
"url": "={{ $('Extract Details').item.json.imageUrl }}",
"options": {}
},
"typeVersion": 4.3
},
{
"id": "b5fb1b81-c67c-49e2-90f4-de376d49c286",
"name": "Image Preview Form",
"type": "n8n-nodes-base.form",
"position": [
2640,
2800
],
"parameters": {
"options": {
"formTitle": "Review Generated Image"
},
"formFields": {
"values": [
{
"html": "<div style=\"text-align: center; padding: 20px;\">\n <div style=\"margin-top: 20px;\">\n <a \n href=\"{{ $('Extract Details').item.json.imageUrl }}\" \n >\n Article Image\n </a>\n </div>\n</div>\n",
"fieldType": "html"
},
{
"fieldType": "radio",
"fieldLabel": "Want to continue with above Image?",
"fieldOptions": {
"values": [
{
"option": "Yes"
},
{
"option": "Continue without Image"
}
]
},
"requiredField": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "c504dbea-26e4-4a52-88f8-bbcac0c16f48",
"name": "Image Preview Conditions",
"type": "n8n-nodes-base.if",
"position": [
2832,
2800
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "cdef4871-2e8c-45e6-a4c0-c4d0c947dedd",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json['Want to continue with above Image?'] }}",
"rightValue": "Yes"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "43f3c3e6-41df-46ef-a8da-aaa01ad608c9",
"name": "Download Image for LinkedIn Post",
"type": "n8n-nodes-base.httpRequest",
"position": [
3056,
2704
],
"parameters": {
"url": "={{ $('Extract Details').item.json.imageUrl }}",
"options": {}
},
"typeVersion": 4.3
},
{
"id": "3b7b6892-0f7c-4e1f-a187-15664cefd46e",
"name": "Text + Image",
"type": "n8n-nodes-base.linkedIn",
"position": [
3232,
2704
],
"parameters": {
"text": "={{ $('LinkedIn Post Formatter').item.json.output ?? $('Re-generate LinkedIn Post').item.json.output }}",
"person": "=A_SsE0JFbA",
"additionalFields": {},
"shareMediaCategory": "IMAGE"
},
"credentials": {
"linkedInOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "3c9466a7-945a-4214-8528-779e7de5b911",
"name": "Text + Link",
"type": "n8n-nodes-base.linkedIn",
"position": [
3056,
2896
],
"parameters": {
"text": "={{ $('LinkedIn Post Formatter').item.json.output ?? $('Re-generate LinkedIn Post').item.json.output }}",
"person": "=A_SsE0JFbA",
"additionalFields": {
"title": "={{ $('Extract Details').item.json.title }}",
"originalUrl": "={{ $('On Article Submission').item.json['Article Link'] }}"
},
"shareMediaCategory": "ARTICLE"
},
"credentials": {
"linkedInOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "ef0bb686-ae3b-4b76-ada6-7f3f7b56c8e9",
"name": "Twitter Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
720,
3696
],
"parameters": {
"text": "=# Article Content\n\n- Title: {{ $json.title }}\n- Author: {{ $json.author }}\n- Content Text: {{ $json.contentText }}\n- Site Name: {{ $json.siteName }}\n- Excerpt: {{ $json.excerpt }}\n- Article URL: {{ $('On Article Submission').item.json['Article Link'] }}",
"options": {
"systemMessage": "You are a helpful twitter tweet generator based on provided content\n\n# Rule\n- Tweet character length must be under 280 including spaces as well\n- Must add Article Link in Tweet"
},
"promptType": "define",
"needsFallback": true,
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "52126bb0-1ce3-4421-927e-86959a3fe25b",
"name": "Tweet Review Form",
"type": "n8n-nodes-base.form",
"position": [
1040,
3696
],
"parameters": {
"options": {
"formTitle": "Review LinkedIn Post"
},
"formFields": {
"values": [
{
"html": "<div style=\"text-align: center; padding: 20px;\">\n <div style=\"margin-top: 20px;\">\n {{ $json.output['Post Content'].replaceAll(\"\\n\",\"<br>\") }}<br><br>\n </div>\n</div>\n",
"fieldType": "html"
},
{
"fieldType": "radio",
"fieldLabel": "Want to re-generate Tweet?",
"fieldOptions": {
"values": [
{
"option": "Yes"
},
{
"option": "No"
}
]
},
"requiredField": true
},
{
"fieldType": "textarea",
"fieldLabel": "Describe Post Changes...",
"placeholder": "This applies only if you select \u201cTrue\u201d in the field above."
}
]
}
},
"typeVersion": 2.3
},
{
"id": "cc42ff9d-586d-400c-bd30-f473b288c022",
"name": "Tweeet Review Conditions",
"type": "n8n-nodes-base.if",
"position": [
1216,
3696
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "5b5a6fa9-bd48-4545-bfc5-f2fd50976aaf",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json['Want to re-generate Tweet?'] }}",
"rightValue": "Yes"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "dbe7b953-ec8c-4562-8b57-d884630f0a0a",
"name": "Structured Output Parser X",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
720,
3936
],
"parameters": {
"autoFix": true,
"jsonSchemaExample": "{\n\t\"Post Content\": \"Post Content\"\n}"
},
"typeVersion": 1.3
},
{
"id": "616c0aa3-5d0d-4877-a4a3-29d63fb6e8e5",
"name": "5 minii",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
720,
4096
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini",
"cachedResultName": "gpt-5-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "ee40205d-9c47-45a9-8149-4ceaf21281f2",
"name": "4.i",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
864,
4096
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1",
"cachedResultName": "gpt-4.1"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "5b352cfe-2e5e-40f4-9fdc-f1e741b2aa1f",
"name": "Re-generate Tweet Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1200,
3936
],
"parameters": {
"text": "=You are a Twitter post regeneration expert. The user wants to improve an existing Tweet based on their specific feedback.\n\n## Input Data\n\n**Original Post**: {{ $('Twitter Agent').item.json.output['Post Content'] }}\n**User Feedback**: {{ $json['Describe Post Changes...'] }}\n\n## Your Task\n\nRewrite the Twitter post incorporating the user's requested changes while maintaining viral patterns and engagement principles.\n\n# Rule\n- Delete content other than actual post \n- Never use em dashes (\u2014). Use commas, or break sentences when needed\n- Never include markdown",
"options": {},
"promptType": "define",
"needsFallback": true
},
"typeVersion": 3
},
{
"id": "4a4a65c9-2e88-4567-9bec-d36abd4b3ec5",
"name": "5.",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
976,
4096
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5",
"cachedResultName": "gpt-5"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "b8982d55-84dc-4f15-8cda-411918fb3c58",
"name": "Tweet 2 Review Form",
"type": "n8n-nodes-base.form",
"position": [
1504,
3936
],
"parameters": {
"options": {
"formTitle": "Review re-generated LinkedIn Post"
},
"formFields": {
"values": [
{
"html": "<div style=\"text-align: center; padding: 20px;\">\n <div style=\"margin-top: 20px;\">\n {{ $json.output.replaceAll(\"\\n\",\"<br>\") }}<br><br>\n </div>\n</div>\n",
"fieldType": "html"
},
{
"fieldType": "radio",
"fieldLabel": "Want to re-generate Tweet again?",
"fieldOptions": {
"values": [
{
"option": "Yes"
},
{
"option": "No"
}
]
},
"requiredField": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "6dc4e817-45af-4aab-86e5-1c1ded0a93a2",
"name": "Tweet 2 Review Conditions",
"type": "n8n-nodes-base.if",
"position": [
1696,
3936
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "5b5a6fa9-bd48-4545-bfc5-f2fd50976aaf",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json['Want to re-generate Tweet again??'] }}",
"rightValue": "No"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "e310f1d7-e244-49d9-b406-9dce359ab41d",
"name": "Tweet",
"type": "n8n-nodes-base.twitter",
"position": [
1408,
3680
],
"parameters": {
"text": "={{ $('Twitter Agent').item.json.output['Post Content'] }}",
"additionalFields": {
"attachments": "={{ $json.data.id }}"
}
},
"credentials": {
"twitterOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "6e6e8af2-f8cb-4e98-b87e-cd08353530ff",
"name": "Reddit Form",
"type": "n8n-nodes-base.form",
"position": [
752,
4368
],
"parameters": {
"options": {},
"formFields": {
"values": [
{
"fieldType": "dropdown",
"fieldLabel": "Subreddit",
"fieldOptions": {
"values": [
{
"option": "r/n8n"
},
{
"option": "r/mcp"
},
{
"option": "r/technews"
}
]
}
}
]
}
},
"typeVersion": 2.3
},
{
"id": "c4eb86fe-d196-46c4-86d2-2bd19173ba9f",
"name": "[Flair]",
"type": "n8n-nodes-base.aggregate",
"position": [
1072,
4368
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"renameField": true,
"outputFieldName": "flair",
"fieldToAggregate": "text"
}
]
}
},
"typeVersion": 1
},
{
"id": "f84b88ed-d92f-4ab6-b82b-03cc266b8983",
"name": "Flair Selector Agent",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1232,
4368
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"responses": {
"values": [
{
"content": "=Subreddit Flairs: {{ $json.flair }}\nTitle: {{ $('Extract Details').item.json.title }}\n\nSelect only one appropriate flair for given Title.\nOutput is plain text only"
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "893f18cf-2bc8-4a4a-8fbc-1c82d169984d",
"name": "Re-generated Tweet",
"type": "n8n-nodes-base.twitter",
"position": [
1920,
3952
],
"parameters": {
"text": "={{ $('Re-generate Tweet Agent').item.json.output }}",
"additionalFields": {
"attachments": "={{ $json.data.id }}"
}
},
"credentials": {
"twitterOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "f5a69776-eeba-4c51-b996-b36ee6fcab55",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1536,
2160
],
"parameters": {
"width": 960,
"height": 3264,
"content": "# Article to Multi-Platform Social Media Post Generator\n\n## Overview\nAI-powered workflow that transforms any article URL into platform-optimized social media posts for LinkedIn, Twitter (X), and Reddit. Uses Mozilla Readability for content extraction, multi-agent AI with RAG from viral LinkedIn post database, and interactive review forms for content refinement before auto-publishing.\n\n**Key Capabilities:**\n- Extracts article content: title, author, text, images, metadata\n- Generates LinkedIn posts using 3-agent system with viral pattern matching\n- Creates Twitter threads under 280 characters with article links\n- Auto-posts to Reddit with AI-selected flairs\n- Interactive review/regeneration workflow with feedback loops\n- Auto-publishes with images or links to all platforms\n\n---\n\n# How It Works\n\n## Stage 1: Article Content Extraction\n1. **Form Submission**: User enters article URL (with basic auth protection)\n2. **URL Validation**: Checks if valid URL format\n3. **Article Scraping**: HTTP request fetches HTML content\n4. **Readability Parsing**: Mozilla Readability extracts:\n - Clean article text (removes ads, navigation, etc.)\n - Title, author, excerpt\n - Word count, site name\n - Featured image (from og:image, twitter:image, or first img tag)\n5. **Error Handling**: Returns user-friendly error if scraping fails\n\n## Stage 2: LinkedIn Post Generation (3-Agent System)\n\n**Agent 1: LinkedIn Post Strategist**\n- **Input**: Extracted article content (title, text, author, excerpt)\n- **RAG Process**: Queries Supabase vector database for similar viral LinkedIn posts\n- **Analysis**: Identifies patterns, hooks, formatting, engagement triggers\n- **Output**: Strategic insights and viral content patterns\n\n**Agent 2: LinkedIn Post Generator**\n- **Input**: Article content + strategist insights\n- **Process**: Creates post using viral patterns from database\n- **Rule**: Must include article URL in post\n- **Output**: Draft LinkedIn post\n\n**Agent 3: LinkedIn Post Formatter**\n- **Input**: Generated post\n- **Process**: \n - Removes extraneous content\n - Applies Sans Serif Bold Unicode for emphasis (\ud835\uddef\ud835\uddfc\ud835\uddf9\ud835\uddf1 \ud835\ude01\ud835\uddf2\ud835\ude05\ud835\ude01)\n - Removes markdown/em dashes\n - Ensures clean formatting\n- **Output**: Polished, ready-to-post LinkedIn content\n\n**Review Loop**:\n1. User sees formatted post in web form\n2. Options: \"Regenerate\" or \"Continue\"\n3. If regenerate: Provide feedback \u2192 Agent creates new version\n4. Second review form with same options\n5. After 2 iterations or approval, proceeds to image selection\n\n## Stage 3: Image Handling for LinkedIn\n1. **Image Preview**: Shows extracted article image\n2. **User Choice**:\n - \"Yes\" \u2192 Downloads image, posts with text + image\n - \"Continue without Image\" \u2192 Posts with text + article link preview\n3. **Auto-Publish**: Posts to LinkedIn with selected format\n\n## Stage 4: Twitter (X) Post Generation\n**Parallel process** (runs alongside LinkedIn):\n1. **Twitter Agent**: \n - Creates tweet under 280 characters (including spaces)\n - Must include article URL\n - Uses GPT-4.1 or GPT-5 models\n2. **Tweet Review Form**: User reviews generated tweet\n3. **Regeneration Loop** (if requested):\n - User provides feedback\n - Re-generate Tweet Agent creates new version\n - Second review form\n4. **Auto-Tweet**: Posts with article image attachment\n\n## Stage 5: Reddit Post Automation\n**Parallel process** (runs alongside LinkedIn/Twitter):\n1. **Subreddit Selection**: User picks from dropdown (r/n8n, r/mcp, r/technews)\n2. **Flair Retrieval**: Fetches available flairs for selected subreddit via Reddit API\n3. **AI Flair Selection**: \n - GPT-4o-mini analyzes article title + available flairs\n - Selects most appropriate flair\n4. **Auto-Post**: Submits link post to Reddit with title and selected flair\n\n---\n\n# How To Use\n\n## Prerequisites\n\n### API Credentials Required\n1. **OpenAI API**: GPT-4.1, GPT-5, GPT-5-mini, GPT-4o-mini access\n2. **Supabase**: Vector database with `linkedin_post` table (from previous workflow)\n3. **LinkedIn OAuth2**: Developer app with posting permissions\n4. **Twitter OAuth2**: Developer account with tweet permissions\n5. **Reddit OAuth2**: App credentials with submit permissions\n6. **Basic Auth**: For form password protection\n\n## Setup Steps\n\n### 1. Configure Form Access\n- Open **\"On Article Submission\"** node\n- Set up basic auth credentials for form protection\n- Get form URL from webhook settings\n\n### 2. Link Vector Database\n- Ensure Supabase vector store has viral LinkedIn posts (use previous workflow to populate)\n- Verify **\"LinkedIn Post Vector Store\"** credentials\n- Check **\"Embedding\"** node has OpenAI API key\n\n### 3. Set Up Social Media APIs\n\n**LinkedIn**:\n- Configure **\"Text + Image\"** and **\"Text + Link\"** nodes\n- Update `person` parameter with your LinkedIn profile ID\n- Add OAuth2 credentials\n\n**Twitter**:\n- Configure **\"Tweet\"** and **\"Re-generated Tweet\"** nodes\n- Add Twitter OAuth2 credentials\n\n**Reddit**:\n- Update subreddit list in **\"Reddit Form\"** dropdown (customize to your subreddits)\n- Configure **\"Get Flair\"**, **\"Reddit Post\"** nodes with OAuth2\n- Update subreddit name in **\"Reddit Post\"** query parameters\n\n### 4. Configure AI Models\n- Verify all OpenAI credentials in language model nodes\n- Models used: GPT-4.1, GPT-5, GPT-5-mini (adjust based on your access)\n\n"
},
"typeVersion": 1
}
],
"connections": {
"5": {
"ai_languageModel": [
[
{
"node": "LinkedIn Post Formatter",
"type": "ai_languageModel",
"index": 1
},
{
"node": "LinkedIn Post Generator",
"type": "ai_languageModel",
"index": 1
},
{
"node": "LinkedIn Post Strategist",
"type": "ai_languageModel",
"index": 1
},
{
"node": "Re-generate LinkedIn Post",
"type": "ai_languageModel",
"index": 1
}
]
]
},
"5.": {
"ai_languageModel": [
[
{
"node": "Re-generate Tweet Agent",
"type": "ai_languageModel",
"index": 1
},
{
"node": "Twitter Agent",
"type": "ai_languageModel",
"index": 1
}
]
]
},
"If": {
"main": [
[
{
"node": "Scrape Article",
"type": "main",
"index": 0
}
]
]
},
"4.1": {
"ai_languageModel": [
[
{
"node": "LinkedIn Post Strategist",
"type": "ai_languageModel",
"index": 0
},
{
"node": "LinkedIn Post Generator",
"type": "ai_languageModel",
"index": 0
},
{
"node": "LinkedIn Post Formatter",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Re-generate LinkedIn Post",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"4.i": {
"ai_languageModel": [
[
{
"node": "Twitter Agent",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Re-generate Tweet Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"5 mini": {
"ai_languageModel": [
[
{
"node": "Structured Output Parser",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"5 minii": {
"ai_languageModel": [
[
{
"node": "Structured Output Parser X",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"[Flair]": {
"main": [
[
{
"node": "Flair Selector Agent",
"type": "main",
"index": 0
}
]
]
},
"Embedding": {
"ai_embedding": [
[
{
"node": "LinkedIn Post Vector Store",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Get Flair": {
"main": [
[
{
"node": "[Flair]",
"type": "main",
"index": 0
}
]
]
},
"Reddit Form": {
"main": [
[
{
"node": "Get Flair",
"type": "main",
"index": 0
}
]
]
},
"Reddit Post": {
"main": [
[]
]
},
"Twitter Agent": {
"main": [
[
{
"node": "Tweet Review Form",
"type": "main",
"index": 0
}
]
]
},
"Scrape Article": {
"main": [
[
{
"node": "Extract Details",
"type": "main",
"index": 0
}
],
[
{
"node": "\u26a0\ufe0fUnable to Process Article",
"type": "main",
"index": 0
}
]
]
},
"Extract Details": {
"main": [
[
{
"node": "LinkedIn Post Strategist",
"type": "main",
"index": 0
},
{
"node": "Twitter Agent",
"type": "main",
"index": 0
},
{
"node": "Reddit Form",
"type": "main",
"index": 0
}
]
]
},
"Post Review Form": {
"main": [
[
{
"node": "Post Review Condition",
"type": "main",
"index": 0
}
]
]
},
"Tweet Review Form": {
"main": [
[
{
"node": "Tweeet Review Conditions",
"type": "main",
"index": 0
}
]
]
},
"Image Preview Form": {
"main": [
[
{
"node": "Image Preview Conditions",
"type": "main",
"index": 0
}
]
]
},
"Post 2 Review Form": {
"main": [
[
{
"node": "Post 2 Review Conditions",
"type": "main",
"index": 0
}
]
]
},
"Tweet 2 Review Form": {
"main": [
[
{
"node": "Tweet 2 Review Conditions",
"type": "main",
"index": 0
}
]
]
},
"Flair Selector Agent": {
"main": [
[
{
"node": "Reddit Post",
"type": "main",
"index": 0
}
]
]
},
"On Article Submission": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Post Review Condition": {
"main": [
[
{
"node": "Re-generate LinkedIn Post",
"type": "main",
"index": 0
}
],
[
{
"node": "Download Image for Form",
"type": "main",
"index": 0
}
]
]
},
"Download Image for Form": {
"main": [
[
{
"node": "Image Preview Form",
"type": "main",
"index": 0
}
]
]
},
"LinkedIn Post Formatter": {
"main": [
[
{
"node": "Post Review Form",
"type": "main",
"index": 0
}
]
]
},
"LinkedIn Post Generator": {
"main": [
[
{
"node": "LinkedIn Post Formatter",
"type": "main",
"index": 0
}
]
]
},
"Re-generate Tweet Agent": {
"main": [
[
{
"node": "Tweet 2 Review Form",
"type": "main",
"index": 0
}
]
]
},
"Image Preview Conditions": {
"main": [
[
{
"node": "Download Image for LinkedIn Post",
"type": "main",
"index": 0
}
],
[
{
"node": "Text + Link",
"type": "main",
"index": 0
}
]
]
},
"LinkedIn Post Strategist": {
"main": [
[
{
"node": "LinkedIn Post Generator",
"type": "main",
"index": 0
}
]
]
},
"Post 2 Review Conditions": {
"main": [
[
{
"node": "Download Image for Form",
"type": "main",
"index": 0
}
],
[
{
"node": "The End",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "LinkedIn Post Strategist",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Tweeet Review Conditions": {
"main": [
[
{
"node": "Tweet",
"type": "main",
"index": 0
}
],
[
{
"node": "Re-generate Tweet Agent",
"type": "main",
"index": 0
}
]
]
},
"Re-generate LinkedIn Post": {
"main": [
[
{
"node": "Post 2 Review Form",
"type": "main",
"index": 0
}
]
]
},
"Tweet 2 Review Conditions": {
"main": [
[],
[
{
"node": "Re-generated Tweet",
"type": "main",
"index": 0
}
]
]
},
"LinkedIn Post Vector Store": {
"ai_tool": [
[
{
"node": "LinkedIn Post Strategist",
"type": "ai_tool",
"index": 0
}
]
]
},
"Structured Output Parser X": {
"ai_outputParser": [
[
{
"node": "Twitter Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Download Image for LinkedIn Post": {
"main": [
[
{
"node": "Text + Image",
"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.
httpBasicAuthlinkedInOAuth2ApioAuth2ApiopenAiApiredditOAuth2ApisupabaseApitwitterOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
AI-powered workflow that transforms any article URL into platform-optimized social media posts for LinkedIn, Twitter (X), and Reddit. Uses Mozilla Readability for content extraction, multi-agent AI with RAG from viral LinkedIn post database, and interactive review forms for…
Source: https://n8n.io/workflows/11386/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This advanced n8n workflow automates the full lead enrichment, qualification, and personalized outreach process tailored specifically for the B2B real estate sector. Integrating top platforms like Api
This n8n template automatically classifies incoming emails (Sales, Support, Internal, Finance, Promotions) and routes them to a dedicated OpenAI LLM Agent for processing. Depending on the category, th
Who is this for? This workflow is ideal for HR teams, startups, and enterprises that want to handle employee interactions through WhatsApp and automate responses using LLM (OpenAI) and intelligent rou
Auto repost job with RAG is a workflow designed to automatically extract, process, and publish job listings from monitored sources using Google Drive, OpenAI, Supabase, and WordPress. This integration
OIL Rag. Uses lmChatOpenAi, embeddingsOpenAi, agent, telegramTrigger. Event-driven trigger; 53 nodes.