{
  "name": "AI-powered X (Twitter) content generator and scheduler with LangChain and Blotato",
  "nodes": [
    {
      "id": "13440d5f-a35c-4968-b586-450cac904f49",
      "name": "LLM: OpenRouter",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -280,
        384
      ]
    },
    {
      "id": "8ce3e713-f572-4d1f-b39f-6d4356f09d36",
      "name": "AI: Generate X Post Content",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -288,
        160
      ]
    },
    {
      "id": "37f408af-806e-483d-b750-e12ba3c0ea27",
      "name": "Parser: Format AI Output to JSON",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -152,
        384
      ]
    },
    {
      "id": "51964d4e-1211-4194-be67-6bbf6c23d9ef",
      "name": "Google Sheets: Save Generated Post as 'Not Posted'",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        288,
        160
      ]
    },
    {
      "id": "b4732535-56d6-4503-a743-3c23daf1b3ec",
      "name": "Blotato: Post Text-Only Tweet",
      "type": "@blotato/n8n-nodes-blotato.blotato",
      "position": [
        1632,
        256
      ]
    },
    {
      "id": "2c74a705-79be-4473-bfed-4f9dc6871947",
      "name": "Gmail: Send 'Post Complete' Notification",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1856,
        160
      ]
    },
    {
      "id": "7eb7e55e-aefb-4305-854a-e6f098daaeb7",
      "name": "Google Sheets: Update Post Status to 'Completed'",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2080,
        160
      ]
    },
    {
      "id": "a00c8615-345d-47ef-a8a3-1c957a7397cb",
      "name": "Google Sheets: Get 'Not Posted' Row for Posting",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        512,
        160
      ]
    },
    {
      "id": "49c0f318-a0a9-48db-8ebb-5400cc57175d",
      "name": "If: Does Post Need an Image?",
      "type": "n8n-nodes-base.if",
      "position": [
        736,
        160
      ]
    },
    {
      "id": "0cf92b8d-a758-44e9-b76f-54958314ff49",
      "name": "Google Drive: Find Image by Category Name",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        960,
        64
      ]
    },
    {
      "id": "8d809919-fb1c-43c9-ae57-246cc7ca3b7e",
      "name": "Blotato: Post Tweet with Image",
      "type": "@blotato/n8n-nodes-blotato.blotato",
      "position": [
        1632,
        64
      ]
    },
    {
      "id": "9bb0cb38-fead-4ab6-bcbf-18984ce9f1c2",
      "name": "Google Drive: Download Image File",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1184,
        64
      ]
    },
    {
      "id": "d400529c-8221-42af-8937-42cbed08fcd8",
      "name": "Blotato: Upload Image Media",
      "type": "@blotato/n8n-nodes-blotato.blotato",
      "position": [
        1408,
        64
      ]
    },
    {
      "id": "f56b070b-7101-49ff-a9ec-68a56ecdec64",
      "name": "Code: Clean Up Post Text",
      "type": "n8n-nodes-base.code",
      "position": [
        64,
        160
      ]
    },
    {
      "id": "07a90bb5-832e-4598-90b1-df9f3cab0b41",
      "name": "Trigger: Every 4 Hours",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -512,
        160
      ]
    },
    {
      "id": "e22d952a-decf-4bd0-b4bd-8b832b31a89c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -704,
        -20
      ],
      "parameters": {
        "width": 240,
        "height": 160,
        "content": "**Trigger: Every 4 Hours**\n\n**Role:** The starting point for the entire workflow.\n**Settings:** Set to run \"every 4 hours\" to periodically generate new post content."
      }
    },
    {
      "id": "e519e95e-1763-4796-9815-592f750b3e7f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -376,
        -100
      ],
      "parameters": {
        "width": 260,
        "height": 200,
        "content": "**AI: Generate X Post Content**\n\n**Role:** The command center that instructs the AI to generate a post based on a defined persona and rules.\n**Settings:** Defines strict rules such as persona, purpose"
      }
    },
    {
      "id": "4d166c4c-7c09-4177-bb89-7243c3937107",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -20
      ],
      "parameters": {
        "width": 260,
        "height": 180,
        "content": "**Code: Clean Up Post Text**\n\n**Role:** Cleans up the AI-generated text to ensure it ends naturally and doesn't get cut off.\n**Settings:** Uses JS code to find punctuation or emojis and truncates the "
      }
    },
    {
      "id": "e98e211e-b9b0-410a-b141-94578b9432d6",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        288,
        -44
      ],
      "parameters": {
        "width": 280,
        "height": 160,
        "content": "**G-Sheets: Save Generated Post...**\n\n**Role:** Saves the AI-generated post draft to a management Google Sheet.\n**Settings:** Writes \"Not Posted\" to the `Status` column, adding it to the queue of unpu"
      }
    },
    {
      "id": "a9042b3b-851d-4054-915f-6a7516848c5b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        280
      ],
      "parameters": {
        "width": 280,
        "height": 160,
        "content": "**G-Sheets: Get 'Not Posted' Row...**\n\n**Role:** Retrieves the next post to be published from the queue in the Google Sheet.\n**Settings:** Fetches the first row where the `Status` column is \"Not Poste"
      }
    },
    {
      "id": "921869e5-6b87-4348-844c-0cddca51c034",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        280
      ],
      "parameters": {
        "width": 260,
        "height": 160,
        "content": "**If: Does Post Need an Image?**\n\n**Role:** Determines if an image is needed based on the category and branches the workflow.\n- **True:** Proceeds to the 'Post with Image' route.\n- **False:** Proceeds"
      }
    },
    {
      "id": "d0413f28-2a07-425b-80a2-231a4a2f8b50",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        -140
      ],
      "parameters": {
        "width": 340,
        "height": 160,
        "content": "**G-Drive: Find Image...** -> **Download Image...** -> **Blotato: Upload Image...** -> **Blotato: Post Tweet with Image**\n\n**Role:** Finds an image by category name, downloads it, uploads it, and then"
      }
    },
    {
      "id": "6ebec956-628d-424a-b51f-50b3294c77c1",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1480,
        344
      ],
      "parameters": {
        "width": 220,
        "height": 100,
        "content": "**Blotato: Post Text-Only Tweet**\n\n**Role:** Executes the posting of a text-only tweet."
      }
    },
    {
      "id": "3589b91e-bce4-4e20-911e-289b4f910404",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1856,
        280
      ],
      "parameters": {
        "width": 300,
        "height": 140,
        "content": "**Gmail: Send...** -> **G-Sheets: Update...**\n\n**Role:** Sends an email notification upon completion and updates the sheet's status to \"Completed\" to prevent duplicate posts."
      }
    }
  ],
  "connections": {
    "LLM: OpenRouter": {
      "ai_languageModel": [
        [
          {
            "node": "AI: Generate X Post Content",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Trigger: Every 4 Hours": {
      "main": [
        [
          {
            "node": "AI: Generate X Post Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: Clean Up Post Text": {
      "main": [
        [
          {
            "node": "Google Sheets: Save Generated Post as 'Not Posted'",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI: Generate X Post Content": {
      "main": [
        [
          {
            "node": "Code: Clean Up Post Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Blotato: Upload Image Media": {
      "main": [
        [
          {
            "node": "Blotato: Post Tweet with Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If: Does Post Need an Image?": {
      "main": [
        [
          {
            "node": "Google Drive: Find Image by Category Name",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Blotato: Post Text-Only Tweet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Blotato: Post Text-Only Tweet": {
      "main": [
        [
          {
            "node": "Gmail: Send 'Post Complete' Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Blotato: Post Tweet with Image": {
      "main": [
        [
          {
            "node": "Gmail: Send 'Post Complete' Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parser: Format AI Output to JSON": {
      "ai_outputParser": [
        [
          {
            "node": "AI: Generate X Post Content",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive: Download Image File": {
      "main": [
        [
          {
            "node": "Blotato: Upload Image Media",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail: Send 'Post Complete' Notification": {
      "main": [
        [
          {
            "node": "Google Sheets: Update Post Status to 'Completed'",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive: Find Image by Category Name": {
      "main": [
        [
          {
            "node": "Google Drive: Download Image File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets: Get 'Not Posted' Row for Posting": {
      "main": [
        [
          {
            "node": "If: Does Post Need an Image?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets: Save Generated Post as 'Not Posted'": {
      "main": [
        [
          {
            "node": "Google Sheets: Get 'Not Posted' Row for Posting",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}