{
  "id": "GhhQipbYpxeWDukK",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Text To Image Flux AI copy",
  "tags": [],
  "nodes": [
    {
      "id": "b3c3a883-4999-4b37-9f34-dc0d39e74900",
      "name": "Google Sheets2",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -400,
        -480
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "4d98ceae-2e2b-44cc-a885-ac9df6c8445c",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -160,
        -480
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "64c9af39-3b1d-4095-b5df-c4a6010e8ba5",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        1500,
        -160
      ],
      "parameters": {
        "amount": 10
      },
      "typeVersion": 1.1
    },
    {
      "id": "81fbbaf8-5f0d-42b1-bb96-dad3a61caf7b",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -600,
        -480
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "1e7416e9-9331-4d13-b7ab-447aa37d7cdc",
      "name": "If2",
      "type": "n8n-nodes-base.if",
      "position": [
        100,
        -460
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e0b7b7c8-3a7a-466d-bae7-269282b49d34",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.Prompt }}",
              "rightValue": ""
            },
            {
              "id": "64dde394-0e49-4306-a24a-de2bf448fc95",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json['drive path'] }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "59f2d118-2bb7-46a2-8dde-95dff6d681fc",
      "name": "If1",
      "type": "n8n-nodes-base.if",
      "position": [
        680,
        -200
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "205d9270-aa0e-4864-bbb6-c67206eda0a2",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.error }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c5fbcba1-9b63-4493-8547-8c55698fa5ba",
      "name": "Google Sheets4",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        960,
        -180
      ],
      "parameters": {
        "columns": {
          "value": {
            "Base64": "={{ $json.error }}",
            "Prompt": "={{ $json.Prompt }}"
          },
          "schema": [
            {
              "id": "Prompt",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Prompt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "drive path",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "drive path",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Generated Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Generated Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Base64",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Base64",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Prompt"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "647c344f-689a-40b5-a7ea-b1ec84b50866",
      "name": "Code1",
      "type": "n8n-nodes-base.code",
      "position": [
        640,
        -620
      ],
      "parameters": {
        "jsCode": "const base64String = $input.first().json.image_base64;\nconsole.log(base64String);\n// If it includes a prefix like 'data:image/jpeg;base64,', split it\nconst cleanedBase64 = base64String.includes(\",\")\n  ? base64String.split(\",\")[1]\n  : base64String;\n\nreturn [\n  {\n    binary: {\n      data: {\n        data: Buffer.from(cleanedBase64, 'base64'),\n        mimeType: 'image/jpeg', // or image/png depending on the format\n        fileName: 'output.jpg'\n      }\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "7b99ef51-5c71-4a5a-8e2f-6bd86446c2b6",
      "name": "Google Sheets1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        940,
        -580
      ],
      "parameters": {
        "columns": {
          "value": {
            "Base64": "={{ $('HTTP Request1').item.json.image_base64 }}",
            "Prompt": "={{ $('If2').item.json.Prompt }}",
            "Generated Date": "={{$now}}"
          },
          "schema": [
            {
              "id": "Prompt",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Prompt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "drive path",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "drive path",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Generated Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Generated Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Base64",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Base64",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "7def0479-c62e-4c9f-8001-03cafdea3c74",
      "name": "HTTP Request1",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        340,
        -500
      ],
      "parameters": {
        "url": "https://text-to-image-flux-ai.p.rapidapi.com/flux.php",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "prompt",
              "value": "={{ $json.Prompt }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "x-rapidapi-host",
              "value": "text-to-image-flux-ai.p.rapidapi.co"
            },
            {
              "name": "x-rapidapi-key",
              "value": "your key"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e6645ea0-8ec7-46a3-a04d-12fef706a03d",
      "name": "Google Drive1",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1080,
        -1100
      ],
      "parameters": {
        "name": "={{ $binary.data.fileName }}",
        "driveId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "53711d81-9c16-49dd-917b-76d45730b8a7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1580,
        -1000
      ],
      "parameters": {
        "width": 780,
        "height": 1220,
        "content": "# Text To Image Flux AI Workflow\n\n## Short Description\nAutomates the generation of images from text prompts stored in a Google Sheet, processes the image data, uploads the images to Google Drive, and updates the Google Sheet with the generated image data.\n\n## Use Case\nIdeal for content creators, marketers, or businesses who want to bulk-generate images based on text prompts stored in a spreadsheet without manual intervention.\n\n## Problem Solved\nEliminates the manual process of creating images from text prompts, managing image data, and updating logs, streamlining and scaling image generation workflows.\n\n---\n\n## Workflow Steps (Summary)\n\n1. **Manual Trigger**  \n   Starts the workflow on demand.\n\n2. **Google Sheets2**  \n   Reads text prompts from a Google Sheet.\n\n3. **Loop Over Items**  \n   Processes each prompt individually in batches.\n\n4. **If2 (Condition)**  \n   Checks if the prompt is present and if the image is not already generated (`drive path` empty).\n\n5. **HTTP Request1**  \n   Sends the prompt to the Text To Image Flux AI API to generate the image.\n\n6. **Code1**  \n   Converts the base64 image string from the API response into a binary file.\n\n7. **Google Sheets1**  \n   Appends the base64 image data and generation timestamp back into the Google Sheet.\n\n8. **Google Drive1**  \n   Uploads the generated image file to a specified Google Drive folder.\n\n9. **Google Sheets4**  \n   Updates the original Google Sheet row with errors if any occur.\n\n10. **Wait**  \n    Pauses for 10 seconds between batches to avoid API rate limits or overload.\n\n11. **If1 (Error Check)**  \n    Detects if there is an error from the API call and routes accordingly.\n\n---\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ed7d467c-34ad-42a4-89ce-de69187cf2f1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -680,
        -760
      ],
      "parameters": {
        "height": 500,
        "content": "### 1. When clicking \u2018Execute workflow\u2019 (Manual Trigger)\n- **Type:** Manual trigger  \n- **Purpose:** Starts the workflow manually when you click \u201cExecute workflow.\u201d  \n- **Usage:** Initiates the entire process."
      },
      "typeVersion": 1
    },
    {
      "id": "ca2119ad-fb45-45a0-b3b2-dbbabdf42b35",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -420,
        -760
      ],
      "parameters": {
        "height": 500,
        "content": "### 2. Google Sheets2 (Read Prompts)\n- **Type:** Google Sheets node (read)  \n- **Purpose:** Reads the list of text prompts from a Google Sheet.  \n- **Usage:** Fetches data that drives the image generation process."
      },
      "typeVersion": 1
    },
    {
      "id": "f36a50d3-9610-46be-954d-8d4b691429dc",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        -760
      ],
      "parameters": {
        "height": 500,
        "content": "### 3. Loop Over Items (Split in Batches)\n- **Type:** Split In Batches  \n- **Purpose:** Processes each prompt individually in manageable batches to avoid API overload.  \n- **Usage:** Allows sequential or batch processing of multiple prompts."
      },
      "typeVersion": 1
    },
    {
      "id": "57b85cd9-1d1f-4f8c-8fca-ec1553183917",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        100,
        -760
      ],
      "parameters": {
        "height": 500,
        "content": "### 4. If2 (Check Prompt & Drive Path)\n- **Type:** If node (conditional check)  \n- **Purpose:** Checks if the prompt is present and the image has not already been generated (`drive path` is empty).  \n- **Usage:** Prevents duplicate processing of prompts that already have generated images."
      },
      "typeVersion": 1
    },
    {
      "id": "e9b2273a-643f-47eb-8e37-61418385a841",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        360,
        -760
      ],
      "parameters": {
        "height": 520,
        "content": "### 5. HTTP Request1 (Generate Image)\n- **Type:** HTTP Request (POST)  \n- **Purpose:** Sends the prompt to the Text To Image Flux AI API and receives a base64 encoded image.  \n- **Usage:** Calls the external AI service for image generation."
      },
      "typeVersion": 1
    },
    {
      "id": "2b66a488-d1d6-49f1-84d9-52919b0eb945",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        620,
        -900
      ],
      "parameters": {
        "height": 400,
        "content": "### 6. Code1 (Convert Base64 to Binary)\n- **Type:** Code (JavaScript)  \n- **Purpose:** Converts the base64 image string into a binary format suitable for upload.  \n- **Usage:** Prepares image data for Google Drive upload."
      },
      "typeVersion": 1
    },
    {
      "id": "b9a32ed9-dbc5-48d0-bd0f-cd5656c0c641",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -760
      ],
      "parameters": {
        "width": 380,
        "height": 320,
        "content": "### 7. Google Sheets1 (Append Image Data)\n- **Type:** Google Sheets node (append)  \n- **Purpose:** Appends the generated base64 image and timestamp back to the Google Sheet.  \n- **Usage:** Logs image generation results in the sheet for tracking."
      },
      "typeVersion": 1
    },
    {
      "id": "22f66814-7f95-4a6f-ac46-4030ec422191",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        920,
        -1260
      ],
      "parameters": {
        "width": 440,
        "height": 320,
        "content": "### 8. Google Drive1 (Upload Image)\n- **Type:** Google Drive node (upload)  \n- **Purpose:** Uploads the generated image file to a specified Google Drive folder.  \n- **Usage:** Stores the generated images in the cloud for easy access and sharing."
      },
      "typeVersion": 1
    },
    {
      "id": "97e072fe-1809-447f-9303-1d0fcda6b19c",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        900,
        -420
      ],
      "parameters": {
        "height": 400,
        "content": "### 9. Google Sheets4 (Update Errors)\n- **Type:** Google Sheets node (appendOrUpdate)  \n- **Purpose:** Updates the Google Sheet with error information if image generation fails.  \n- **Usage:** Tracks failures to allow debugging or reprocessing."
      },
      "typeVersion": 1
    },
    {
      "id": "112e8ff7-e2b2-4294-bdbe-744e1d3b1160",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        -380
      ],
      "parameters": {
        "height": 380,
        "content": "### 10. Wait (Pause Between Batches)\n- **Type:** Wait node  \n- **Purpose:** Adds a 10-second pause between batches of processed prompts.  \n- **Usage:** Prevents hitting API rate limits or overloading the system."
      },
      "typeVersion": 1
    },
    {
      "id": "add007b2-05f1-4515-9c18-69604382aee7",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        620,
        -420
      ],
      "parameters": {
        "height": 400,
        "content": "### 11. If1 (Error Handling)\n- **Type:** If node (error check)  \n- **Purpose:** Checks if the API response contains an error.  \n- **Usage:** Routes the flow to handle errors or continue successful processing.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "2f2002fa-33cc-430d-ac3f-fb69999268d0",
  "connections": {
    "If1": {
      "main": [
        [
          {
            "node": "Google Sheets4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If2": {
      "main": [
        [
          {
            "node": "HTTP Request1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "Google Sheets1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Google Drive1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive1": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request1": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets1": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets2": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets4": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "If2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Google Sheets2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}