Automatización de la creación de contenido para blog y LinkedIn
Este es unContent Creation, Multimodal AIflujo de automatización del dominio deautomatización que contiene 28 nodos.Utiliza principalmente nodos como If, Set, Code, Cron, Gmail. Usar OpenAI y Replicate AI image para automatizar la creación de contenido para blog y LinkedIn
- •Cuenta de Google y credenciales de API de Gmail
- •Clave de API de Notion
- •Credenciales de API de LinkedIn
- •Pueden requerirse credenciales de autenticación para la API de destino
- •Clave de API de OpenAI
Nodos utilizados (28)
Categoría
{
"meta": {
"instanceId": "f930580f475173640cf75bd5e1dc94fd2a589d21917d2c231c8fd90eb205f9b82",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "45e081e9-db15-4808-9c26-6f1089f23a0e",
"name": "Cron (Programación)",
"type": "n8n-nodes-base.cron",
"position": [
-1648,
-304
],
"parameters": {
"triggerTimes": {
"item": [
{
"hour": 19
}
]
}
},
"typeVersion": 1
},
{
"id": "7e72fddb-7c81-4bf3-bd96-b02c3ebb53efa",
"name": "Set (Configuraciones)",
"type": "n8n-nodes-base.set",
"position": [
-1424,
-304
],
"parameters": {
"values": {
"string": [
{
"name": "NOTION_DB_ID",
"value": "25496301-7675-81fa-9d31-cedcc7f452c6a"
},
{
"name": "NOTION_PAGE_PARENT",
"value": "XXXXXXXXXXXXXXXXXXXXXXXXXXX"
},
{
"name": "LINKEDIN_PERSON_URN",
"value": "urn:li:person:XXXXXXXX"
},
{
"name": "OPENAI_MODEL",
"value": "gpt-4.1-mini"
},
{
"name": "EMAIL_TO",
"value": "test@mail.com"
}
],
"boolean": [
{
"name": "LINKEDIN_PUBLISH",
"value": true
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 2
},
{
"id": "648ff7d2-a55e-4e0c-8b12-d3634d1f1b958",
"name": "Notion → Consultar BD de Ideas (todas)",
"type": "n8n-nodes-base.notion",
"position": [
-1200,
-304
],
"parameters": {
"simple": false,
"options": {
"sort": {
"sortValue": [
{
"key": "created_time",
"direction": "ascending",
"timestamp": true
}
]
}
},
"resource": "databasePage",
"operation": "getAll",
"returnAll": true,
"databaseId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.NOTION_DB_ID }}"
},
"filterJson": "={\n \"property\": \"published\",\n \"checkbox\": { \"equals\": false }\n}",
"filterType": "json"
},
"credentials": {
"notionApi": {
"id": "AU61TARrYLYMxTj9",
"name": "Notion account"
}
},
"typeVersion": 2
},
{
"id": "c964ef88-6dea-4ea1-ad6c-2eef99b483646",
"name": "IF (¿Tiene Elegibles?)",
"type": "n8n-nodes-base.if",
"position": [
-1200,
0
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "d6c0245f-b296-4a04-861d-84c42736aa997",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.eligible_count > 0 }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "e3a428a0-c52e-47f6-9281-1063f84e587c3",
"name": "Dividir en Lotes (1)",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-656,
-304
],
"parameters": {
"options": {},
"batchSize": 1
},
"typeVersion": 2
},
{
"id": "017d6b4c-52f8-4238-abf1-95f44d08b182b",
"name": "Error Trigger (Si Fallara Cualquier Nodo)",
"type": "n8n-nodes-base.errorTrigger",
"position": [
-1520,
2272
],
"parameters": {},
"typeVersion": 1
},
{
"id": "219ddd0a-9ad8-4555-acf1-b002406738346",
"name": "Contar Elegibles",
"type": "n8n-nodes-base.code",
"position": [
-1424,
0
],
"parameters": {
"jsCode": "// Emit a single item with the eligible count for IF routing\nreturn [{ json: { eligible_count: items.length } }];"
},
"typeVersion": 2
},
{
"id": "7d00232e-be9d-4cdc-b072-eedc64dd79e3c",
"name": "Filtrar No Publicados + Mapear",
"type": "n8n-nodes-base.code",
"position": [
-976,
-304
],
"parameters": {
"jsCode": "/* Filter unpublished + map fields safely */\nconst out = [];\nfor (const item of items) {\n const page = item.json;\n const id = page.id;\n const p = page.properties || {};\n const g = (prop) => {\n if (!prop) return '';\n if (prop.type === 'title' && prop.title?.length) return prop.title.map(t=>t.plain_text).join('');\n if (prop.type === 'rich_text' && prop.rich_text?.length) return prop.rich_text.map(t=>t.plain_text).join('');\n if (prop.type === 'url') return prop.url || '';\n if (prop.type === 'checkbox') return !!prop.checkbox;\n if (prop.type === 'multi_select') return prop.multi_select.map(o=>o.name);\n if (prop.type === 'select') return prop.select?.name || '';\n if (prop.type === 'date') return prop.date?.start || '';\n return '';\n };\n const isPublished = p.published ? !!p.published.checkbox : false;\n if (isPublished) continue;\n\n const title = g(p.title) || page.properties?.Name?.title?.[0]?.plain_text || '';\n const angle = g(p.angle);\n const tags = p.tags ? (p.tags.type === 'multi_select' ? p.tags.multi_select.map(o=>o.name) : g(p.tags)) : '';\n const primary_link = g(p.primary_link);\n const reference_links = g(p.reference_links);\n const images = g(p.images);\n const notes = g(p.notes);\n const target_audience = g(p.target_audience);\n const canonical_url = g(p.canonical_url);\n const language = g(p.language);\n const slug = g(p.slug);\n\n out.push({ json: {\n notion_page_id: id,\n title,\n angle,\n tags,\n primary_link,\n reference_links,\n images,\n notes,\n target_audience,\n canonical_url,\n language,\n slug\n }});\n}\nreturn out;\n"
},
"typeVersion": 2
},
{
"id": "40b826f5-b1ef-490b-b208-f1754c1972d81",
"name": "Enviar un mensaje",
"type": "n8n-nodes-base.gmail",
"position": [
-976,
0
],
"webhookId": "60e2a23b-9c59-485b-a5d3-9c61b2f39a45",
"parameters": {
"sendTo": "={{ $('Set (Configs)').item.json.EMAIL_TO }}",
"message": "=No rows found in {{ $('Set (Configs)').item.json.NOTION_DB_ID }} with published != true at {{$now}}.",
"options": {},
"subject": "Blog Pipeline: No Eligible Notion Rows!",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "g6m2gV1BtMtEggjm",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "87a55a66-d609-47d2-a177-eddb4a7d9d560",
"name": "Analizar y Validar JSON",
"type": "n8n-nodes-base.code",
"position": [
144,
-304
],
"parameters": {
"jsCode": "/**\n * Node 11 — Function (Parse & Validate JSON from OpenAI)\n * Soft-handles safety_flags (warnings) instead of throwing.\n */\n\n// ---------- 1) Extract message.content ----------\nconst input = items[0].json;\n\nfunction extractContent(nodeOut) {\n // n8n OpenAI nodes vary; support a few shapes:\n\n // A) Array of { message: { content } }\n if (Array.isArray(nodeOut) && nodeOut[0]?.message?.content !== undefined) {\n return nodeOut[0].message.content;\n }\n // B) Chat Completions\n if (nodeOut?.data?.choices?.[0]?.message?.content !== undefined) {\n return nodeOut.data.choices[0].message.content;\n }\n // C) OpenAI node returning raw string JSON at top level\n if (typeof nodeOut === \"string\") {\n return nodeOut;\n }\n // D) Flattened shape\n if (nodeOut?.message?.content !== undefined) {\n return nodeOut.message.content;\n }\n // E) Sometimes models already return parsed object\n if (nodeOut?.content !== undefined) {\n return nodeOut.content;\n }\n throw new Error(\"Node11: could not locate message.content from OpenAI output\");\n}\n\nlet content = extractContent(input);\n\n// ---------- 2) Parse to object ----------\nlet parsed;\nif (content && typeof content === \"object\") {\n parsed = content;\n} else if (typeof content === \"string\") {\n let txt = content.trim();\n if (txt.startsWith(\"```\")) {\n txt = txt.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```$/i, \"\");\n }\n txt = txt\n .replace(/[\\u2018\\u2019]/g, \"'\")\n .replace(/[\\u201C\\u201D]/g, '\"')\n .replace(/[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F]/g, \" \")\n .replace(/,\\s*([}\\]])/g, \"$1\");\n\n // escape raw newlines inside strings\n (function escapeNewlinesInStrings() {\n let out = \"\", inStr = false, esc = false;\n for (let i = 0; i < txt.length; i++) {\n const ch = txt[i];\n if (!inStr) { if (ch === '\"') inStr = true; out += ch; continue; }\n if (esc) { out += ch; esc = false; continue; }\n if (ch === \"\\\\\") { out += ch; esc = true; continue; }\n if (ch === '\"') { inStr = false; out += ch; continue; }\n if (ch === \"\\n\" || ch === \"\\r\") { out += \"\\\\n\"; continue; }\n out += ch;\n }\n txt = out;\n })();\n\n try {\n parsed = JSON.parse(txt);\n } catch (e) {\n throw new Error(\"Node11: JSON.parse failed after repair: \" + e.message);\n }\n} else {\n throw new Error(\"Node11: message.content is neither object nor string\");\n}\n\n// ---------- 3) Validate + normalize ----------\nconst errs = [];\nconst warn = [];\nconst isNonEmpty = (s) => typeof s === \"string\" && s.trim().length > 0;\nconst arrOfStr = (a) => Array.isArray(a) ? a.map(x => String(x)).filter(Boolean) : [];\n\nif (!parsed.blog) errs.push(\"blog missing\");\nelse {\n if (!isNonEmpty(parsed.blog.title)) errs.push(\"blog.title missing\");\n if (!isNonEmpty(parsed.blog.slug)) errs.push(\"blog.slug missing\");\n if (!isNonEmpty(parsed.blog.markdown)) errs.push(\"blog.markdown missing\");\n if (parsed.blog.slug && parsed.blog.slug.length > 100) errs.push(\"blog.slug > 100 chars\");\n parsed.blog.keywords = arrOfStr(parsed.blog.keywords);\n parsed.blog.image_alt_texts = arrOfStr(parsed.blog.image_alt_texts);\n if (\n parsed.blog.canonical_url !== null &&\n parsed.blog.canonical_url !== undefined &&\n typeof parsed.blog.canonical_url !== \"string\"\n ) errs.push(\"blog.canonical_url must be string or null\");\n}\n\nif (!parsed.linkedin) errs.push(\"linkedin missing\");\nelse {\n if (!isNonEmpty(parsed.linkedin.final_text)) errs.push(\"linkedin.final_text missing\");\n // hashtags soft window\n parsed.linkedin.hashtags = arrOfStr(parsed.linkedin.hashtags);\n if (parsed.linkedin.hashtags.length > 8) {\n parsed.linkedin.hashtags = parsed.linkedin.hashtags.slice(0, 8);\n }\n // char guard\n let ft = String(parsed.linkedin.final_text || \"\");\n if (ft.length > 1200) {\n let cut = ft.slice(0, 1180);\n const lastBreak = Math.max(cut.lastIndexOf(\"\\n\"), cut.lastIndexOf(\".\"));\n if (lastBreak > 800) cut = cut.slice(0, lastBreak + 1);\n parsed.linkedin.final_text = cut;\n warn.push(\"linkedin.final_text truncated to 1200 chars\");\n }\n}\n\n// Safety flags: treat as warnings (expose downstream)\nif (!Array.isArray(parsed.safety_flags)) parsed.safety_flags = [];\nif (parsed.safety_flags.length) {\n warn.push(\"safety_flags present: \" + parsed.safety_flags.join(\", \"));\n}\n\n// Hard errors?\nif (errs.length) {\n throw new Error(\"Node11 validation failed: \" + errs.join(\"; \"));\n}\n\n// ---------- 4) Merge with Normalize Arrays (Node 9), return ----------\nlet norm = {};\ntry {\n const n = $items(\"Function (Normalize Arrays)\", 0, $runIndex);\n if (Array.isArray(n) && n[0] && n[0].json) norm = n[0].json;\n} catch (_) {}\n\nreturn [{\n json: {\n ...norm,\n openai: parsed,\n warnings: warn\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "3ab2103a-a358-415c-a4d1-1df7c3cb14f5",
"name": "Normalizar Arrays",
"type": "n8n-nodes-base.code",
"position": [
-432,
-304
],
"parameters": {
"jsCode": "// Normalize arrays + carry configs\nfunction toArray(v){\n if (Array.isArray(v)) return v;\n if (typeof v === 'string'){\n const s = v.trim();\n if (!s) return [];\n try { const parsed = JSON.parse(s); if (Array.isArray(parsed)) return parsed; } catch(e) {}\n return s.split(',').map(x=>x.trim()).filter(Boolean);\n }\n return [];\n}\n\n// Pull config from the Set (Configs) node\n// Simple form:\nconst cfg = $node[\"Set (Configs)\"].json;\n// Robust form (if you prefer):\n// const cfg = $items(\"Set (Configs)\", 0, $runIndex)[0].json;\n\nconst i = items[0].json;\n\nreturn [{\n json: {\n NOTION_DB_ID: cfg.NOTION_DB_ID,\n NOTION_PAGE_PARENT: cfg.NOTION_PAGE_PARENT,\n LINKEDIN_PERSON_URN: cfg.LINKEDIN_PERSON_URN,\n OPENAI_MODEL: cfg.OPENAI_MODEL,\n EMAIL_TO: cfg.EMAIL_TO,\n\n notion_page_id: i.notion_page_id,\n title: i.title || '',\n angle: i.angle || '',\n tags: toArray(i.tags),\n primary_link: i.primary_link || '',\n reference_links: toArray(i.reference_links),\n images: toArray(i.images),\n notes: i.notes || '',\n target_audience: i.target_audience || '',\n canonical_url: i.canonical_url || '',\n language: i.language || '',\n slug: i.slug || ''\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "52a1ad9c-cc6a-49a1-ab7f-9b3a8a2e8c2b",
"name": "Crear una publicación",
"type": "n8n-nodes-base.linkedIn",
"position": [
1872,
-432
],
"parameters": {
"text": "={{ $('Content Creator').item.json.message.content.linkedin.final_text }}",
"person": "k47kCb899q",
"additionalFields": {
"title": "={{ $('Content Creator').item.json.message.content.blog.title }}",
"visibility": "PUBLIC"
},
"binaryPropertyName": "=data",
"shareMediaCategory": "IMAGE"
},
"credentials": {
"linkedInOAuth2Api": {
"id": "DzG9q9KGhJCP5FSt",
"name": "LinkedIn account"
}
},
"typeVersion": 1
},
{
"id": "128ee066-dca2-4c19-830b-621e3eafbbc0",
"name": "Crear Página en BD de Artículos",
"type": "n8n-nodes-base.notion",
"position": [
432,
-304
],
"parameters": {
"title": "={{ $json.openai.blog.title }}",
"simple": false,
"options": {},
"resource": "databasePage",
"databaseId": {
"__rl": true,
"mode": "list",
"value": "25496301-7675-81bc-b023-c7e012094120",
"cachedResultUrl": "https://www.notion.so/25496301767581bcb023c7e012094120",
"cachedResultName": "Articles"
},
"propertiesUi": {
"propertyValues": [
{
"key": "title|title",
"title": "={{ $json.openai.blog.title }}"
},
{
"key": "slug|rich_text",
"text": {
"text": [
{
"text": "={{ $json.openai.blog.slug }}",
"annotationUi": {}
}
]
},
"richText": true
},
{
"key": "excerpt|rich_text",
"text": {
"text": [
{
"text": "={{ $json.openai.blog.excerpt }}",
"annotationUi": {}
}
]
},
"richText": true
},
{
"key": "keywords|multi_select",
"multiSelectValue": "={{ $json.openai.blog.keywords }}"
},
{
"key": "canonical_url|url",
"urlValue": "={{ $json.openai.blog.canonical_url || '' }}",
"ignoreIfEmpty": true
},
{
"key": "suggested_cover_caption|rich_text",
"text": {
"text": [
{
"text": "={{ $json.openai.blog.suggested_cover_caption }}",
"annotationUi": {}
}
]
},
"richText": true
},
{
"key": "image_alt_texts|rich_text",
"text": {
"text": [
{
"text": "={{ $json.openai.blog.image_alt_texts.join(', ') }}",
"annotationUi": {}
}
]
},
"richText": true
},
{
"key": "language|select",
"selectValue": "={{ $('Split In Batches (1)').item.json.language || 'en' }}"
},
{
"key": "tags|multi_select",
"multiSelectValue": "={{ $json.openai.linkedin.hashtags }}"
},
{
"key": "status|select",
"selectValue": "Published"
},
{
"key": "published_at|date",
"date": "={{ $now }}",
"timezone": "Asia/Kathmandu"
},
{
"key": "source_idea|relation",
"relationValue": [
"={{ $('Split In Batches (1)').item.json.notion_page_id }}"
]
},
{
"key": "linkedin_draft|rich_text",
"text": {
"text": [
{
"text": "={{ $json.openai.linkedin.final_text }}",
"annotationUi": {}
}
]
},
"richText": true
}
]
}
},
"credentials": {
"notionApi": {
"id": "AU61TARrYLYMxTj9",
"name": "Notion account"
}
},
"typeVersion": 2.2
},
{
"id": "6160be76-97f5-4f4c-bfa6-5e480080d854",
"name": "Borrador de Email",
"type": "n8n-nodes-base.gmail",
"position": [
1120,
-80
],
"webhookId": "4a91eae9-a78f-4246-bdf2-faaf10f3afdd",
"parameters": {
"sendTo": "={{ $('Set (Configs)').item.json.EMAIL_TO }}",
"message": "=Title: {{ $json.properties.title.title[0].text.content }}\nDraft: {{ $json.properties.linkedin_draft.rich_text[0].text.content }}",
"options": {},
"subject": "LinkedIn Draft Ready",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "g6m2gV1BtMtEggjm",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "a1a7482f-3868-402c-a05b-2535b8443ad7",
"name": "Email de Publicado",
"type": "n8n-nodes-base.gmail",
"position": [
2096,
-432
],
"webhookId": "f2d6603d-058d-43dd-8d67-aaed9476c825",
"parameters": {
"sendTo": "mail@budhathokisagar.com.np",
"message": "=Published: {{ $('Create a Article Database Page').item.json.properties.title.title[0].text.content }}\nSlug: {{ $('Create a Article Database Page').item.json.properties.slug.rich_text[0].text.content }}\nLinkedIn: posted as person.\nIdea Page: {{ $('Create a Article Database Page').item.json.id }}",
"options": {},
"subject": "LinkedIn Post Published!",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "g6m2gV1BtMtEggjm",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "a7b80170-9832-46fb-85ba-8b87c5bd9da4",
"name": "Borrador de Actualizar BD",
"type": "n8n-nodes-base.notion",
"position": [
1344,
-80
],
"parameters": {
"pageId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Create a Article Database Page').item.json.id }}"
},
"simple": false,
"options": {},
"resource": "databasePage",
"operation": "update",
"propertiesUi": {
"propertyValues": [
{
"key": "status|select",
"selectValue": "Draft"
}
]
}
},
"credentials": {
"notionApi": {
"id": "AU61TARrYLYMxTj9",
"name": "Notion account"
}
},
"typeVersion": 2.2
},
{
"id": "4e43c32b-407c-4a62-8a0d-2b5eea10c615",
"name": "Actualizar página de BD",
"type": "n8n-nodes-base.notion",
"position": [
2320,
-432
],
"parameters": {
"pageId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Create a Article Database Page').item.json.id }}"
},
"simple": false,
"options": {},
"resource": "databasePage",
"operation": "update",
"propertiesUi": {
"propertyValues": [
{
"key": "status|select",
"selectValue": "Published"
}
]
}
},
"credentials": {
"notionApi": {
"id": "AU61TARrYLYMxTj9",
"name": "Notion account"
}
},
"typeVersion": 2.2
},
{
"id": "c3dfe348-0a68-45ee-b538-2f72fdbffaa9",
"name": "Descargar Imagen",
"type": "n8n-nodes-base.httpRequest",
"position": [
1648,
-432
],
"parameters": {
"url": "={{ $json.output[0] }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "4b21b649-4087-4ef2-aa8d-9ee53c5db581",
"name": "Replicate Predicción de Imagen",
"type": "n8n-nodes-base.httpRequest",
"position": [
1424,
-432
],
"parameters": {
"url": "https://api.replicate.com/v1/models/black-forest-labs/flux-schnell/predictions",
"method": "POST",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
},
"jsonBody": "={\n \"input\": {\n \"prompt\": \"{{ $json.message.content }}\",\n \"aspect_ratio\": \"16:9\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Prefer",
"value": "wait"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"id": "UMvkuuToRy2C4VYfo",
"name": "Bearer Auth Replicate"
}
},
"typeVersion": 4.2
},
{
"id": "2dd65c1f-d859-4809-857b-7f8b6e535306",
"name": "Creador de Contenido",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
-208,
-304
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini",
"cachedResultName": "GPT-5-MINI"
},
"options": {},
"messages": {
"values": [
{
"content": "=You are a senior technical writer and LinkedIn ghostwriter for a Nepal-based DevOps/CloudOps/SysOps/Python developer who also loves AI/ML. \nYour job is to take one Notion row and turn it into:\n\n1) A polished, human-readable blog article for Hashnode (Markdown only).\n2) A LinkedIn post that feels authentic, insightful, and share-worthy, and most-importantly simpler english.\n\nYour voice should feel like a real engineer sharing something useful:\n- Informative but conversational\n- Confident but humble\n- Sometimes witty, but never forced\n- Includes actionable value (tips, insights, commands, lessons)\n- Occasionally adds light Nepali flavor naturally if language=\"ne\"\n\n---\n### INPUT\n- title: {{ $json.title }}\n- angle: {{ $json.angle }}\n- tags: {{ $json.tags }}\n- primary_link: {{ $json.primary_link }}\n- reference_links: {{ $json.reference_links }}\n- images: {{ $json.images }}\n- notes: {{ $json.notes }}\n- target_audience: {{ $json.target_audience }}\n- canonical_url: {{ $json.canonical_url }}\n- language: {{ $json.language }}\n- slug: {{ $json.slug }}\n\n---\n### PREFERENCES\n- LinkedIn posts ≤ 1200 characters\n- Blog word count:\n - Rich notes/tags: 900–1400 words\n - Sparse notes/tags: 600–900 words\n- Include at least one specific example, command, or actionable tip\n- Only one link allowed in LinkedIn text (if primary_link exists)\n\n---\n### STYLE TARGETS\nFor LinkedIn, pick the most natural style automatically:\n- **Story:** Small anecdote or lesson\n- **Industry Take:** Commentary with reflection\n- **Tech Breakdown:** Clear step-by-step with code/tips\n- **Basics:** Foundational guidance in checklist format\n- **Humor List:** Funny but relatable \"few techs\" overwhelm joke\n- **Optimization/Win:** Real-world result or improvement shared\n\n---\n### BLOG REQUIREMENTS\n- Markdown only, no frontmatter\n- Structure:\n - Hook intro (2–4 lines)\n - Clear sections with H2/H3\n - Include steps, code snippets, or bullet lists\n - Add “Sharp edges & gotchas” with realistic pitfalls\n - Include a mini case/example\n - End with actionable “Key Takeaways” (3–6 bullets)\n- Include:\n - SEO: slug, excerpt, keywords (5–10)\n - Suggested cover caption\n - Alt text suggestions for images\n - Canonical URL if provided\n\n---\n### LINKEDIN REQUIREMENTS\n- Start with a strong HOOK (1–2 lines), do not mention word itself like 'hook' or similar\n- Use short, human paragraphs\n- Include at least one actionable tip or fact\n- Invite engagement with a closing question or CTA\n- Add 5–10 hashtags, a mix of broad (#DevOps #Cloud) and niche (#AWS #Kubernetes #Observability)\n\n---\n### RULES\n- Never invent unknown facts\n- Prioritize clear, human language\n- Favor real-world examples over generic advice\n- Use emojis sparingly and purposefully (max 3)\n\n---\n### OUTPUT SCHEMA\n{\n \"blog\": {\n \"title\": \"string\",\n \"slug\": \"string\",\n \"excerpt\": \"string\",\n \"keywords\": [\"string\", \"...\"],\n \"canonical_url\": \"string|null\",\n \"suggested_cover_caption\": \"string\",\n \"image_alt_texts\": [\"string\", \"...\"],\n \"markdown\": \"string\"\n },\n \"linkedin\": {\n \"style_used\": \"story|industry_take|tech_breakdown|basics|humor_list|optimization\",\n \"final_text\": \"string\",\n \"alt_titles\": [\"string\",\"string\",\"string\"]\n },\n \"safety_flags\": []\n}"
}
]
},
"simplify": "={{ true }}",
"jsonOutput": true
},
"credentials": {
"openAiApi": {
"id": "1JMlq9LFlvNZ4n7z",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "17809fd9-84d8-458b-a904-b497549c10dd",
"name": "Generador de Prompt de Imagen",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1072,
-432
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini",
"cachedResultName": "GPT-4.1-MINI"
},
"options": {},
"messages": {
"values": [
{
"content": "={\n \"title\": \"{{$json.properties?.title?.title?.[0]?.plain_text || ''}}\",\n \"excerpt\": \"{{$json.properties?.excerpt?.rich_text?.[0]?.plain_text || ''}}\",\n \"linkedin_draft\": \"{{$json.properties?.linkedin_draft?.rich_text?.[0]?.plain_text || ''}}\",\n \"alt\": \"{{$json.properties?.image_alt_texts?.rich_text?.[0]?.plain_text || ''}}\",\n \"keywords\": \"{{$json.properties?.keywords?.multi_select?.map(k => k.name).join(', ') || ''}}\"\n}\n"
},
{
"role": "system",
"content": "You generate a single, realistic text-to-image prompt for the Replicate model black-forest-labs/flux-schnell, based on details from a LinkedIn post.\n\nRULES:\n- Output only the prompt as plain text, no JSON, no commentary.\n- Make the scene look photorealistic but clean and professional — perfect for LinkedIn.\n- Focus on key objects, actions, and environment described in the post (title, excerpt, alt, keywords).\n- Include subtle realistic elements (lighting, depth, perspective, color) but keep the layout minimal and balanced.\n- Never include any legible text, logos, watermarks, brand names, or faces.\n- Use soft professional lighting, shallow depth of field, and natural tones.\n- Keep it under ~900 characters.\n- Default to a 16:9 aspect ratio.\n"
}
]
}
},
"credentials": {
"openAiApi": {
"id": "1JMlq9LFlvNZ4n7z",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "20246ca2-9171-4ba8-8009-f43a43296c59",
"name": "Mensaje de Fallo",
"type": "n8n-nodes-base.gmail",
"position": [
-1232,
2272
],
"webhookId": "3fd774cb-ed1a-4d99-9680-46fed3bdeb82",
"parameters": {
"sendTo": "={{$json.execution?.error?.workflow?.data?.startData?.runData?.['Set (Configs)']?.[0]?.json?.EMAIL_TO || 'test@mail.com'}}",
"message": "=Node: {{$json.execution?.error?.node?.name}}\\nMessage: {{$json.execution?.error?.message}}\\nStack: {{$json.execution?.error?.stack}}\\nLast Payload: {{JSON.stringify($json.execution?.error?.node?.data, null, 2).slice(0,5000)}}",
"options": {},
"subject": "=Blog Pipeline ERROR: {{$json.execution?.error?.message || 'Unknown error'}}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "g6m2gV1BtMtEggjm",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "efd5db98-aa5e-46e4-9d6c-4708b8db08a4",
"name": "Nota Adhesiva",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1712,
-624
],
"parameters": {
"color": 4,
"width": 960,
"height": 832,
"content": "# INITIALIZATION & DATA COLLECTION\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n- Cron triggers daily at 7 PM\n- Set configs (DB IDs, email, LinkedIn settings)\n- Query Notion for unpublished ideas\n- Filter & clean the data\n- Count eligible posts\n\nIf no posts found → Send \"nothing to do\" email"
},
"typeVersion": 1
},
{
"id": "0c0f92c8-d1b4-4e11-86cf-dc32022e984b",
"name": "Nota Adhesiva1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-720,
-624
],
"parameters": {
"color": 4,
"width": 1024,
"height": 832,
"content": "# CONTENT PROCESSING & AI GENERATION\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n- Process ideas one by one (batch size: 1)\n- Normalize data for AI prompt\n- OpenAI creates:\n - Full blog post (Markdown)\n - LinkedIn post with hashtags\n - SEO keywords & metadata\n- Validate & parse AI output\n\nQuality control ensures perfect formatting"
},
"typeVersion": 1
},
{
"id": "69e0c3a8-1239-4283-8c64-7c8aa8c3ec4e",
"name": "If LinkedIn Verificación de Publicado",
"type": "n8n-nodes-base.if",
"position": [
640,
-304
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "58a827f7-5153-4641-afbd-9bdf3d62ee2c",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $('Set (Configs)').item.json.LINKEDIN_PUBLISH || false }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.2,
"alwaysOutputData": false
},
{
"id": "b3f96e1b-73d8-4153-84ef-952fd9785888",
"name": "Nota Adhesiva2",
"type": "n8n-nodes-base.stickyNote",
"position": [
336,
-624
],
"parameters": {
"color": 5,
"width": 608,
"height": 832,
"content": "# CONTENT STORAGE & PUBLISH DECISION\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n- Save AI content to Articles database\n- Check LINKEDIN_PUBLISH setting\n\nTwo paths:\nPUBLISH = TRUE → Auto-publish flow\nPUBLISH = FALSE → Draft review flow\n\nAll content safely stored in Notion first"
},
"typeVersion": 1
},
{
"id": "c663ee05-545d-4c1e-995d-26ed92ecba6d",
"name": "Nota Adhesiva3",
"type": "n8n-nodes-base.stickyNote",
"position": [
976,
-624
],
"parameters": {
"color": 5,
"width": 1536,
"height": 832,
"content": ""
},
"typeVersion": 1
},
{
"id": "995fee04-6be5-4b7b-ad46-6a0965696e5c",
"name": "Nota Adhesiva4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1920,
-144
],
"parameters": {
"color": 5,
"width": 592,
"height": 352,
"content": "# PUBLISHING & COMPLETION\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nAUTO-PUBLISH PATH:\n- Generate image prompt → Create image\n- Post to LinkedIn with image\n- Send success email\n- Mark as \"Published\"\n\nDRAFT PATH:\n- Email draft for review\n- Mark as \"Draft\"\n\nBoth paths ensure proper status tracking"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"6160be76-97f5-4f4c-bfa6-5e480080d854": {
"main": [
[
{
"node": "a7b80170-9832-46fb-85ba-8b87c5bd9da4",
"type": "main",
"index": 0
}
]
]
},
"52a1ad9c-cc6a-49a1-ab7f-9b3a8a2e8c2b": {
"main": [
[
{
"node": "a1a7482f-3868-402c-a05b-2535b8443ad7",
"type": "main",
"index": 0
}
]
]
},
"7e72fddb-7c81-4bf3-bd96-b02c3ebb53efa": {
"main": [
[
{
"node": "648ff7d2-a55e-4e0c-8b12-d3634d1f1b958",
"type": "main",
"index": 0
}
]
]
},
"219ddd0a-9ad8-4555-acf1-b002406738346": {
"main": [
[
{
"node": "c964ef88-6dea-4ea1-ad6c-2eef99b483646",
"type": "main",
"index": 0
}
]
]
},
"c3dfe348-0a68-45ee-b538-2f72fdbffaa9": {
"main": [
[
{
"node": "52a1ad9c-cc6a-49a1-ab7f-9b3a8a2e8c2b",
"type": "main",
"index": 0
}
]
]
},
"40b826f5-b1ef-490b-b208-f1754c1972d81": {
"main": [
[]
]
},
"2dd65c1f-d859-4809-857b-7f8b6e535306": {
"main": [
[
{
"node": "87a55a66-d609-47d2-a177-eddb4a7d9d560",
"type": "main",
"index": 0
}
]
]
},
"45e081e9-db15-4808-9c26-6f1089f23a0e": {
"main": [
[
{
"node": "7e72fddb-7c81-4bf3-bd96-b02c3ebb53efa",
"type": "main",
"index": 0
}
]
]
},
"a1a7482f-3868-402c-a05b-2535b8443ad7": {
"main": [
[
{
"node": "4e43c32b-407c-4a62-8a0d-2b5eea10c615",
"type": "main",
"index": 0
}
]
]
},
"3ab2103a-a358-415c-a4d1-1df7c3cb14f5": {
"main": [
[
{
"node": "2dd65c1f-d859-4809-857b-7f8b6e535306",
"type": "main",
"index": 0
}
]
]
},
"c964ef88-6dea-4ea1-ad6c-2eef99b483646": {
"main": [
[],
[
{
"node": "40b826f5-b1ef-490b-b208-f1754c1972d81",
"type": "main",
"index": 0
}
]
]
},
"e3a428a0-c52e-47f6-9281-1063f84e587c3": {
"main": [
[
{
"node": "3ab2103a-a358-415c-a4d1-1df7c3cb14f5",
"type": "main",
"index": 0
}
]
]
},
"87a55a66-d609-47d2-a177-eddb4a7d9d560": {
"main": [
[
{
"node": "128ee066-dca2-4c19-830b-621e3eafbbc0",
"type": "main",
"index": 0
}
]
]
},
"17809fd9-84d8-458b-a904-b497549c10dd": {
"main": [
[
{
"node": "4b21b649-4087-4ef2-aa8d-9ee53c5db581",
"type": "main",
"index": 0
}
]
]
},
"4e43c32b-407c-4a62-8a0d-2b5eea10c615": {
"main": [
[]
]
},
"7d00232e-be9d-4cdc-b072-eedc64dd79e3c": {
"main": [
[
{
"node": "e3a428a0-c52e-47f6-9281-1063f84e587c3",
"type": "main",
"index": 0
},
{
"node": "219ddd0a-9ad8-4555-acf1-b002406738346",
"type": "main",
"index": 0
}
]
]
},
"4b21b649-4087-4ef2-aa8d-9ee53c5db581": {
"main": [
[
{
"node": "c3dfe348-0a68-45ee-b538-2f72fdbffaa9",
"type": "main",
"index": 0
}
]
]
},
"69e0c3a8-1239-4283-8c64-7c8aa8c3ec4e": {
"main": [
[
{
"node": "17809fd9-84d8-458b-a904-b497549c10dd",
"type": "main",
"index": 0
}
],
[
{
"node": "6160be76-97f5-4f4c-bfa6-5e480080d854",
"type": "main",
"index": 0
}
]
]
},
"128ee066-dca2-4c19-830b-621e3eafbbc0": {
"main": [
[
{
"node": "69e0c3a8-1239-4283-8c64-7c8aa8c3ec4e",
"type": "main",
"index": 0
}
]
]
},
"017d6b4c-52f8-4238-abf1-95f44d08b182b": {
"main": [
[
{
"node": "20246ca2-9171-4ba8-8009-f43a43296c59",
"type": "main",
"index": 0
}
]
]
},
"648ff7d2-a55e-4e0c-8b12-d3634d1f1b958": {
"main": [
[
{
"node": "7d00232e-be9d-4cdc-b072-eedc64dd79e3c",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - Creación de contenido, IA Multimodal
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Sagar Budhathoki
@sbmagar13A DevOps and AI Engineer with a passion for automation, infrastructure as code, building resilient systems, and exploring AI agents & MCP technologies.
Compartir este flujo de trabajo