{
  "id": "xmR9W82MkB4yEqEI",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Smart News-to-Social Media Content Generator",
  "tags": [
    {
      "id": "0KEEkf4eRob224WF",
      "name": "Working",
      "createdAt": "2025-02-12T15:11:37.955Z",
      "updatedAt": "2025-02-12T15:11:37.955Z"
    }
  ],
  "nodes": [
    {
      "id": "c3ba165e-5f40-4399-a36c-1676a31d6a23",
      "name": "Scheduled Workflow Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -464,
        -784
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "7fbd9919-95b0-407e-8c85-464b4a35b639",
      "name": "Fetch Latest News Articles",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -240,
        -784
      ],
      "parameters": {
        "url": "https://newsapi.org/v2/everything?q=artificial intelligence OR AI innovation OR OpenAI OR tech startups&sortBy=publishedAt&language=en&pageSize=5&apiKey=YOUR_NEWS_API_KEY_HERE",
        "options": {}
      },
      "typeVersion": 4.4
    },
    {
      "id": "76e2c4f0-908b-4293-b3f7-6595541e8b37",
      "name": "Validate News Availability",
      "type": "n8n-nodes-base.if",
      "position": [
        32,
        -784
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "dff1831f-1003-4099-94eb-175369d7e115",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.totalResults }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f8800c57-0adb-45ba-a81e-9425fd6f1fae",
      "name": "AI News Quality Filter",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        336,
        -944
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash",
          "cachedResultName": "models/gemini-2.5-flash"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are a content quality filter for LinkedIn posts.\n\nAnalyze the news article below and decide if it is suitable for a professional LinkedIn post.\n\nRules:\n- Keep: AI, technology, business, startups, innovation, finance, research, productivity\n- Reject: sports, entertainment gossip, local events, irrelevant news, low-value content\n\nReturn ONLY raw valid JSON.\nDo NOT use markdown.\nDo NOT use ```json.\nDo NOT add explanations outside JSON.\n\nFormat:\n{\n  \"approved\": true,\n  \"reason\": \"\"\n}\n\nArticle:\nTitle: {{ $json.articles[0].title }}\nDescription: {{ $json.articles[0].description }}\nSource: {{ $json.articles[0].source.name }}"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "449203d4-9e69-417f-b0cb-35f2ab4b8feb",
      "name": "Notify for not availability of news",
      "type": "n8n-nodes-base.gmail",
      "position": [
        320,
        -592
      ],
      "parameters": {
        "sendTo": "example.123@gmail.com",
        "message": "No new News availability on the API",
        "options": {},
        "subject": "News not available"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "282c84b9-e676-46db-a6d4-3c08acf3d276",
      "name": "Notify not relevent data for publishing",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1184,
        -784
      ],
      "parameters": {
        "sendTo": "example.123@gmail.com",
        "message": "Notify there is not any new data available for Publishing on social media",
        "options": {},
        "subject": "Not relavent data for post"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e104967e-04e4-40bd-968b-675a00d8d516",
      "name": "Check Content Relevance",
      "type": "n8n-nodes-base.if",
      "position": [
        896,
        -944
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "012a0e47-de21-42dd-8579-570697b3fd49",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.approved }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "622ed721-7321-4d73-b0e7-dd490e50cbe2",
      "name": "Generate LinkedIn Post Content",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        1168,
        -1104
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-robotics-er-1.6-preview",
          "cachedResultName": "models/gemini-robotics-er-1.6-preview"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are a professional LinkedIn content strategist and AI visual designer.\n\nCreate a high-quality LinkedIn post AND an image prompt based on the news article below.\n\n---\n\nINPUT:\n\nTitle: {{ $('Fetch Latest News Articles').item.json.articles[0].title }}\n\nDescription:\n{{ $('Fetch Latest News Articles').item.json.articles[0].description }}\n\nContent:\n{{ $('Fetch Latest News Articles').item.json.articles[0].content }}\n\nSource:\n{{ $('Fetch Latest News Articles').item.json.articles[0].source.name }}\n\n---\n\nTASK:\nYou must generate TWO outputs:\n\n1. LinkedIn Post\n2. AI Image Prompt (for generating a professional LinkedIn image)\n\n---\n\nLINKEDIN POST RULES:\n- 6\u201312 lines max\n- Professional tone\n- Human-like writing\n- Strong hook at start\n- Insightful business/tech angle\n- End with a question\n- 3\u20135 hashtags\n\n---\n\nIMAGE PROMPT RULES:\nCreate a high-quality AI image prompt that:\n- Matches the LinkedIn post topic\n- Looks professional and corporate\n- Suitable for LinkedIn audience\n- No text inside image\n- Modern tech / business / infographic style\n- Clean composition, not cluttered\n- Visual metaphor of the news topic\n- 16:9 or square composition\n\n---\n\nOUTPUT FORMAT (STRICT JSON ONLY):\n\n{\n  \"post\": \"LinkedIn post text here\",\n  \"image_prompt\": \"AI image generation prompt here\"\n}"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "8cbbce8c-8ac9-4777-97da-2ca6a7e5b918",
      "name": "Prepare Filter News data",
      "type": "n8n-nodes-base.code",
      "position": [
        672,
        -944
      ],
      "parameters": {
        "jsCode": "return [\n  {\n    json: JSON.parse($json.content.parts[0].text)\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "b8b91a1c-5453-4679-914f-75dd295495d1",
      "name": "Clean AI Response Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1504,
        -1104
      ],
      "parameters": {
        "jsCode": "// Get raw Gemini response\nconst raw = $json.content.parts?.[0]?.text || \"\";\n\n// Step 1: Remove markdown code block wrappers\nlet cleaned = raw\n  .replace(/```json/g, \"\")\n  .replace(/```/g, \"\")\n  .trim();\n\n// Step 2: Sometimes AI adds hidden spaces/newlines before JSON\ncleaned = cleaned.replace(/^\\s+|\\s+$/g, \"\");\n\n// Step 3: Parse JSON safely\nlet parsed;\n\ntry {\n  parsed = JSON.parse(cleaned);\n} catch (error) {\n  throw new Error(\n    \"Failed to parse Gemini output as JSON. Raw output: \" + cleaned\n  );\n}\n\n// Step 4: Return structured output for next nodes\nreturn [\n  {\n    json: {\n      post: parsed.post,\n      image_prompt: parsed.image_prompt\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "ea9a1cb1-37c4-49fd-b982-3da6c5ce2423",
      "name": "Generate AI Post Image",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1744,
        -1104
      ],
      "parameters": {
        "model": "gpt-image-1",
        "prompt": "={{ $json.image_prompt }}",
        "options": {},
        "resource": "image"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "5a5e2043-dbe8-4760-814e-f033e3a520f8",
      "name": "Register LinkedIn Media Upload",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2176,
        -1104
      ],
      "parameters": {
        "url": "https://api.linkedin.com/v2/assets?action=registerUpload",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"registerUploadRequest\": {\n    \"recipes\": [\n      \"urn:li:digitalmediaRecipe:feedshare-image\"\n    ],\n    \"owner\": \"urn:li:person:{{ $json.sub }}\",\n    \"serviceRelationships\": [\n      {\n        \"relationshipType\": \"OWNER\",\n        \"identifier\": \"urn:li:userGeneratedContent\"\n      }\n    ]\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "linkedInOAuth2Api"
      },
      "credentials": {
        "linkedInOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4,
      "alwaysOutputData": false
    },
    {
      "id": "b8fb05e5-206c-4a97-9809-55f87a8b4218",
      "name": "Extrect Binary to Base 64",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        2416,
        -1104
      ],
      "parameters": {
        "options": {},
        "operation": "binaryToPropery",
        "binaryPropertyName": "={{ $('Generate AI Post Image').item.binary.data }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "e4c02600-9aec-46f0-a7f1-7d9cd75b10fb",
      "name": "Extrect Base64 to file",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        2624,
        -1104
      ],
      "parameters": {
        "options": {},
        "operation": "toBinary",
        "sourceProperty": "data"
      },
      "typeVersion": 1.1
    },
    {
      "id": "a0f1673e-9daf-475e-95c1-f53bccf16b80",
      "name": "Put Image on Linkedin API",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2832,
        -1104
      ],
      "parameters": {
        "url": "=YOUR_GENRATED_UPLOAD_URL",
        "method": "PUT",
        "options": {
          "response": {
            "response": {
              "neverError": true,
              "fullResponse": true
            }
          }
        },
        "sendBody": true,
        "contentType": "binaryData",
        "authentication": "predefinedCredentialType",
        "inputDataFieldName": "data",
        "nodeCredentialType": "linkedInOAuth2Api"
      },
      "credentials": {
        "linkedInOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "fb1e6632-7dbe-4488-a98b-7658c517f719",
      "name": "Create Post on Linkedin",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3056,
        -1104
      ],
      "parameters": {
        "url": "https://api.linkedin.com/v2/ugcPosts",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "neverError": true,
              "fullResponse": true
            }
          }
        },
        "jsonBody": "={\n  \"author\": \"urn:li:person:{{ $('Get ProfileInfo').item.json.sub }}\",\n  \"lifecycleState\": \"PUBLISHED\",\n  \"specificContent\": {\n    \"com.linkedin.ugc.ShareContent\": {\n      \"shareCommentary\": {\n        \"text\": \"{{ $('Clean AI Response Data').item.json.post.replace(/\\n/g, '\\\\n') }}\"\n      },\n      \"shareMediaCategory\": \"IMAGE\",\n      \"media\": [\n        {\n          \"status\": \"READY\",\n          \"media\": \"{{$node['Register LinkedIn Media Upload'].json['value']['asset']}}\"\n        }\n      ]\n    }\n  },\n  \"visibility\": {\n    \"com.linkedin.ugc.MemberNetworkVisibility\": \"PUBLIC\"\n  }\n}",
        "sendBody": true,
        "jsonHeaders": "{\n  \"X-Restli-Protocol-Version\": \"2.0.0\",\n  \"Content-Type\": \"application/json\"\n}",
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "specifyHeaders": "json",
        "nodeCredentialType": "linkedInOAuth2Api"
      },
      "credentials": {
        "linkedInOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "e5247417-4dfd-40b3-a0c8-e25c46d9e414",
      "name": "Notify on Success",
      "type": "n8n-nodes-base.slack",
      "position": [
        3264,
        -1104
      ],
      "parameters": {
        "text": "=Linkedin Post Related Notification\n\nPost Is : {{ $json.statusMessage }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09S57E2JQ2",
          "cachedResultName": "n8n"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "c820836e-5e57-4f7b-86d6-5b4053949ac5",
      "name": "Get ProfileInfo",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1968,
        -1104
      ],
      "parameters": {
        "url": "https://api.linkedin.com/v2/userinfo",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "linkedInOAuth2Api"
      },
      "credentials": {
        "linkedInOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "3fadd8cb-f12f-4e70-b577-fd289fd9aa11",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1024,
        -1376
      ],
      "parameters": {
        "width": 416,
        "height": 544,
        "content": "## How it works\n\nThis workflow automatically converts the latest news into LinkedIn posts. It starts by fetching real-time news from a News API and filtering relevant articles for social media publishing. AI then analyzes the news and generates a professional LinkedIn post along with an image prompt. An AI image is created based on the news context and converted into a LinkedIn-compatible format. The system fetches LinkedIn profile details, registers the image upload, and uploads it using a secure URL. Finally, a LinkedIn post is published combining the news-based content and image, and a Slack notification is sent to confirm successful publishing.\n\n\n## Setup steps\n**1.** Fetch latest news using News API\n**2.** Filter relevant articles for social media use\n**3.** Generate LinkedIn post content + image prompt using AI\n**4.** Create image using OpenAI Image node\n**5.** Convert image into binary format\n**6.** Register LinkedIn media upload using profile info\n**7.** Upload image via PUT API using upload URL\n**8.** Create LinkedIn post with text + image asset\n**9.** Send Slack notification after successful post"
      },
      "typeVersion": 1
    },
    {
      "id": "eabbd9e0-184f-4b88-b09b-061db3e3eac9",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -512,
        -896
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 288,
        "content": "Automatically triggers the workflow every on scheduler time to fetch and process the latest news articles. and Retrieves the latest trending news data from external News APIs for content generation."
      },
      "typeVersion": 1
    },
    {
      "id": "28b5a80e-e10e-4403-84cc-4bc8fe548ad9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -32,
        -896
      ],
      "parameters": {
        "color": 7,
        "width": 208,
        "height": 288,
        "content": "Checks whether valid news articles are available before continuing the workflow execution."
      },
      "typeVersion": 1
    },
    {
      "id": "48c406f7-b51c-4af8-9bb7-5ebc97c9f382",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        -704
      ],
      "parameters": {
        "color": 7,
        "width": 272,
        "height": 288,
        "content": "Notify the team when no new news data is available during workflow execution."
      },
      "typeVersion": 1
    },
    {
      "id": "a2840a45-6fbd-441b-a7ae-7625fd9ea882",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        -1104
      ],
      "parameters": {
        "color": 7,
        "width": 784,
        "height": 368,
        "content": "## AI Content Validation & Quality Check\n\nUses AI to validate and filter news articles to ensure the content is relevant, professional, and suitable for social media publishing."
      },
      "typeVersion": 1
    },
    {
      "id": "4f45a82d-9ecc-4042-914a-71bcd3472569",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        -864
      ],
      "parameters": {
        "color": 7,
        "width": 272,
        "height": 256,
        "content": "Notify the team that no relevant data is available for social media publishing at this time."
      },
      "typeVersion": 1
    },
    {
      "id": "48435737-83e9-40da-980b-e2142deac9d3",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        -1376
      ],
      "parameters": {
        "color": 7,
        "width": 2352,
        "height": 448,
        "content": "## AI Content Genration, Image Genration and Notify Process\n\nThis part of process uses AI to generate LinkedIn post content along with an image prompt based on the given topic. An AI image is generated and converted into a binary file for LinkedIn compatibility. The user\u2019s LinkedIn profile is fetched to register the media upload and obtain an upload URL. The image is then uploaded using a PUT API call to LinkedIn\u2019s media storage. Finally, a LinkedIn post is published combining the generated content and image, followed by a Slack notification to confirm successful posting."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "2670a2f8-4da2-4f46-9162-4219c68d5a7e",
  "connections": {
    "Get ProfileInfo": {
      "main": [
        [
          {
            "node": "Register LinkedIn Media Upload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI News Quality Filter": {
      "main": [
        [
          {
            "node": "Prepare Filter News data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean AI Response Data": {
      "main": [
        [
          {
            "node": "Generate AI Post Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extrect Base64 to file": {
      "main": [
        [
          {
            "node": "Put Image on Linkedin API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate AI Post Image": {
      "main": [
        [
          {
            "node": "Get ProfileInfo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Content Relevance": {
      "main": [
        [
          {
            "node": "Generate LinkedIn Post Content",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify not relevent data for publishing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Post on Linkedin": {
      "main": [
        [
          {
            "node": "Notify on Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Filter News data": {
      "main": [
        [
          {
            "node": "Check Content Relevance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extrect Binary to Base 64": {
      "main": [
        [
          {
            "node": "Extrect Base64 to file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Put Image on Linkedin API": {
      "main": [
        [
          {
            "node": "Create Post on Linkedin",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Latest News Articles": {
      "main": [
        [
          {
            "node": "Validate News Availability",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scheduled Workflow Trigger": {
      "main": [
        [
          {
            "node": "Fetch Latest News Articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate News Availability": {
      "main": [
        [
          {
            "node": "AI News Quality Filter",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify for not availability of news",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate LinkedIn Post Content": {
      "main": [
        [
          {
            "node": "Clean AI Response Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Register LinkedIn Media Upload": {
      "main": [
        [
          {
            "node": "Extrect Binary to Base 64",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}