{
  "id": "ZA5qaD1t4XGXynfw",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "POST INSTAGRAM",
  "tags": [],
  "nodes": [
    {
      "id": "96259848-1561-4691-98b2-8fd8218dc0a8",
      "name": "Schedule Trigger1",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1792,
        176
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "daysInterval": 2,
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "be82c8d6-ea67-4790-a620-be50dacbc1f0",
      "name": "AI Agent1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1024,
        176
      ],
      "parameters": {
        "text": "=You are a social media content strategist and visual content creator for Instagram.\n\nYour task is to transform ONE real RSS news item into a useful Instagram post.\n\nYou must return:\n\n1. \"prompt_image\": a prompt to generate one vertical image for Instagram (1080x1350)\n2. \"caption\": a short Instagram caption in Spanish\n\nAvailable information:\n- News title: {{ $json.title }}\n- News summary: {{ $json.contentSnippet }}\n- News link: {{ $json.link }}\n- Category: {{ $('CODE TEMAS').item.json.categoria }}\n- Editorial focus: {{ $('CODE TEMAS').item.json.enfoque }}\n\nBrand direction:\n- Audience: {{ $('CODE TEMAS').item.json.audience }}\n- Brand style: {{ $('CODE TEMAS').item.json.brand_style }}\n- Visual direction: {{ $('CODE TEMAS').item.json.visual_direction }}\n\nGoal:\nTurn a real news story into a visual content piece that is clear, relevant, and useful for entrepreneurs, brands, or businesses.\n\nRules for \"prompt_image\":\n- Describe a concrete and visually clear scene\n- The scene must relate directly to the real news story\n- Avoid generic office scenes and abstract AI clich\u00e9s\n- The image should feel modern, clean, and professional\n- The image must reflect the defined brand direction\n- It should feel aligned with the intended audience and visual style, not generic\n- Format must be vertical 1080x1350\n- No real logos\n- No watermarks\n- No excessive text inside the image\n- If text is included, it must be short, natural, and easy to read\n\nRules for \"caption\":\n- Write in Spanish\n- Maximum 450 characters\n- Explain the impact, opportunity, or lesson of the news for businesses\n- Keep it natural and professional\n- Maximum 3 hashtags\n- No emojis\n- Do not copy the original headline literally\n\nReturn ONLY valid JSON with this exact structure:\n\n{\n  \"prompt_image\": \"string\",\n  \"caption\": \"string\"\n}",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1,
      "alwaysOutputData": false
    },
    {
      "id": "aee53344-c795-484d-8fa4-1c4527c61af8",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -864,
        368
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"prompt_image\": \"string\",\n  \"caption\": \"string\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "1a5c7adf-3766-4857-a02f-4ed880e8e916",
      "name": "Send message and wait for response1",
      "type": "n8n-nodes-base.telegram",
      "position": [
        144,
        176
      ],
      "parameters": {
        "message": "={{ $('AI Agent1').item.json.output.caption }}",
        "options": {
          "limitWaitTime": {
            "values": {
              "resumeUnit": "minutes",
              "resumeAmount": 5
            }
          }
        },
        "operation": "sendAndWait",
        "approvalOptions": {
          "values": {
            "approvalType": "double"
          }
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ad6ecf73-5dfe-42fb-a536-920f1d683bb7",
      "name": "Send a photo message1",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -48,
        176
      ],
      "parameters": {
        "operation": "sendPhoto",
        "binaryData": true,
        "additionalFields": {},
        "binaryPropertyName": "image"
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6cc6dd74-d8b2-4eb9-a6b1-3166ed139932",
      "name": "Publish1",
      "type": "@mookielianhd/n8n-nodes-instagram.instagram",
      "position": [
        768,
        144
      ],
      "parameters": {
        "node": "your own account ID",
        "caption": "={{ $('AI Agent1').item.json.output.caption }}",
        "imageUrl": "={{ $json.public_image_url }}",
        "additionalFields": {}
      },
      "credentials": {
        "instagramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0defe584-b68f-4462-8f4f-c423fe2262e1",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        560,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "94dbe8de-7414-4c4f-8351-06a5ea62fad7",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.approved }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "6db4c197-20db-46b3-b944-def05065b47b",
      "name": "CODE TEMAS",
      "type": "n8n-nodes-base.code",
      "position": [
        -1584,
        176
      ],
      "parameters": {
        "jsCode": "const now = new Date();\nconst startOfYear = new Date(now.getFullYear(), 0, 1);\nconst dayOfYear = Math.floor((now - startOfYear) / 86400000);\n\nconst topics = [\n  {\n    categoria: \"AI for entrepreneurs\",\n    feed_url: \"https://news.google.com/rss/search?q=AI+startup+founder+small+business&hl=en-US&gl=US&ceid=US:en\",\n    enfoque: \"opportunity\"\n  },\n  {\n    categoria: \"AI tools for productivity\",\n    feed_url: \"https://news.google.com/rss/search?q=AI+tools+productivity+small+business+automation&hl=en-US&gl=US&ceid=US:en\",\n    enfoque: \"practical use\"\n  },\n  {\n    categoria: \"AI risks for business\",\n    feed_url: \"https://news.google.com/rss/search?q=AI+business+risk+mistake+automation+failure&hl=en-US&gl=US&ceid=US:en\",\n    enfoque: \"risk awareness\"\n  },\n  {\n    categoria: \"Real AI business cases\",\n    feed_url: \"https://news.google.com/rss/search?q=AI+case+study+startup+growth&hl=en-US&gl=US&ceid=US:en\",\n    enfoque: \"real example\"\n  },\n  {\n    categoria: \"AI trends and opportunities\",\n    feed_url: \"https://news.google.com/rss/search?q=AI+business+trend+opportunity&hl=en-US&gl=US&ceid=US:en\",\n    enfoque: \"trend insight\"\n  }\n];\n\nconst topicIndex = dayOfYear % topics.length;\nconst picked = topics[topicIndex];\n\nreturn [\n  {\n    json: {\n      fecha: now.toISOString().slice(0, 10),\n      topic_index: topicIndex,\n      categoria: picked.categoria,\n      feed_url: picked.feed_url,\n      enfoque: picked.enfoque,\n      audience: \"entrepreneurs and small business owners\",\n      brand_style: \"modern, clean, premium\",\n      visual_direction: \"editorial Instagram ad with strong focal point\"\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "e4381223-ae9d-403c-a17d-5056c23d9f23",
      "name": "CODE RSS",
      "type": "n8n-nodes-base.code",
      "position": [
        -1264,
        176
      ],
      "parameters": {
        "jsCode": "// Toma todos los items que vienen del RSS Read\nconst items = $input.all();\n\n// Si no hay nada, devuelve vac\u00edo\nif (!items.length) return [];\n\n// Ordenar por fecha (isoDate) descendente\nitems.sort((a, b) => {\n  const da = new Date(a.json.isoDate || a.json.pubDate || 0).getTime();\n  const db = new Date(b.json.isoDate || b.json.pubDate || 0).getTime();\n  return db - da;\n});\n\n// Quedarnos con el primero (m\u00e1s reciente)\nreturn [items[0]];"
      },
      "typeVersion": 2
    },
    {
      "id": "22f48f89-6811-4282-a850-695cc1ac3536",
      "name": "CODE BINARY",
      "type": "n8n-nodes-base.code",
      "position": [
        -432,
        176
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Toma el base64 de la respuesta de Gemini (inlineData.data)\nconst b64 = $json.candidates?.[0]?.content?.parts?.find(p => p.inlineData)?.inlineData?.data;\n\nif (!b64) {\n  throw new Error('No encontr\u00e9 inlineData.data en la respuesta. Revisa el path candidates[0].content.parts[].inlineData.data');\n}\n\n// Construye binario para n8n\nitem.binary = item.binary || {};\nitem.binary.image = {\n  data: b64,                // base64 puro, sin \"data:image/png;base64,\"\n  mimeType: 'image/png',\n  fileName: `imagen_${Date.now()}.png`,\n\n};\n\nreturn item;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "561026aa-ccb7-4b0f-b607-29bb37d22a95",
      "name": "Upload a file",
      "type": "n8n-nodes-base.s3",
      "position": [
        48,
        0
      ],
      "parameters": {
        "fileName": "={{ $('Edit Image1').item.json.responseId }}",
        "operation": "upload",
        "additionalFields": {},
        "binaryPropertyName": "image"
      },
      "credentials": {
        "s3": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "123a0ab5-fa17-4ad7-9212-babee9cb96f3",
      "name": "Edit Image1",
      "type": "n8n-nodes-base.editImage",
      "position": [
        -304,
        176
      ],
      "parameters": {
        "options": {
          "format": "jpeg"
        },
        "operation": "resize",
        "dataPropertyName": "image"
      },
      "typeVersion": 1
    },
    {
      "id": "9533bda4-51d2-4448-b13e-6678d6d4f94a",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        400,
        160
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "91f4af3c-5f78-4f4f-8ee8-da1e5fe59401",
      "name": "RSS Noticias",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        -1424,
        176
      ],
      "parameters": {
        "url": "={{ $json.feed_url }}",
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "d99670ff-2705-43fa-b1e9-1f1652c91a91",
      "name": "HTTP NANOBANANA 3.1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -608,
        176
      ],
      "parameters": {
        "method": "POST",
        "options": {},
        "jsonBody": "={{\n{\n  contents: [\n    {\n      role: \"user\",\n      parts: [\n        { text: $json.output.prompt_imagen }\n      ]\n    }\n  ]\n}\n}}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "X-goog-api-key",
              "value": "YOUR_API_KEY_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "e53e38da-a268-4514-9722-a618a596883c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1616,
        -176
      ],
      "parameters": {
        "color": 5,
        "width": 480,
        "height": 496,
        "content": "## News sources\n\nThis workflow uses a rotating list of RSS feeds grouped by topic.\n\n**What happens here:**\n- one topic is selected for the current run\n- one matching RSS feed is used\n- the latest news item is extracted\n\n**You can customize:**\n- RSS feed URLs\n- content themes\n- editorial focus\n\n**Result:** a fresh content angle without manual research."
      },
      "typeVersion": 1
    },
    {
      "id": "5f92b455-5444-4b7f-8122-4810bd227625",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1088,
        -176
      ],
      "parameters": {
        "width": 368,
        "height": 704,
        "content": "## AI prompt generation\n\nThis block transforms news into social media content.\n\n**What the AI creates:**\n- an image generation prompt\n- a short Instagram caption\n\n**Goal:**\nTurn real information into engaging, usable content.\n\n**Result:** structured input ready for image generation."
      },
      "typeVersion": 1
    },
    {
      "id": "8c096ad7-f73f-46b2-b6f8-408b836335cf",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        -112
      ],
      "parameters": {
        "width": 512,
        "height": 448,
        "content": "## Image generation\n\nThis block creates the **final Instagram-ready image**.\n\n**What happens here:**\n- AI output is used as input\n- Image is generated via API\n- Response is converted into binary\n- Image is resized to the final format\n\n**Result:** a clean, ready-to-use visual asset."
      },
      "typeVersion": 1
    },
    {
      "id": "b5c21b0c-f74c-4193-b484-8b2a9b2c483d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        -432
      ],
      "parameters": {
        "color": 6,
        "width": 416,
        "height": 576,
        "content": "## Image hosting (required)\n\nThis step uploads the generated image to cloud storage to create a public URL.\n\n**Why this is required:**\n- Instagram API requires a public image URL\n- It does NOT accept binary files directly\n\n**What happens here:**\n- the generated image is uploaded\n- a public URL is created\n- that URL is used in the publish step\n\n**You must configure:**\n- a storage provider (S3, or similar)\n- public access to the file or link\n\n**Result:** a valid public image URL that Instagram can use."
      },
      "typeVersion": 1
    },
    {
      "id": "c0390749-7339-4d39-bafd-fecd8f55479f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        160
      ],
      "parameters": {
        "color": 3,
        "width": 416,
        "height": 432,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Approval step\n\nBefore publishing, content is sent for manual review.\n\n**This helps validate:**\n- image quality\n- caption clarity\n- brand alignment\n\n**Result:** better control before going live."
      },
      "typeVersion": 1
    },
    {
      "id": "5542bc9a-a8ed-48cb-a216-a59a78c94135",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        -64
      ],
      "parameters": {
        "color": 4,
        "width": 560,
        "height": 592,
        "content": "## Publish\n\nOnce approved, the workflow publishes the content to Instagram automatically.\n\n**What happens:**\n- image is posted\n- caption is included\n- no manual publishing required\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n**Important:**\nReplace all credentials and IDs before using.\nThe publish step expects a field called: \"public_image_url\"\n\nMake sure your upload node returns this field.\n\n**Result:** fully automated social media publishing."
      },
      "typeVersion": 1
    },
    {
      "id": "1d8f73ca-0af6-426d-853e-ace19008d72c",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1616,
        -512
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 304,
        "content": "## Setup\n\nTo use this workflow:\n\n1. Connect your AI provider (OpenAI or Google Gemini)\n2. Add your image generation API key\n3. Connect your Instagram account\n4. Configure image hosting (S3)\n   \u2192 The image must be publicly accessible via URL5. \n5. Replace any placeholder values in the HTTP node\n\nEstimated setup time: 10\u201320 minutes"
      },
      "typeVersion": 1
    },
    {
      "id": "a7aa4226-7d30-45ff-9934-83deccf3c45a",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1968,
        -208
      ],
      "parameters": {
        "color": 4,
        "width": 320,
        "height": 544,
        "content": "## Trigger\n\nThis workflow runs automatically on a schedule.\n\n**What it does:**\n- Generates new Instagram content periodically\n- Requires no manual input once configured\n\n**You can adjust:**\n- frequency (daily, weekly, etc.)\n\n**Result:** continuous content generation without manual effort."
      },
      "typeVersion": 1
    },
    {
      "id": "da62e905-d4fd-4944-8e49-3a4d8b6df4ce",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1616,
        352
      ],
      "parameters": {
        "color": 5,
        "width": 480,
        "height": 304,
        "content": "## Content direction\n\nThis workflow also defines a simple creative direction for the generated post.\n\n**You can customize:**\n- audience\n- brand style\n- visual direction\n\nThese settings help the AI create images that feel more aligned with your brand instead of looking generic."
      },
      "typeVersion": 1
    },
    {
      "id": "bdf16ea7-16bd-43b5-a0ca-4b40bc14bc49",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1040,
        368
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "8b331753-011d-4901-b68d-b3558345339f",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Publish1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CODE RSS": {
      "main": [
        [
          {
            "node": "AI Agent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent1": {
      "main": [
        [
          {
            "node": "HTTP NANOBANANA 3.1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CODE TEMAS": {
      "main": [
        [
          {
            "node": "RSS Noticias",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CODE BINARY": {
      "main": [
        [
          {
            "node": "Edit Image1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Image1": {
      "main": [
        [
          {
            "node": "Send a photo message1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Upload a file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RSS Noticias": {
      "main": [
        [
          {
            "node": "CODE RSS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload a file": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger1": {
      "main": [
        [
          {
            "node": "CODE TEMAS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP NANOBANANA 3.1": {
      "main": [
        [
          {
            "node": "CODE BINARY",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a photo message1": {
      "main": [
        [
          {
            "node": "Send message and wait for response1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Send message and wait for response1": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  }
}