This workflow corresponds to n8n.io template #8694 — we link there as the canonical source.
This workflow follows the Google Drive → 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 →
{
"id": "jBgzLQDvUfBwo5rG",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "\ud83d\uddde\ufe0f News Summarizer & Auto-Poster for Social Media - Late",
"tags": [
{
"id": "L5OfKYUAxU0VDZh3",
"name": "Content",
"createdAt": "2025-07-02T08:32:59.389Z",
"updatedAt": "2025-07-02T08:32:59.389Z"
}
],
"nodes": [
{
"id": "38daed7e-5981-48b0-9dd4-b5dc4da09cbb",
"name": "Edit Fields",
"type": "n8n-nodes-base.set",
"position": [
-752,
-240
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "{\n \"urls\": [\n \"URL1\",\n \"URL2\",\n\"URL3\"\n ]\n}"
},
"typeVersion": 3.4
},
{
"id": "0c3c6494-b0d5-4e8c-838c-7c0d83ed2ac9",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
-304,
-240
],
"parameters": {
"url": "={{ $json.urls }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "da58c23f-1a20-45f1-ab4b-f65f14bdae91",
"name": "Code",
"type": "n8n-nodes-base.code",
"position": [
-80,
-144
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// INPUTS\nconst html = $json.data; // HTML complet\nconst articleUrl = $('Split Out').item.json.urls || \"\"; // URL de l\u2019article (pour les URLs relatives)\n\n// ------------------ Utils ------------------\nfunction decodeEntities(text) {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/ /g, ' ')\n .replace(/é/g, '\u00e9')\n .replace(/è/g, '\u00e8')\n .replace(/à/g, '\u00e0');\n}\n\nfunction resolveUrl(baseUrl, src) {\n if (!src) return null;\n // //cdn\u2026 \u2192 https:\n if (src.startsWith('//')) return 'https:' + src;\n // absolute\n try {\n return new URL(src, baseUrl).href;\n } catch {\n return src;\n }\n}\n\n// Supprime blocs connus de \u201cparasites\u201d (share, related, newsletter, footer\u2026)\nfunction stripNoise(htmlChunk) {\n let s = htmlChunk;\n\n // blocs \u201cshare/social\u201d\n s = s.replace(/<aside[\\s\\S]*?<\\/aside>/gi, '');\n s = s.replace(/<section[^>]*?(?:share|social|related|newsletter|comments)[^>]*>[\\s\\S]*?<\\/section>/gi, '');\n s = s.replace(/<div[^>]*?(?:share|social|related|newsletter|comments|social-tools|meta-social)[^>]*>[\\s\\S]*?<\\/div>/gi, '');\n\n // scripts/styles\n s = s.replace(/<script[\\s\\S]*?<\\/script>/gi, '');\n s = s.replace(/<style[\\s\\S]*?<\\/style>/gi, '');\n\n // nav/footer/header souvent non-article\n s = s.replace(/<(?:nav|footer|header)[\\s\\S]*?<\\/(?:nav|footer|header)>/gi, '');\n\n return s;\n}\n\n// Extrait tous les <p> d\u2019un bloc HTML (en gardant l\u2019ordre)\nfunction extractParagraphs(htmlChunk) {\n const ps = [];\n const re = /<p[^>]*>([\\s\\S]*?)<\\/p>/gi;\n let m;\n while ((m = re.exec(htmlChunk)) !== null) {\n // retire tags r\u00e9siduels dans <p>\n let t = m[1]\n .replace(/<figure[\\s\\S]*?<\\/figure>/gi, '')\n .replace(/<[^>]+>/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n if (t) ps.push(t);\n }\n return ps;\n}\n\n// Cherche une image principale : og:image > twitter:image > figure > img dans article/main\nfunction findMainImage(html, baseUrl) {\n let imageMatch =\n html.match(/<meta[^>]+property=[\"']og:image[\"'][^>]+content=[\"']([^\"']+)[\"']/i) ||\n html.match(/<meta[^>]+name=[\"']twitter:image[\"'][^>]+content=[\"']([^\"']+)[\"']/i);\n\n if (imageMatch) return resolveUrl(baseUrl, imageMatch[1]);\n\n // image dans <figure>\n imageMatch =\n html.match(/<figure[\\s\\S]*?<img[^>]+src=[\"']([^\"']+)[\"'][\\s\\S]*?<\\/figure>/i) ||\n html.match(/<(?:article|main)[^>]*>[\\s\\S]*?<img[^>]+src=[\"']([^\"']+)[\"']/i) ||\n html.match(/<img[^>]+src=[\"']([^\"']+)[\"']/i);\n\n return imageMatch ? resolveUrl(baseUrl, imageMatch[1]) : null;\n}\n\n// ------------------ Titre ------------------\nlet titleMatch =\n html.match(/<meta[^>]+property=[\"']og:title[\"'][^>]+content=[\"']([^\"']+)[\"']/i) ||\n html.match(/<meta[^>]+name=[\"']twitter:title[\"'][^>]+content=[\"']([^\"']+)[\"']/i) ||\n html.match(/<title>([\\s\\S]*?)<\\/title>/i);\nlet title = titleMatch ? titleMatch[1] : \"\";\n\n// ------------------ Corps de l\u2019article ------------------\n// 1) Privil\u00e9gie <article>, sinon <main>, sinon grands conteneurs classiques\nconst candidatePatterns = [\n /<article[^>]*>([\\s\\S]*?)<\\/article>/i,\n /<main[^>]*>([\\s\\S]*?)<\\/main>/i,\n /<div[^>]+class=[\"'][^\"']*(?:article__body|article-body|articleBody|content-article|story|post-content|post__content|entry-content|main-content|content__body)[^\"']*[\"'][^>]*>([\\s\\S]*?)<\\/div>/i,\n // fallback : gros container central (layout courant)\n /<div[^>]+class=[\"'][^\"']*(?:container|content|wrapper)[^\"']*[\"'][^>]*>([\\s\\S]*?)<\\/div>/i,\n];\n\nlet articleHtml = \"\";\nfor (const p of candidatePatterns) {\n const m = html.match(p);\n if (m && m[1]) {\n articleHtml = m[1];\n break;\n }\n}\n// Si encore vide, on prend tout le HTML (on filtrera)\nif (!articleHtml) articleHtml = html;\n\n// 2) Nettoyage \u201cbruit\u201d (share, related, scripts, etc.)\narticleHtml = stripNoise(articleHtml);\n\n// 3) R\u00e9cup\u00e8re beaucoup plus de texte : on concat\u00e8ne les <p>\nlet paragraphs = extractParagraphs(articleHtml);\n\n// Si on n\u2019a quasiment rien, tente aussi les <h2>/<h3> comme \u201cparagraphes\u201d\nif (paragraphs.length < 3) {\n const hx = [];\n const reHx = /<(?:h2|h3)[^>]*>([\\s\\S]*?)<\\/(?:h2|h3)>/gi;\n let m;\n while ((m = reHx.exec(articleHtml)) !== null) {\n const t = m[1].replace(/<[^>]+>/g, '').replace(/\\s+/g, ' ').trim();\n if (t) hx.push(t);\n }\n paragraphs = paragraphs.concat(hx);\n}\n\n// 4) Filtrage l\u00e9ger : on retire les lignes trop courtes (menus, miettes)\nparagraphs = paragraphs.filter(p => p.length > 40);\n\n// 5) Limites souples (\u00e9vite d\u2019avaler l\u2019entier du site)\nconst MAX_PARAGRAPHS = 20; // augmente si tu veux encore plus\nconst MAX_CHARS = 8000; // coupe si trop long\nlet content = \"\";\nfor (const p of paragraphs.slice(0, MAX_PARAGRAPHS)) {\n if ((content + p + \"\\n\\n\").length > MAX_CHARS) break;\n content += p + \"\\n\\n\";\n}\ncontent = content.trim();\n\n// 6) Coupe les blocs \u201cparasites\u201d s\u2019ils apparaissent *plus loin* dans l\u2019article\nconst breakMarkers = [\n \"Partager\", \"Commenter\", \"Partagez sur\", \"Lire aussi\", \"Sur le m\u00eame sujet\",\n \"Voir aussi\", \"Suivez-nous\", \"Retrouvez-nous\", \"Contactez\", \"R\u00e9daction\",\n \"lire plus tard\", \"newsletter\", \"publicit\u00e9\", \"nos autres articles\"\n];\n// coupe uniquement apr\u00e8s un petit seuil pour ne pas tronquer l\u2019intro\nfor (const marker of breakMarkers) {\n const idx = content.indexOf(marker);\n if (idx > 300) {\n content = content.slice(0, idx).trim();\n break;\n }\n}\n\n// ------------------ Image principale ------------------\nlet imageUrl = findMainImage(html, articleUrl);\n\n// ------------------ Finalisation ------------------\ntitle = decodeEntities(title);\ncontent = decodeEntities(content);\n\nreturn {\n json: {\n title,\n urls: articleUrl,\n content,\n imageUrl\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "d8ba2c62-a400-4634-b0b6-08ce3f1ead6f",
"name": "OpenAI",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
144,
-144
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-5",
"cachedResultName": "GPT-5"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "Tu es un assistant charg\u00e9 de r\u00e9sumer des articles de presse de mani\u00e8re factuelle, synth\u00e9tique et hi\u00e9rarchis\u00e9e. Tu n'as pas le droit d'inventer quoi que ce soit qui ne soit pas \u00e9crit dans le contenu initial"
},
{
"content": "=Voici un article d'actualit\u00e9 \u00e0 r\u00e9sumer de mani\u00e8re claire, synth\u00e9tique et d\u00e9taill\u00e9 en ne gardant que les informations en rapport avec le titre.\n\nTITRE : {{$json.title}}\n\nCONTENU : {{ $json.content }}"
}
]
}
},
"typeVersion": 1.8
},
{
"id": "f1f69341-f3f5-4fa5-a920-0937da06f643",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
-528,
-240
],
"parameters": {
"options": {},
"fieldToSplitOut": "=urls"
},
"typeVersion": 1
},
{
"id": "25152ee0-5ccc-4946-96d1-3004094bcb11",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
496,
-144
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "message.content"
}
]
}
},
"typeVersion": 1
},
{
"id": "a1ac8d77-76d3-4e98-87cd-ca741123d24b",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1024,
-304
],
"parameters": {
"width": 400,
"height": 220,
"content": "## Test mode"
},
"typeVersion": 1
},
{
"id": "d7d70ef4-ac43-408f-85f2-aeee25030189",
"name": "When clicking \u2018Execute workflow\u2019",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-976,
-240
],
"parameters": {},
"typeVersion": 1
},
{
"id": "6905d681-6b32-4fda-a9ea-3fc39aa81ce8",
"name": "HTML1",
"type": "n8n-nodes-base.html",
"position": [
336,
-464
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"extractionValues": {
"values": [
{
"key": "figure_img",
"attribute": "content",
"cssSelector": "meta[property=\"og:image\"]",
"returnValue": "attribute"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "f6fd3ca8-7c3d-412a-b1d2-4bcedf3a4dfe",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
272,
-576
],
"parameters": {
"color": 4,
"width": 932,
"height": 260,
"content": "## Images downloading"
},
"typeVersion": 1
},
{
"id": "fcd4a0f2-4cef-42ae-bfd8-bbe9fc3d33ed",
"name": "HTTP Request1",
"type": "n8n-nodes-base.httpRequest",
"position": [
624,
-464
],
"parameters": {
"url": "={{ $json.figure_img }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "15bd8581-6713-4421-9c4e-5ba194fa536a",
"name": "Message a model",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
720,
-144
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"messages": {
"values": [
{
"role": "assistant",
"content": "Tu es un assistant qui r\u00e9sume de mani\u00e8re journalistique pour les jeunes des articles d\u2019actualit\u00e9, sans \u00e9mojis, sans interpr\u00e9tation."
},
{
"content": "=Voici les articles :\n{{ $json.content }}\n\nR\u00e9alise une synth\u00e8se structur\u00e9e pour des jeunes lecteurs, format\u00e9e comme ce JSON :\n\n{\n \"titre\": \"\u2026\", // min 45 caract\u00e8res, max 60 caract\u00e8res\n \"sous_titre\": \"\u2026\", // min 150 caract\u00e8res, max 220 caract\u00e8res, ton journalistique et accrocheur\n \"parties\": [\n {\n \"titre_1\": \"\u2026\", // max 60 caract\u00e8res ton journalistique et accrocheur qui r\u00e9sume la description\n \"description\": \"\u2026\" // max 500 caract\u00e8res, avec faits et chiffres\n },\n {\n \"titre_2\": \"\u2026\", // idem\n \"description\": \"\u2026\"\n }\n // etc.\n ]\n}\n\nExemple de consignes \u00e0 inclure en d\u00e9but de prompt :\n\n\u00ab **Attention** : \n- il doit y avoir exactement {{ $('Webhook').item.json.body.pages }} pages- `titre` ne doit pas d\u00e9passer 60 caract\u00e8res \n- `sous_titre` ne doit pas d\u00e9passer 220 caract\u00e8res \n- pour chaque objet de `parties`, `titre_X` \u2264 60 caract\u00e8res et `description` \u2264 500 caract\u00e8res \nR\u00e9pond strictement au format JSON ci-dessus, sans explications additionnelles, sans commencer par \"json\". \u00bb\n"
},
{
"role": "system",
"content": "Respecte strictement la structure JSON, sans texte avant ou apr\u00e8s. N'invente rien. Ne r\u00e9p\u00e8te pas d'information. Utilise uniquement le contenu fourni."
}
]
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.8
},
{
"id": "4972cdd6-c3fd-4d1e-95e4-8a1684d5bd66",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
-272
],
"parameters": {
"color": 5,
"width": 1140,
"height": 308,
"content": "## Social Networks posting"
},
"typeVersion": 1
},
{
"id": "ba945e0a-5aa4-4601-a6b2-8c73bb725232",
"name": "Message a model1",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1072,
-144
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "chatgpt-4o-latest",
"cachedResultName": "CHATGPT-4O-LATEST"
},
"options": {},
"messages": {
"values": [
{
"content": "=Tu es un assistant sp\u00e9cialis\u00e9 dans la cr\u00e9ation de descriptions impactantes pour les r\u00e9seaux sociaux, \u00e0 destination des 18-25 ans. Voici le texte de l\u2019article \u00e0 r\u00e9sumer\u202f:\n\" {{ $json.message.content }} \"\n\n\nG\u00e9n\u00e8re une description pr\u00eate \u00e0 poster sur Instagram, TikTok et autres r\u00e9seaux, au format suivant\u202f:\n\n- Hook d\u2019accroche (1 phrase qui donne envie de lire le post, max 80 caract\u00e8res)\n- R\u00e9sum\u00e9 de l\u2019actu (2 \u00e0 4 phrases synth\u00e9tiques et factuelles, 200 \u00e0 250 caract\u00e8res max)\n- Question ou call-to-action pour inciter \u00e0 commenter ou r\u00e9agir (max 80 caract\u00e8res)\n- Hashtags (5 \u00e0 8, s\u00e9par\u00e9s par des espaces, m\u00e9lange de #actu #news #jeunes #actualit\u00e9 + sujets du texte + toujours #pikor)\n\nContraintes\u202f:\n- Pas d\u2019\u00e9mojis ou juste un seul, jamais au d\u00e9but du texte.\n- Aucune invention\u202f: tu utilises uniquement les infos de l\u2019article.\n- Le ton doit rester journalistique, mais accrocheur, \u00e9crit pour des jeunes adultes (jamais infantilisant).\n- Pas de r\u00e9p\u00e9tition, ni d\u2019auto-promo, ni de lien externe.\n- Jamais plus de 450 caract\u00e8res au total."
},
{
"role": "system",
"content": "Tu es un assistant \u00e9ditorial qui g\u00e9n\u00e8re des descriptions pr\u00eates \u00e0 publier sur les r\u00e9seaux sociaux pour une application d\u2019actualit\u00e9 destin\u00e9e aux 18-25 ans. \n\nTa mission\u202f: \n- Structurer la description comme demand\u00e9 (hook, r\u00e9sum\u00e9, call-to-action, hashtags)\n- Toujours respecter les consignes de format, de longueur et de ton\u202f: journalistique, accrocheur, jamais infantilisant.\n- Aucune invention ni ajout ext\u00e9rieur\u202f: uniquement des faits pr\u00e9sents dans l\u2019article.\n- Pas de r\u00e9p\u00e9tition, pas d\u2019auto-promo, pas de lien externe, pas plus d\u2019un \u00e9moji.\n- Si l\u2019information manque dans l\u2019article, n\u2019ajoute rien et passe \u00e0 la suite.\n- La sortie doit \u00eatre claire, pr\u00eate \u00e0 l\u2019emploi et strictement respecter la structure demand\u00e9e dans le prompt utilisateur."
}
]
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.8
},
{
"id": "01102406-10d0-424f-9f60-69717e87dc9c",
"name": "Upload file",
"type": "n8n-nodes-base.googleDrive",
"position": [
976,
-464
],
"parameters": {
"name": "={{$now.format('f') }}_{{ $json[\"source\"] || \"image\" }}_{{$itemIndex}}.jpg",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "191yh8eb9mx8wykfpGXJNVy9F9IWgDZxz",
"cachedResultUrl": "https://drive.google.com/drive/folders/191yh8eb9mx8wykfpGXJNVy9F9IWgDZxz",
"cachedResultName": "Pikor - Images articles"
}
},
"typeVersion": 3
},
{
"id": "1cfd0408-80e4-411e-9c9b-130a327be710",
"name": "GetLate multipublishing",
"type": "n8n-nodes-base.httpRequest",
"position": [
1424,
-240
],
"parameters": {
"url": "https://getlate.dev/api/v1/post",
"method": "POST",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "={\n \"content\": \"{{ $('Message a model1').item.json.message.content }}\",\n \"platforms\": [\n {\"platform\": \"twitter\", \"accountId\": \"TWITTER_ACCOUNT_ID\"},\n {\"platform\": \"instagram\", \"accountId\": \"INSTAGRAM_ACCOUNT_ID\"},\n {\"platform\": \"linkedin\", \"accountId\": \"LINKEDIN_ACCOUNT_ID\"},\n {\"platform\": \"threads\", \"accountId\": \"THREADS_ACCOUNT_ID\"},\n {\"platform\": \"youtube\", \"accountId\": \"YOUTUBE_ACCOUNT_ID\"}\n ],\n \"scheduledFor\": \"today\",\n \"timezone\": \"America/New_York\",\n \"publishNow\": false,\n \"isDraft\": false,\n \"visibility\": \"public\",\n \"tags\": [\"programming\", \"tutorial\", \"api\", \"coding\"],\n \"mediaItems\": [\n {\n \"type\": \"image\",\n \"url\": \"{{ $('HTTP Request1').item.json.figure_img }}\",\n \"filename\": \"optional_filename\"\n }\n ]\n}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "d5abfc93-9f61-4c24-b577-4cf7fef2e35f",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1264,
-944
],
"parameters": {
"color": 7,
"width": 384,
"height": 544,
"content": "## Different Articles Summarizer & Social Media Auto-Poster\n\nThis n8n template demonstrates how to extract full-text articles from different news websites, summarize them with AI, and automatically generate content for social networks (Twitter, Instagram, Threads, LinkedIn, YouTube).\n\nYou can use it for any news topic. Example: posting summaries of breaking news articles.\n\nPossible use cases :\n* Automate press article summarization with GPT.\n* Create social media posts optimized for young audiences.\n* Publish content simultaneously across multiple platforms with Late API."
},
"typeVersion": 1
},
{
"id": "92d59f4a-125b-4579-b842-345ff18e1936",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-848,
-944
],
"parameters": {
"color": 7,
"width": 384,
"height": 544,
"content": "## How it works\n\n* The workflow starts manually or with a trigger.\n* URLs of news articles are defined in the Edit Fields node.\n* Each URL is processed separately via Split Out.\n* HTTP Request fetches the article HTML.\n* Custom Code node extracts clean text (title, content, main image).\n* OpenAI summarizes each article factually.\n* Aggregate combines results.\n* Another OpenAI node (Message a model) creates structured JSON summaries for young readers.\n* A final OpenAI node (Message a model1) generates short social media posts (hook, summary, CTA, hashtags).\n* Images are extracted via HTML1 and uploaded to Google Drive.\n* Posts (text + image) are sent to Late API for multi-platform scheduling (Twitter, Instagram, Threads, LinkedIn, YouTube)."
},
"typeVersion": 1
},
{
"id": "90105c8e-5fb0-4626-a18a-41f3aa05e5b2",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-432,
-944
],
"parameters": {
"color": 7,
"width": 384,
"height": 544,
"content": "## Requirements\n\n* OpenAI API key connected to n8n.\n\n* Google Drive account (for storing article images).\n\n* Late API credentials with platform account IDs.\n\n* Valid list of article URLs."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "c968e6b7-0af4-4269-b953-2961c85e7f67",
"connections": {
"Code": {
"main": [
[
{
"node": "OpenAI",
"type": "main",
"index": 0
}
]
]
},
"HTML1": {
"main": [
[
{
"node": "HTTP Request1",
"type": "main",
"index": 0
}
]
]
},
"OpenAI": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Message a model",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Upload file": {
"main": [
[
{
"node": "GetLate multipublishing",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
},
{
"node": "HTML1",
"type": "main",
"index": 0
}
],
[]
]
},
"HTTP Request1": {
"main": [
[
{
"node": "Upload file",
"type": "main",
"index": 0
}
]
]
},
"Message a model": {
"main": [
[
{
"node": "Message a model1",
"type": "main",
"index": 0
}
]
]
},
"Message a model1": {
"main": [
[
{
"node": "GetLate multipublishing",
"type": "main",
"index": 0
}
]
]
},
"GetLate multipublishing": {
"main": [
[]
]
},
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Edit Fields",
"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.
openAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n template demonstrates how to extract full-text articles from different news websites, summarize them with AI, and automatically generate content for social networks (Twitter, Instagram, Threads, LinkedIn, YouTube).
Source: https://n8n.io/workflows/8694/ — 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 workflow automatically turns any uploaded video into structured blog research using AI tools. It transcribes the video, extracts keywords, runs research based on those keywords, and saves the fin
Marketing agencies, digital agencies, and freelancers who need to streamline their client onboarding process and create consistent, professional documentation for new clients. Perfect for teams handli
Clone_Viral_TikToks_with_AI_Avatars___Auto_Post_to_9_Platforms_using_Perplexity___Blotato. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 42 nodes.
1-Clone_Viral_TikToks_with_AI_Avatars___Auto_Post_to_9_Platforms_using_Perplexity___Blotato. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 42 nodes.
1-Clone_Viral_TikToks_with_AI_Avatars___Auto_Post_to_9_Platforms_using_Perplexity___Blotato. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 42 nodes.