Tired of manually posting on social media every day? Want to grow your audience while you sleep? In this guide, I’ll show you how to create an AI-powered social media agent that automatically posts trending news to LinkedIn and Facebook—for free using n8n (a no-code automation tool).
How It Works
- Fetches Latest News – Uses the GNews API to find trending articles.
- Generates AI Content – Google Gemini rewrites the news into engaging posts.
- Creates AI Images – Automatically generates visuals for each post.
- Auto-Posts to Social Media – Publishes to LinkedIn & Facebook on a schedule.
What You’ll Need
✅ Free n8n account
✅ Free Google Gemini API Key
✅ Free GNews API Key
✅ Facebook & LinkedIn developer access (for auto-posting)
Step 1: Set Up the n8n Workflow
- Go to n8n.io and sign up (or use the desktop app).
- Create a new workflow (click the
+
button). - Add a Schedule Trigger – This will run your workflow daily.
- Set it to trigger at 9 AM (or your preferred time).
Step 2: Fetch Trending News (GNews API)
- Add an HTTP Request Node – This will call the GNews API.
- Configure the API Request:
- Method:
GET
- URL: https://gnews.io/api/v4/search
- Query Parameters:
token=YOUR_API_KEY
(Get it from GNews)q=ecommerce
(or any topic like “AI,” “marketing,” etc.)lang=en
(for English articles)max=5
(number of articles to fetch)
- Test the Node – You should see recent news articles in JSON format.
Step 3: Let AI Pick the Best Article
- Add an AI Agent Node (Google Gemini).
- Configure Gemini API:
- Model:
Gemini 1.5 Pro
- Prompt:
You are an expert social media strategist and content curator. Your task is to help me identify 1 article from following and analyze their potential for high click-through rates when shared on social media.
Article #1:
Title: {{ $json.articles[0].title }}
Description: {{ $json.articles[0].description }}
Content: {{ $json.articles[0].content }}
URL: {{ $json.articles[0].url }}
Article #2:
Title: {{ $json.articles[1].title }}
Description: {{ $json.articles[1].description }}
Content: {{ $json.articles[1].content }}
URL: {{ $json.articles[1].url }}
In return only share Title, URL and summary with in 100 words of that article. In following format
Title:
URL:
Summary:
- Map the GNews data (title, description, URL) into the AI input.
- Test the Node – It should return the best article for posting.
Step 4: Generate AI-Powered Post Content
- Add Another AI Agent Node (Gemini).
- Prompt:
"Write a LinkedIn/Facebook post about this news. Make it engaging, add hashtags, and include 'Read more: [URL]' at the end."
- Test the Node – You’ll get a ready-to-post social media update.
Step 5: Create an AI Image for the Post
- Add an HTTP Request Node (Gemini Image Generation).
- URL:
https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent
- Headers:
Authorization: Bearer YOUR_GEMINI_API_KEY
- Body (JSON):
json { "contents": [{ "parts": [{ "text": "Generate an engaging social media image about: [ARTICLE_SUMMARY]" }] }] }
- Test & Extract Image URL – Save the generated image for posting.
Step 6: Auto-Post to Facebook
- Add Facebook Graph API Node.
- Configure:
- Endpoint:
me/feed
(orpage_id/feed
for Pages). - Method:
POST
- Parameters:
message
= AI-generated post texturl
= AI-generated image URL
- Test the Node – Check your Facebook to confirm the post went live!
Step 7: Auto-Post to LinkedIn
- Add LinkedIn API Node.
- Configure:
- Endpoint:
ugcPosts
- Method:
POST
- Body:
json { "author": "urn:li:person:YOUR_ID", "lifecycleState": "PUBLISHED", "specificContent": { "com.linkedin.ugc.ShareContent": { "shareCommentary": { "text": "AI-generated post here" }, "media": [{ "status": "READY", "description": { "text": "AI-generated image" } }] } }, "visibility": { "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC" } }
- Test & Confirm Posting – Refresh LinkedIn to see the automated post!
Step 8: Schedule Daily Auto-Posting
- Go back to the Schedule Trigger and set it to run daily at your chosen time.
- Save & Activate the workflow.
🎉 Done! Your AI agent will now:
✔ Fetch trending news
✔ Write posts with AI
✔ Generate images
✔ Post to LinkedIn & Facebook automatically!
Bonus: Expand to Twitter & Instagram
Want to add more platforms? Drop a comment below, and I’ll make a follow-up tutorial!
Complete JSON Code for N8N Workflow
{
"name": "Social Media Content Generator",
"nodes": [
{
"parameters": {
"url": "https://gnews.io/api/v4/search",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "q",
"value": "ecommerce"
},
{
"name": "lang",
"value": "en"
},
{
"name": "country",
"value": "us"
},
{
"name": "max",
"value": "10"
},
{
"name": "apikey",
"value": "b005cb1634851b7ebc140bdb1aac6847"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
260,
0
],
"id": "d6cfa9fa-bcdb-4196-8264-9d747a8a05b3",
"name": "HTTP Request"
},
{
"parameters": {
"amount": 1
},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
1020,
0
],
"id": "7debaf41-c5c4-49ef-9e6f-3eaccfeaa78f",
"name": "Wait1",
"webhookId": "f2d44e18-f08a-4db2-b42e-370b6be83598"
},
{
"parameters": {
"jsCode": "const outputText = $input.first().json.output;\n\nlet title = '';\nlet summary = '';\nlet url = '';\n\n// Regex for URL - notice the escaped asterisks: \\*\\*\nconst urlMatch = outputText.match(/\\*\\*URL:\\*\\* (.*?)\\n/);\nif (urlMatch && urlMatch[1]) {\n url = urlMatch[1].trim();\n}\n\n// Regex for Title - notice the escaped asterisks: \\*\\*\nconst titleMatch = outputText.match(/\\*\\*Title:\\*\\* (.*?)\\n/);\nif (titleMatch && titleMatch[1]) {\n title = titleMatch[1].trim();\n}\n\n// Extract Summary - notice the escaped asterisks: \\*\\*\n// [\\s\\S]* matches any character including newline until the end of the string\nconst summaryMatch = outputText.match(/\\*\\*Summary:\\*\\* ([\\s\\S]*)/);\nif (summaryMatch && summaryMatch[1]) {\n summary = summaryMatch[1].trim();\n}\n\n// It's good practice to only build the imagePrompt if summary is found\nlet imagePrompt = '';\nif (summary) {\n imagePrompt = `Illustrate the concept of: ${summary}`;\n} else {\n // Handle cases where summary might still not be found, e.g., if output format changes\n imagePrompt = 'Illustrate the concept of: [Summary not available]';\n}\n\n\nreturn [{\n json: {\n originalTitle: title,\n originalSummary: summary,\n imagePrompt: imagePrompt,\n originalURL: url\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
800,
0
],
"id": "77ffb7bc-c65f-40bf-8ad9-9b1f2a26eac5",
"name": "Code"
},
{
"parameters": {
"method": "POST",
"url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp-image-generation:generateContent",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googlePalmApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{\n {\n \"contents\": [{\n \"parts\": [\n { \"text\": $('Code').item.json.imagePrompt }\n ]\n }],\n \"generationConfig\": { \"responseModalities\": [\"TEXT\", \"IMAGE\"] }\n }\n}}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1820,
0
],
"id": "13782923-fed9-4560-a883-150071a476b1",
"name": "HTTP Request1",
"retryOnFail": true,
"waitBetweenTries": 5000,
"credentials": {
"googlePalmApi": {
"id": "6Ym7ncLLSycPldzg",
"name": "Google Gemini(PaLM) Api account"
}
}
},
{
"parameters": {
"amount": 1
},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
1640,
0
],
"id": "d537ebeb-6a35-4990-b336-ea98d5a8626a",
"name": "Wait",
"webhookId": "fff719c9-e7b5-493e-bd81-78b50adb3e89"
},
{
"parameters": {
"promptType": "define",
"text": "=You are an expert social media strategist and content curator. Your task is to help me identify 1 article from following and analyze their potential for high click-through rates when shared on social media.\n\nArticle #1:\n\nTitle: {{ $json.articles[0].title }}\nDescription: {{ $json.articles[0].description }}\nContent: {{ $json.articles[0].content }}\nURL: {{ $json.articles[0].url }}\n\nArticle #2:\nTitle: {{ $json.articles[1].title }}\nDescription: {{ $json.articles[1].description }}\nContent: {{ $json.articles[1].content }}\nURL: {{ $json.articles[1].url }}\n\nIn return only share Title, URL and summary with in 100 words of that article. In following format\n\nTitle: \nURL: \nSummary:",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.7,
"position": [
460,
0
],
"id": "cc9da31c-c977-496a-9b63-e9920a690114",
"name": "AI Agent"
},
{
"parameters": {
"modelName": "models/gemini-2.5-pro-preview-05-06",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
500,
220
],
"id": "8d09d174-8b50-416d-bed3-2d7ed7805971",
"name": "Google Gemini Chat Model",
"credentials": {
"googlePalmApi": {
"id": "6Ym7ncLLSycPldzg",
"name": "Google Gemini(PaLM) Api account"
}
}
},
{
"parameters": {
"promptType": "define",
"text": "=You are an experienced Marketing Manager writing a LinkedIn post. Your goal is to share a valuable insight from following summary\n\n{{ $json.originalSummary }}\n\nReflection in a way that feels authentic, engaging, and genuinely human-written. Only return linkedin post content. Don't include anything like \"Here's a LinkedIn post reflecting on the summary:\". Please only return post which I can copy and paste in linkedin directly ",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.7,
"position": [
1300,
0
],
"id": "12d60105-12ba-47d8-aa89-304ccc436a45",
"name": "AI Agent1"
},
{
"parameters": {
"modelName": "models/gemini-2.5-flash-preview-04-17-thinking",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
1220,
220
],
"id": "52901dad-e16e-47f6-bbbd-9a3cb48218e3",
"name": "Google Gemini Chat Model1",
"credentials": {
"googlePalmApi": {
"id": "6Ym7ncLLSycPldzg",
"name": "Google Gemini(PaLM) Api account"
}
}
},
{
"parameters": {
"operation": "toBinary",
"sourceProperty": "imageData",
"options": {}
},
"type": "n8n-nodes-base.convertToFile",
"typeVersion": 1.1,
"position": [
2360,
0
],
"id": "1be7a527-a6dd-437a-a4b3-c9e098548cfc",
"name": "Convert to File",
"retryOnFail": true,
"waitBetweenTries": 2000
},
{
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 10
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
],
"id": "4aeb37b1-ed43-433c-9317-bac7e423d2e9",
"name": "Schedule Trigger"
},
{
"parameters": {
"postAs": "organization",
"organization": "10500516",
"text": "={{ $('Wait').item.json.output }}\n\nRead More: {{ $('Code').item.json.originalURL }}",
"shareMediaCategory": "IMAGE",
"additionalFields": {}
},
"type": "n8n-nodes-base.linkedIn",
"typeVersion": 1,
"position": [
2720,
-60
],
"id": "0263af92-e4c6-442a-8977-00081797b174",
"name": "Post To Linkedin",
"credentials": {
"linkedInOAuth2Api": {
"id": "oI6AJAhpxFVotGo8",
"name": "LinkedIn account"
}
}
},
{
"parameters": {
"httpRequestMethod": "POST",
"graphApiVersion": "v22.0",
"node": "me",
"edge": "photos",
"options": {
"queryParameters": {
"parameter": [
{
"name": "message",
"value": "={{ $('AI Agent1').item.json.output }}\n\nRead More: {{ $('Wait1').item.json.originalURL }}"
},
{
"name": "url",
"value": "={{ $('Google Drive Upload Image').item.json.webContentLink }}"
}
]
}
}
},
"type": "n8n-nodes-base.facebookGraphApi",
"typeVersion": 1,
"position": [
2860,
260
],
"id": "37e3d697-4599-40d3-94af-941ddc5f0c3d",
"name": "Post To Facebook",
"credentials": {
"facebookGraphApi": {
"id": "iEdddBpcH0TtneDh",
"name": "Facebook Graph account"
}
}
},
{
"parameters": {
"name": "image.png",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "1C0m6_SFcDzcII49KkBgONQEmOjVrsTrE",
"mode": "list",
"cachedResultName": "Content Creator",
"cachedResultUrl": "https://drive.google.com/drive/folders/1C0m6_SFcDzcII49KkBgONQEmOjVrsTrE"
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
2440,
260
],
"id": "78b86c63-988d-4b2f-b86f-fe4f308cfce5",
"name": "Google Drive Upload Image",
"credentials": {
"googleDriveOAuth2Api": {
"id": "21UFu9AjTKl1aVlG",
"name": "Google Drive account"
}
}
},
{
"parameters": {
"operation": "share",
"fileId": {
"__rl": true,
"value": "={{ $json.id }}",
"mode": "id"
},
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "anyone"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
2640,
260
],
"id": "5b53590f-6288-4ba1-8b52-01a46ceb6fd0",
"name": "Google Drive Set Permissions",
"credentials": {
"googleDriveOAuth2Api": {
"id": "21UFu9AjTKl1aVlG",
"name": "Google Drive account"
}
}
},
{
"parameters": {
"jsCode": "const items = $input.first().json.candidates; // Or however you get the input item\nconst results = [];\n\nfor (const item of items) {\n // Adjust the path according to the actual output structure\n // This assumes the first candidate is the one we want.\n const parts = $input.first().json.candidates[0].content.parts;\n let imageBase64 = null;\n let imageMimeType = null;\n\n for (const part of parts) {\n if (part.inlineData && part.inlineData.mimeType && part.inlineData.mimeType.startsWith('image/')) {\n imageBase64 = part.inlineData.data;\n imageMimeType = part.inlineData.mimeType;\n break; // Found the image part\n }\n }\n\n if (imageBase64) {\n results.push({\n json: {\n imageData: imageBase64,\n mimeType: imageMimeType\n // You can add other fields from the original item if needed\n // ...item.json\n }\n });\n } else {\n // Handle case where no image part was found (optional)\n results.push({ json: { error: \"No image data found in response\", originalResponse: item.json } });\n }\n}\n\nreturn results;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2100,
0
],
"id": "3b1ece86-a1ea-42bc-9c56-d9a301aacab6",
"name": "Code1"
}
],
"pinData": {},
"connections": {
"Code": {
"main": [
[
{
"node": "Wait1",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request1": {
"main": [
[
{
"node": "Code1",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "HTTP Request1",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Wait1": {
"main": [
[
{
"node": "AI Agent1",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[
{
"node": "AI Agent1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"AI Agent1": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Convert to File": {
"main": [
[
{
"node": "Google Drive Upload Image",
"type": "main",
"index": 0
},
{
"node": "Post To Linkedin",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Google Drive Upload Image": {
"main": [
[
{
"node": "Google Drive Set Permissions",
"type": "main",
"index": 0
}
]
]
},
"Google Drive Set Permissions": {
"main": [
[
{
"node": "Post To Facebook",
"type": "main",
"index": 0
}
]
]
},
"Code1": {
"main": [
[
{
"node": "Convert to File",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "1c550945-ed48-4a32-a7ae-5fb494443c58",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "7d6a5bcda733904ebcb54fc0e889f6735550f40f670703e17874c0872e05a9cb"
},
"id": "MThpyJnqjAHtW512",
"tags": []
}
5/5 - (5 votes)