AutomationFlowsAI & RAG › Auto-summarize Blog Posts to Social Media with Gemma and Postiz

Auto-summarize Blog Posts to Social Media with Gemma and Postiz

ByKyriakos Papadopoulos @lzrd on n8n.io

This workflow automates fetching the latest post from a Blogspot RSS feed, summarizes it with an LLM (e.g., Gemma via Ollama), extracts and uploads an image, generates three relevant hashtags, and posts to Facebook, LinkedIn, X (Twitter), and Instagram via the Postiz API.

Cron / scheduled trigger★★★★★ complexityAI-powered35 nodesN8N Nodes PostizRSS Feed ReadChain LlmLm OllamaHTTP RequestEdit Image
AI & RAG Trigger: Cron / scheduled Nodes: 35 Complexity: ★★★★★ AI nodes: yes Added:

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

This workflow follows the Chainllm → HTTP Request 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": "5qiiLNNCnMfa0ACi",
  "name": "Auto-Summarize Blog Posts to Social Media with Gemma and Postiz",
  "tags": [],
  "nodes": [
    {
      "id": "4de18e8b-5e69-4635-8f9e-3c4b12ab82e9",
      "name": "Postiz (Create Post)",
      "type": "n8n-nodes-postiz.postiz",
      "disabled": true,
      "position": [
        4656,
        640
      ],
      "parameters": {
        "date": "2025-08-06T14:45:00",
        "posts": {
          "post": [
            {
              "value": {
                "contentItem": [
                  {
                    "image": {
                      "imageItem": [
                        {
                          "id": "={{ $('Upload Image to Postiz').item.json.id }}",
                          "path": "={{ $('Upload Image to Postiz').item.json.path }}"
                        }
                      ]
                    },
                    "content": "={{ $json.text ? $json.text : 'NO_TEXT' }} {{ $json.link ? $json.link : 'NO_LINK' }}"
                  }
                ]
              },
              "integrationId": "cmdt7mm7c0001uq6yoangez5f"
            },
            {
              "value": {
                "contentItem": [
                  {
                    "image": {
                      "imageItem": [
                        {
                          "id": "={{ $('Upload Image to Postiz').item.json.id }}",
                          "path": "={{ $('Upload Image to Postiz').item.json.path }}"
                        }
                      ]
                    },
                    "content": "={{ $json.text ? $json.text : 'NO_TEXT' }} {{ $json.link ? $json.link : 'NO_LINK' }}"
                  }
                ]
              },
              "integrationId": "cmdrm2h2w0001mu75dqdghjh3"
            },
            {
              "value": {
                "contentItem": [
                  {
                    "image": {
                      "imageItem": [
                        {
                          "id": "={{ $('Upload Image to Postiz').item.json.id }}",
                          "path": "={{ $('Upload Image to Postiz').item.json.path }}"
                        }
                      ]
                    },
                    "content": "={{ $json.text ? $json.text : 'NO_TEXT' }} {{ $json.link ? $json.link : 'NO_LINK' }}"
                  }
                ]
              },
              "integrationId": "cmdt8yk610001ql6kgzaipjy7"
            },
            {
              "value": {
                "contentItem": [
                  {
                    "image": {
                      "imageItem": [
                        {
                          "id": "={{ $('Upload Image to Postiz').item.json.id }}",
                          "path": "={{ $('Upload Image to Postiz').item.json.path }}"
                        }
                      ]
                    },
                    "content": "={{ $json.text ? $json.text : 'NO_TEXT' }} {{ $json.link ? $json.link : 'NO_LINK' }}"
                  }
                ]
              },
              "settings": {
                "setting": [
                  {
                    "key": "post_type",
                    "stringValue": "post"
                  },
                  {
                    "key": "collaborators",
                    "stringValue": "[]"
                  },
                  {
                    "key": "media_type",
                    "stringValue": "IMAGE"
                  },
                  {
                    "key": "shortLink",
                    "valueType": "boolean"
                  }
                ]
              },
              "integrationId": "cmdt88b790003uq6y4lyk97o0"
            }
          ]
        }
      },
      "executeOnce": false,
      "notesInFlow": false,
      "retryOnFail": false,
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "6f8f2953-bb6d-46f0-8af7-16ffcbf8341f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        64
      ],
      "parameters": {
        "content": "Replace 'Blog's Name' and the URL with your own RSS feed details (e.g., your blog's RSS URL)."
      },
      "typeVersion": 1
    },
    {
      "id": "3c46789a-12cc-4a29-ab28-68b5a963c8f2",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        48
      ],
      "parameters": {
        "content": "This node fetches the RSS feed. Ensure the URL matches your blog\u2014update if needed for custom feeds."
      },
      "typeVersion": 1
    },
    {
      "id": "dcbe57b4-3866-4053-9da1-874b2b7d6947",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3472,
        48
      ],
      "parameters": {
        "width": 256,
        "content": "Customize the LLM prompt for your content niche (e.g., change tone, fallback summary, or hashtag style to fit your blog's theme)."
      },
      "typeVersion": 1
    },
    {
      "id": "93f63cde-e055-42dd-90b4-d66637339258",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3488,
        384
      ],
      "parameters": {
        "content": "Select your preferred Ollama model (e.g., gemma3:12b or alternatives like LLaMA). Update credentials with your local Ollama API setup."
      },
      "typeVersion": 1
    },
    {
      "id": "68bd2325-938e-42c5-88ef-46a8c556871f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3216,
        48
      ],
      "parameters": {
        "content": "Adjust maxChars calculation, hashtag reserve (default 50 chars), or buffers if using different platforms/limits (e.g., increase for longer hashtags)."
      },
      "typeVersion": 1
    },
    {
      "id": "b2e53420-7251-4a54-b744-b3c2b94aa4e4",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4256,
        48
      ],
      "parameters": {
        "content": "Update validation logic if your inputs vary (e.g., add checks for custom fields like text length, link format, or image presence)."
      },
      "typeVersion": 1
    },
    {
      "id": "9387a000-5013-4a4f-8a6e-3a1de3808cb0",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4544,
        -160
      ],
      "parameters": {
        "width": 288,
        "height": 368,
        "content": "This node posts to social platforms via Postiz API\u2014crucial for the workflow!\n- Update URL if your Postiz instance differs (e.g., self-hosted endpoint).\n- Set authentication: Add your Postiz API credentials (no hardcoding keys!).\n- Customize jsonBody: Replace integration IDs (e.g., \"cmdt7mm7c0001uq6yoangez5f\" for Facebook) with your own from Postiz dashboard.\n- Adjust platform settings (e.g., \"__type\", \"post_type\") if adding/removing channels.\nTest with a sample post to verify."
      },
      "typeVersion": 1
    },
    {
      "id": "9454c1b1-4780-44c8-b2fa-a8122fd3d145",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4480,
        448
      ],
      "parameters": {
        "width": 480,
        "height": 400,
        "content": "The \"Postiz (Create Post)\" node is deactivated due to a compatibility bug with Instagram's JSON payload in the Postiz-n8n integration (see GitHub issue https://github.com/gitroomhq/postiz-n8n/issues/7), which prevents reliable posting. Instead, the \"HTTP Request\" node directly calls the Postiz API for greater control and workaround flexibility. On one hand, this ensures stable posting across platforms; on the other, it requires manual JSON tweaks, potentially increasing setup complexity for users."
      },
      "typeVersion": 1
    },
    {
      "id": "885a82ba-0ba1-47c9-99bf-44aeb21f7b78",
      "name": "Split RSS Feed URLs into Items",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        384,
        192
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "[\"Blog's Name\"]"
      },
      "typeVersion": 1
    },
    {
      "id": "eb7a97de-e95e-43f9-81f1-1559e000f7d8",
      "name": "Fetch Latest RSS Feed Content",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        576,
        192
      ],
      "parameters": {
        "url": "https://blogsname.blogspot.com/feeds/posts/default",
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "c2c32dda-af3a-4988-bc6c-1a85ebfca720",
      "name": "Normalize RSS Fields (Content & Link)",
      "type": "n8n-nodes-base.set",
      "position": [
        3072,
        176
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "00d04dc1-3f58-4027-8807-83d9e1f4fdae",
              "name": "contentSnippet",
              "type": "string",
              "value": "={{ $json.contentSnippet }}"
            },
            {
              "id": "1e12c8ec-8364-4523-a0c7-39e73bbed3f2",
              "name": "link",
              "type": "string",
              "value": "={{ $json.link }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "52af44a5-f28a-42c0-8db4-2738959329f3",
      "name": "Select Latest RSS Item by Date",
      "type": "n8n-nodes-base.code",
      "position": [
        1584,
        176
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nif (items.length === 0) return items;\nconst latestItem = items.sort((a, b) => new Date(b.json.pubDate) - new Date(a.json.pubDate))[0];\nreturn [latestItem];"
      },
      "typeVersion": 2
    },
    {
      "id": "5fc6a338-fb38-4164-a88c-f9567c699753",
      "name": "Generate Summary and Hashtags with LLM",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        3488,
        176
      ],
      "parameters": {
        "text": "={\n  \"promptType\": \"define\",\n  \"text\": \"[\\n  {\\n    \\\"role\\\": \\\"system\\\",\\n    \\\"content\\\": \\\"You summarize texts strictly under {{ $json.maxChars }} characters in a warm, engaging tone, then append exactly 3 relevant hashtags (e.g., #Tag1 #Tag2 #Tag3), then the link. Truncate if needed. Never exceed the limit. If empty, use fallback summary and tags.\\\"\\n  },\\n  {\\n    \\\"role\\\": \\\"user\\\",\\n    \\\"content\\\": \\\"Summarize this in under {{ $json.maxChars }} characters (text only; hashtags and link separate): {{ $json.contentSnippet || 'Discover health and wellbeing tips on our blog!' }}\\\\n\\\\nEnd with: #Hashtag1 #Hashtag2 #Hashtag3 {{ $json.link }}\\\"\\n  }\\n]\",\n  \"batching\": {}\n}",
        "batching": {},
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "dc4bfbda-76b8-425f-86c3-4dede50c5b39",
      "name": "Configure Local LLM Model (Ollama)",
      "type": "@n8n/n8n-nodes-langchain.lmOllama",
      "position": [
        3696,
        448
      ],
      "parameters": {
        "model": "gemma3:12b",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "a1d1e83e-98dd-4fc6-9b81-90519022f2be",
      "name": "Calculate Summary Character Limit",
      "type": "n8n-nodes-base.code",
      "position": [
        3296,
        176
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  const link = item.json.link;\n  const hashtagReserve = 50;\n  item.json.maxChars = 280 - link.length - 20 - hashtagReserve;\n  item.json.link = link;\n  return item;\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "a400eee2-73f8-42ac-9381-e82043505fda",
      "name": "Set RSS Feed URLs",
      "type": "n8n-nodes-base.set",
      "position": [
        160,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "e880cd01-0cc9-46bc-b714-117260be234c",
              "name": "Blog's Name",
              "type": "string",
              "value": "https://blogsname.blogspot.com/feeds/posts/default"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "3ece393b-8584-4f7e-8b4e-ebe59720dd40",
      "name": "Read Last Posted Hash from File",
      "type": "n8n-nodes-base.code",
      "position": [
        2016,
        176
      ],
      "parameters": {
        "jsCode": "const fs = require('fs');\nconst lastPath = '/.n8n/rss_last_posted.txt';\n\nreturn items.map(item => {\n  let lastPostedHash = '';\n  try {\n    if (fs.existsSync(lastPath)) {\n      lastPostedHash = fs.readFileSync(lastPath, 'utf8').trim();\n    }\n    console.log(\"Read lastPostedHash:\", lastPostedHash);\n  } catch (error) {\n    console.error(\"Failed to read last posted hash:\", error.message);\n  }\n  item.json.lastPostedHash = lastPostedHash;\n  return item;\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "f1caf122-f0cf-41c4-8869-b875c3d9207f",
      "name": "Save Posted Hash to File",
      "type": "n8n-nodes-base.code",
      "position": [
        4928,
        176
      ],
      "parameters": {
        "jsCode": "const fs = require('fs');\nconst lastPath = '/.n8n/rss_last_posted.txt';\nconst tempPath = '/.n8n/rss_temp_url.txt';\n\nreturn items.map(item => {\n  let linkHash = item.json.linkHash || '';\n  \n  // Fallback: Read from temp file if linkHash is missing\n  if (!linkHash && fs.existsSync(tempPath)) {\n    try {\n      linkHash = fs.readFileSync(tempPath, 'utf8').trim();\n      console.log(\"Read linkHash from temp file:\", linkHash);\n    } catch (error) {\n      console.error(\"Failed to read temp file:\", error.message);\n    }\n  }\n  \n  if (linkHash) {\n    try {\n      fs.writeFileSync(lastPath, linkHash, 'utf8');\n      console.log(\"Saved linkHash to rss_last_posted.txt:\", linkHash);\n    } catch (error) {\n      console.error(\"Failed to save linkHash:\", error.message);\n    }\n  } else {\n    console.log(\"No linkHash available to save.\");\n  }\n  \n  return item;\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "deece16b-a7fe-4447-a8b0-a8ddd5eca30c",
      "name": "Calculate Link Hash for Duplication Check",
      "type": "n8n-nodes-base.code",
      "position": [
        1808,
        176
      ],
      "parameters": {
        "jsCode": "function simpleHash(str) {\n  let hash = 0;\n  for (let i = 0; i < str.length; i++) {\n    const char = str.charCodeAt(i);\n    hash = ((hash << 5) - hash) + char;\n    hash = hash & hash; // Convert to 32-bit integer\n  }\n  return hash.toString(16);\n}\n\nreturn items.map(item => {\n  const link = item.json.link || '';\n  const linkHash = simpleHash(link.trim()); // Trim to remove trailing spaces\n  item.json.linkHash = linkHash;\n  console.log(\"Calculated linkHash:\", linkHash);\n  return item;\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "f8608124-757d-479b-ba94-b76c62a7c615",
      "name": "Compare Hashes for Duplicate Check",
      "type": "n8n-nodes-base.code",
      "position": [
        2240,
        176
      ],
      "parameters": {
        "jsCode": "const fs = require('fs');\nconst logPath = '/.n8n/debug_log.txt'; // Path to the debug log file\nconst lastPath = '/.n8n/rss_last_posted.txt';\n\nreturn items.map(item => {\n  const linkHash = item.json.linkHash || '';\n  let lastPostedHash = '';\n  try {\n    if (fs.existsSync(lastPath)) {\n      lastPostedHash = fs.readFileSync(lastPath, 'utf8').trim();\n      console.log(\"Comparison - linkHash:\", linkHash, \"lastPostedHash:\", lastPostedHash, \"File Exists:\", fs.existsSync(lastPath));\n    } else {\n      console.log(\"Comparison - File does not exist:\", lastPath);\n    }\n  } catch (error) {\n    console.error(\"Failed to read last posted hash:\", error.message);\n  }\n  const shouldProceed = linkHash !== lastPostedHash;\n  item.json.shouldProceed = shouldProceed;\n  console.log(\"Comparison - shouldProceed:\", shouldProceed, \"Execution ID:\", $execution.id);\n\n  // Log to file\n  try {\n    const logData = {\n      timestamp: new Date().toISOString(),\n      linkHash,\n      lastPostedHash,\n      shouldProceed\n    };\n    fs.appendFileSync(logPath, JSON.stringify(logData) + '\\n');\n    console.log(\"Logged to debug_log.txt\");\n  } catch (error) {\n    console.error(\"Failed to write to debug_log.txt:\", error.message);\n  }\n\n  return item;\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "4fab8e26-a350-46bc-b0ca-d37dbf77533b",
      "name": "Conditional Check for New Post",
      "type": "n8n-nodes-base.code",
      "position": [
        2640,
        176
      ],
      "parameters": {
        "jsCode": "const fs = require('fs');\nconst lastPath = '/.n8n/rss_last_posted.txt';\n\nreturn items.map(item => {\n  const linkHash = item.json.linkHash || '';\n  let lastPostedHash = '';\n  try {\n    if (fs.existsSync(lastPath)) {\n      lastPostedHash = fs.readFileSync(lastPath, 'utf8').trim();\n      console.log(\"Flow Control - linkHash:\", linkHash, \"lastPostedHash:\", lastPostedHash, \"File Exists:\", fs.existsSync(lastPath));\n    } else {\n      console.log(\"Flow Control - File does not exist:\", lastPath);\n    }\n  } catch (error) {\n    console.error(\"Failed to read last posted hash:\", error.message);\n  }\n  const shouldProceed = linkHash !== lastPostedHash;\n  item.json.shouldProceed = shouldProceed;\n  console.log(\"Flow Control - shouldProceed:\", shouldProceed, \"Execution ID:\", $execution.id);\n\n  // Only return items if they should proceed\n  if (shouldProceed) {\n    return item;\n  }\n  return null; // Null items are filtered out by n8n\n}).filter(item => item !== null);"
      },
      "typeVersion": 2
    },
    {
      "id": "52765cc4-2f2f-4b75-823b-2ebbcb265fd9",
      "name": "Extract Image URL from Post HTML",
      "type": "n8n-nodes-base.code",
      "position": [
        1728,
        432
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  let fullImageUrl = null;\n  if (item.json.body) {\n    const imgMatch = item.json.body.match(/<img[^>]+(?:data-original-height=\"\\d+\"[^>]*|data-original-width=\"\\d+\"[^>]*)*src=[\"'](.*?)[\"']/i);\n    if (imgMatch && imgMatch[1]) {\n      fullImageUrl = imgMatch[1].replace(/=w\\d+-h\\d+/, ''); // Simplified regex for clarity\n    }\n  }\n  item.json.imageUrl = fullImageUrl || null;\n  console.log('Extracted full image URL:', item.json.imageUrl);\n  return item;\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "332fdb2c-4553-4ddd-b796-be1d46c08233",
      "name": "Fetch Blog Post HTML Content",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1536,
        432
      ],
      "parameters": {
        "url": "={{ $json.link }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "text",
              "outputPropertyName": "body"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c4240336-7dda-4683-9eb4-fc5ce4f715f4",
      "name": "Download Post Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2080,
        432
      ],
      "parameters": {
        "url": "={{ $json.imageUrl }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4ff2834b-76c7-4522-b234-fb2923f300d5",
      "name": "Transform/Resize Image for Upload",
      "type": "n8n-nodes-base.editImage",
      "position": [
        2288,
        432
      ],
      "parameters": {
        "width": 1080,
        "height": 1080,
        "options": {
          "format": "jpeg",
          "fileName": "=blog-image-{{ $execution.id }}.jpeg"
        },
        "operation": "resize"
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "2bcb9f51-b0f4-415a-8fa2-4bf3a6a9538b",
      "name": "Upload Image to Postiz",
      "type": "n8n-nodes-postiz.postiz",
      "position": [
        2480,
        432
      ],
      "parameters": {
        "operation": "uploadFile",
        "binaryProperty": "={{ $('Transform/Resize Image for Upload').item.binary }}"
      },
      "typeVersion": 1
    },
    {
      "id": "61deda9e-4fa7-446f-86b3-b7edb84065a4",
      "name": "Filter Latest Item for Image Processing",
      "type": "n8n-nodes-base.code",
      "position": [
        1904,
        432
      ],
      "parameters": {
        "jsCode": "return items\n  .filter(item => item.json.imageUrl && item.json.imageUrl !== null) // Ensure valid URL\n  .sort((a, b) => new Date(b.json.pubDate) - new Date(a.json.pubDate)) // Sort by pubDate descending\n  .slice(0, 1); // Take the latest item"
      },
      "typeVersion": 2
    },
    {
      "id": "d2501d1e-d607-4585-8fb2-708ea989c389",
      "name": "Loop Over RSS Items for Processing",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1184,
        384
      ],
      "parameters": {
        "options": {}
      },
      "executeOnce": true,
      "typeVersion": 3
    },
    {
      "id": "38beb7d1-53ee-4a95-9d76-e5d7b0d3574d",
      "name": "Merge Processed Data Streams",
      "type": "n8n-nodes-base.merge",
      "position": [
        1120,
        176
      ],
      "parameters": {
        "mode": "combine",
        "options": {
          "includeUnpaired": true
        },
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "79a42cb0-45bf-496a-bf4f-b78cb1cbd054",
      "name": "Create and Post Content via Postiz API",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4640,
        176
      ],
      "parameters": {
        "url": "https://postiz.selfhosteddomain.net/api/public/v1/posts",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"type\": \"now\",\n  \"date\": \"{{ new Date().toISOString() }}\",\n  \"shortLink\": false,\n  \"tags\": [],\n  \"posts\": [\n    {\n      \"integration\": { \"id\": \"cmdt7mm7c0001uq6yoangez5f\" },\n      \"value\": [\n        {\n          \"content\": \"{{ $json.text || 'NO_TEXT' }} {{ $json.link || 'NO_LINK' }} {{ $json.hashtags && Array.isArray($json.hashtags) ? $json.hashtags.join(' ') : '' }}\",\n          \"image\": [\n            {\n              \"id\": \"{{ $('Upload Image to Postiz').item.json.id || '' }}\",\n              \"path\": \"{{ $('Upload Image to Postiz').item.json.path || '' }}\",\n              \"alt\": null,\n              \"thumbnail\": null,\n              \"thumbnailTimestamp\": null\n            }\n          ]\n        }\n      ],\n      \"settings\": {\"__type\": \"facebook\"}\n    },\n    {\n      \"integration\": { \"id\": \"cmdrm2h2w0001mu75dqdghjh3\" },\n      \"value\": [\n        {\n          \"content\": \"{{ $json.text || 'NO_TEXT' }} {{ $json.link || 'NO_LINK' }} {{ $json.hashtags && Array.isArray($json.hashtags) ? $json.hashtags.join(' ') : '' }}\",\n          \"image\": [\n            {\n              \"id\": \"{{ $('Upload Image to Postiz').item.json.id || '' }}\",\n              \"path\": \"{{ $('Upload Image to Postiz').item.json.path || '' }}\",\n              \"alt\": null,\n              \"thumbnail\": null,\n              \"thumbnailTimestamp\": null\n            }\n          ]\n        }\n      ],\n      \"settings\": {\"__type\": \"linkedin-page\"}\n    },\n    {\n      \"integration\": { \"id\": \"cmdt8yk610001ql6kgzaipjy7\" },\n      \"value\": [\n        {\n          \"content\": \"{{ $json.text || 'NO_TEXT' }} {{ $json.link || 'NO_LINK' }} {{ $json.hashtags && Array.isArray($json.hashtags) ? $json.hashtags.join(' ') : '' }}\",\n          \"image\": [\n            {\n              \"id\": \"{{ $('Upload Image to Postiz').item.json.id || '' }}\",\n              \"path\": \"{{ $('Upload Image to Postiz').item.json.path || '' }}\",\n              \"alt\": null,\n              \"thumbnail\": null,\n              \"thumbnailTimestamp\": null\n            }\n          ]\n        }\n      ],\n      \"settings\": {\"__type\": \"x\"}\n    },\n    {\n      \"integration\": { \"id\": \"cmdt88b790003uq6y4lyk97o0\" },\n      \"value\": [\n        {\n          \"content\": \"{{ $json.text || 'NO_TEXT' }} {{ $json.hashtags && Array.isArray($json.hashtags) ? $json.hashtags.join(' ') : '' }} {{ $json.link || 'NO_LINK' }}\",\n          \"image\": [\n            {\n              \"id\": \"{{ $('Upload Image to Postiz').item.json.id || '' }}\",\n              \"path\": \"{{ $('Upload Image to Postiz').item.json.path || '' }}\",\n              \"alt\": null,\n              \"thumbnail\": null,\n              \"thumbnailTimestamp\": null\n            }\n          ]\n        }\n      ],\n      \"settings\": {\n        \"post_type\": \"post\",\n        \"collaborators\": [],\n        \"media_type\": \"IMAGE\",\n        \"__type\": \"instagram\"\n      }\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "postizApi"
      },
      "typeVersion": 4.2
    },
    {
      "id": "f1b0f139-e790-44a7-9365-1263180d7d30",
      "name": "Validate Inputs for Postiz API",
      "type": "n8n-nodes-base.code",
      "position": [
        4320,
        176
      ],
      "parameters": {
        "jsCode": "const item = $input.item.json;\nconst upload = $('Upload Image to Postiz').item.json;\nconsole.log('Input validation:', { text: item.text, link: item.link, imageId: upload.id, imagePath: upload.path });\nif (!item.text || !item.link || !upload.id || !upload.path) {\n  throw new Error(`Invalid input: text=${item.text}, link=${item.link}, image.id=${upload.id}, image.path=${upload.path}`);\n}\nreturn $input.item;"
      },
      "typeVersion": 2
    },
    {
      "id": "bcf94463-572b-4cbd-bf9d-506609e98221",
      "name": "Schedule: Check RSS Every 10 Minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -64,
        192
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 10
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6e33f728-63bf-4682-b490-729826927a35",
      "name": "Process LLM Output for Postiz (Extract Text/Hashtags/Link)",
      "type": "n8n-nodes-base.code",
      "position": [
        3904,
        176
      ],
      "parameters": {
        "jsCode": "function simpleHash(str) {\n  let hash = 0;\n  for (let i = 0; i < str.length; i++) {\n    const char = str.charCodeAt(i);\n    hash = ((hash << 5) - hash) + char;\n    hash = hash & hash;\n  }\n  return hash.toString(16);\n}\n\nreturn items.map(item => {\n  const inputText = item.json.text || \"No summary available\";\n  const maxChars = item.json.maxChars || 200;\n  let text = inputText;\n  let link = item.json.link || \"\";\n  let hashtags = [];\n  console.log(\"Input text:\", inputText);\n  const parts = inputText.split(\" \").filter(part => part.trim());\n  const lastPart = parts[parts.length - 1];\n  if (lastPart && lastPart.includes(\"http\")) {\n    link = lastPart;\n    hashtags = parts.slice(-4, -1).filter(part => part.startsWith(\"#\"));\n    text = parts.slice(0, -4).join(\" \");\n  } else if (parts.length >= 4) { // Fallback if link not detected\n    hashtags = parts.slice(-3).filter(part => part.startsWith(\"#\"));\n    text = parts.slice(0, -3).join(\" \");\n  }\n  if (hashtags.length !== 3) {\n    console.warn(`Expected 3 hashtags, got ${hashtags.length}. Using defaults if needed.`);\n    hashtags = [\"#Wellbeing\", \"#Health\", \"#Inspiration\"]; // Fallback\n  }\n  text = text.replace(/\\n/g, \" \").replace(/\"/g, '\\\\\"').trim().slice(0, maxChars);\n  const linkHash = simpleHash(link);\n  console.log(\"Processed - text:\", text, \"hashtags:\", hashtags, \"link:\", link, \"length:\", (text + \" \" + hashtags.join(\" \") + \" \" + link).length);\n  return {\n    json: {\n      text: text,\n      hashtags: hashtags,\n      link: link,\n      linkHash: linkHash,\n      title: item.json.title || text.slice(0, 100),\n      imageId: item.json.id || null\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "1852bc12-4f1f-47bd-bdb7-4a12c8f47801",
      "name": "Save Temporary Link Hash to File",
      "type": "n8n-nodes-base.code",
      "position": [
        4112,
        176
      ],
      "parameters": {
        "jsCode": "const fs = require('fs');\nconst tempPath = '/.n8n/rss_temp_url.txt';\n\nreturn items.map(item => {\n  const linkHash = item.json.linkHash || '';\n  if (linkHash) {\n    try {\n      fs.writeFileSync(tempPath, linkHash, 'utf8');\n      console.log(\"Wrote temp URL hash:\", linkHash);\n    } catch (error) {\n      console.error(\"Failed to write temp URL hash:\", error.message);\n    }\n  }\n  console.log(\"Before Postiz - item.json:\", JSON.stringify(item.json));\n  return item;\n});"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "26882586-1d0d-43bc-b4df-78f5e75504a1",
  "connections": {
    "Set RSS Feed URLs": {
      "main": [
        [
          {
            "node": "Split RSS Feed URLs into Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Post Image": {
      "main": [
        [
          {
            "node": "Transform/Resize Image for Upload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Image to Postiz": {
      "main": [
        [
          {
            "node": "Loop Over RSS Items for Processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Blog Post HTML Content": {
      "main": [
        [
          {
            "node": "Extract Image URL from Post HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Processed Data Streams": {
      "main": [
        [
          {
            "node": "Select Latest RSS Item by Date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Latest RSS Feed Content": {
      "main": [
        [
          {
            "node": "Loop Over RSS Items for Processing",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Processed Data Streams",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Conditional Check for New Post": {
      "main": [
        [
          {
            "node": "Normalize RSS Fields (Content & Link)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Latest RSS Item by Date": {
      "main": [
        [
          {
            "node": "Calculate Link Hash for Duplication Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split RSS Feed URLs into Items": {
      "main": [
        [
          {
            "node": "Fetch Latest RSS Feed Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Inputs for Postiz API": {
      "main": [
        [
          {
            "node": "Create and Post Content via Postiz API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Last Posted Hash from File": {
      "main": [
        [
          {
            "node": "Compare Hashes for Duplicate Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Image URL from Post HTML": {
      "main": [
        [
          {
            "node": "Filter Latest Item for Image Processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Temporary Link Hash to File": {
      "main": [
        [
          {
            "node": "Validate Inputs for Postiz API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Summary Character Limit": {
      "main": [
        [
          {
            "node": "Generate Summary and Hashtags with LLM",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Transform/Resize Image for Upload": {
      "main": [
        [
          {
            "node": "Upload Image to Postiz",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compare Hashes for Duplicate Check": {
      "main": [
        [
          {
            "node": "Conditional Check for New Post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure Local LLM Model (Ollama)": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Summary and Hashtags with LLM",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over RSS Items for Processing": {
      "main": [
        [
          {
            "node": "Merge Processed Data Streams",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch Blog Post HTML Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule: Check RSS Every 10 Minutes": {
      "main": [
        [
          {
            "node": "Set RSS Feed URLs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize RSS Fields (Content & Link)": {
      "main": [
        [
          {
            "node": "Calculate Summary Character Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create and Post Content via Postiz API": {
      "main": [
        [
          {
            "node": "Save Posted Hash to File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Summary and Hashtags with LLM": {
      "main": [
        [
          {
            "node": "Process LLM Output for Postiz (Extract Text/Hashtags/Link)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Latest Item for Image Processing": {
      "main": [
        [
          {
            "node": "Download Post Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Link Hash for Duplication Check": {
      "main": [
        [
          {
            "node": "Read Last Posted Hash from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process LLM Output for Postiz (Extract Text/Hashtags/Link)": {
      "main": [
        [
          {
            "node": "Save Temporary Link Hash to File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This workflow automates fetching the latest post from a Blogspot RSS feed, summarizes it with an LLM (e.g., Gemma via Ollama), extracts and uploads an image, generates three relevant hashtags, and posts to Facebook, LinkedIn, X (Twitter), and Instagram via the Postiz API.

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

Automatically scan major financial newswires for biotech catalyst events, score them with AI sentiment analysis, and surface ranked trade candidates — all without manual monitoring.

RSS Feed Read, Data Table, HTTP Request +4
AI & RAG

YOUTUBE GUIDE 📣 This template generates up to 2,000 AI-based stock images per day for under $4. It includes prompt generation, image creation, metadata enrichment, upload to Google Drive, and error lo

Google Sheets, HTTP Request, Google Drive +6
AI & RAG

Categories Content Creation AI Automation Publishing Social Media

Google Docs, HTTP Request, Slack +7
AI & RAG

This n8n workflow automates the process of fetching, processing, and storing tech news articles from RSS feeds into a Notion database. It retrieves articles from The Verge and TechCrunch, processes th

OpenAI Chat, Chain Llm, Notion +3
AI & RAG

This workflow is designed for Japanese-speaking professionals, and learners who want to efficiently stay up to date with practical productivity, lifehack, and efficiency-related insights from Japanese

RSS Feed Read, Chain Llm, Google Gemini Chat +7