{
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "AI Product Image Generator - Public Template",
  "tags": [],
  "nodes": [
    {
      "id": "16c2ca1d-8986-4533-9bf2-aba9fd0efe61",
      "name": "download_influencer_image",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        960,
        320
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $('Get the Raw').item.json['Model url'] }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "credential-id",
          "name": "googleDriveOAuth2Api Credential"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "9def7a44-23bb-4735-b363-901ac7191efb",
      "name": "upload_image",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1040,
        736
      ],
      "parameters": {
        "name": "=Ad Image {{ $runIndex + 1 }}",
        "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": "YOUR_OUTPUT_FOLDER_ID",
          "cachedResultUrl": "https://drive.google.com/drive/folders/YOUR_OUTPUT_FOLDER_ID",
          "cachedResultName": "Ad Images Output Folder"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "credential-id",
          "name": "googleDriveOAuth2Api Credential"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "42e5857c-b566-4ebd-9bc5-ef5cb900e3ce",
      "name": "Analyze image",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        -64,
        736
      ],
      "parameters": {
        "text": "Analyze the provided product image and generate a detailed ad-ready visual description. Focus on how the product can look its best in a promotional image. Include suggestions for:\n\nThe model (male or female) and how they should pose, hold, or interact with the product naturally.\n\nLighting, background, and environment that highlight the product.\n\nStyling, color harmony, and composition to make the product stand out.\n\nMood or emotion the ad should convey.\n\nDo not include details about the specific model in the image. The description should be suitable for any model and emphasize the product's features and presentation.",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {},
        "resource": "image",
        "inputType": "base64",
        "operation": "analyze"
      },
      "credentials": {
        "openAiApi": {
          "id": "credential-id",
          "name": "openAiApi Credential"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "cf18eb77-e961-4d4f-b7c4-bd6ac81e1751",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -112,
        320
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ddd3fd77-5079-4c58-9bc1-cdb6862eb4f4",
      "name": "Download Product Image",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        336,
        320
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json['Product url'] }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "credential-id",
          "name": "googleDriveOAuth2Api Credential"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "5a328387-8506-4e53-8347-7f76fcf0df38",
      "name": "Convert Binary to Text",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        672,
        320
      ],
      "parameters": {
        "options": {},
        "operation": "binaryToPropery"
      },
      "typeVersion": 1
    },
    {
      "id": "f30a0657-152a-4233-888c-3a71fc965bb4",
      "name": "Get the Raw",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        112,
        320
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.Month }} {{ $json['Day of month'] }}, {{ $json.Year }}",
              "lookupColumn": "Date"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SPREADSHEET_ID",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID/edit",
          "cachedResultName": "Product Schedule Spreadsheet"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8121809f-b1ec-49e7-bca3-5e1ee95b1b3b",
      "name": "influencer_image_Convert_to_Text",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        1200,
        320
      ],
      "parameters": {
        "options": {},
        "operation": "binaryToPropery"
      },
      "typeVersion": 1
    },
    {
      "id": "b4e31c1d-29d1-4214-80cb-bc9133b72a7b",
      "name": "Image Generation",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        224,
        736
      ],
      "parameters": {
        "url": "https://openrouter.ai/api/v1/chat/completions",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"model\": \"google/gemini-2.5-flash-image-preview\",\n  \"prompt\": \"{{ $json.content }}\",\n  \"image_inputs\": [\n    {\n      \"image\": \"{{ $json.data }}\",\n      \"mime_type\": \"image/png\"\n    },\n    {\n      \"image\": \"{{ $('Convert Binary to Text').item.json.data }}\",\n      \"mime_type\": \"image/jpeg\"\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "cce44841-176e-48f5-9196-3abf2f284cca",
      "name": "base64 cleanup",
      "type": "n8n-nodes-base.code",
      "position": [
        464,
        736
      ],
      "parameters": {
        "jsCode": "// Loop over all items\nreturn items.map(item => {\n  // Make a copy of the item to avoid mutation\n  let newItem = { ...item };\n\n  // Check if the path exists\n  if (newItem.json.choices && newItem.json.choices[0].images && newItem.json.choices[0].images[0].image_url) {\n    let imageData = newItem.json.choices[0].images[0].image_url.url;\n\n    // Remove the prefix\n    if (imageData.startsWith(\"data:image/png;base64,\")) {\n      imageData = imageData.replace(\"data:image/png;base64,\", \"\");\n    }\n\n    // Update the value\n    newItem.json.choices[0].images[0].image_url.url = imageData;\n  }\n\n  return newItem;\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "c91456d5-1e1f-4c70-90bf-94da0f9bfb46",
      "name": "Convert to File",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        672,
        736
      ],
      "parameters": {
        "options": {},
        "operation": "toBinary",
        "sourceProperty": "choices[0].images[0].image_url.url"
      },
      "typeVersion": 1.1
    },
    {
      "id": "cbc50b85-4b16-4aca-b26b-f5f7ba764c2b",
      "name": "Update Spreadsheet with Results",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1264,
        736
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('Get the Raw').item.json.Date }}",
            "Publish": "Publish",
            "Ad Image Ready To Post": "={{ $json.webContentLink }}"
          },
          "schema": [
            {
              "id": "Product url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Product url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Model url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Model url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Ad Image Ready To Post",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Ad Image Ready To Post",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Publish",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Publish",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Date"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SPREADSHEET_ID",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID/edit",
          "cachedResultName": "Product Schedule Spreadsheet"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "52545f4b-1a5c-4e4a-b9ed-f5a1788f536f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        96
      ],
      "parameters": {
        "width": 1696,
        "height": 448,
        "content": "## Step 1: Trigger & Data Preparation\n- **Schedule Trigger** → Runs daily at a defined interval.  \n- **Google Sheets (Get Row)** → Fetch product + model image URLs for today's date.  \n- **Google Drive (Download Product Image)** → Get product image.  \n- **Google Drive (Download Influencer Image)** → Get influencer/model image.  \n- **Convert Binary → Base64 (Product)** → Prepare product image for AI input.  \n- **Convert Binary → Base64 (Influencer)** → Prepare influencer image for AI input.  \n\n***"
      },
      "typeVersion": 1
    },
    {
      "id": "b80eff1b-cdca-4679-bad1-646f0c3033eb",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        560
      ],
      "parameters": {
        "color": 5,
        "width": 1008,
        "height": 368,
        "content": "## Step 2: AI Analysis & Image Generation\n- **OpenAI (Analyze Image)** → Generate an ad-focused description (lighting, styling, background, mood).  \n- **HTTP Request (OpenRouter Gemini)** → Combine product + influencer images into a new ad-ready visual.  \n- **Code Node (Cleanup)** → Strip `data:image/...;base64,` prefix from the AI output.  \n- **Convert Base64 → File** → Turn AI output into a usable image file. "
      },
      "typeVersion": 1
    },
    {
      "id": "1a744b30-6ca9-45fb-b1b6-a5bb612302ba",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        560
      ],
      "parameters": {
        "color": 3,
        "width": 672,
        "height": 368,
        "content": "## Step 3: Save & Update\n- **Google Drive (Upload Image)** → Save the generated ad image in the correct folder.  \n- **Google Sheets (Append / Update Row)** → Store the Google Drive link + mark status as \"Publish\".  \n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Get the Raw": {
      "main": [
        [
          {
            "node": "Download Product Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "upload_image": {
      "main": [
        [
          {
            "node": "Update Spreadsheet with Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze image": {
      "main": [
        [
          {
            "node": "Image Generation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "base64 cleanup": {
      "main": [
        [
          {
            "node": "Convert to File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to File": {
      "main": [
        [
          {
            "node": "upload_image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Image Generation": {
      "main": [
        [
          {
            "node": "base64 cleanup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get the Raw",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert Binary to Text": {
      "main": [
        [
          {
            "node": "download_influencer_image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Product Image": {
      "main": [
        [
          {
            "node": "Convert Binary to Text",
            "type": "main",
            "index": 0
          },
          {
            "node": "Analyze image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "download_influencer_image": {
      "main": [
        [
          {
            "node": "influencer_image_Convert_to_Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "influencer_image_Convert_to_Text": {
      "main": [
        [
          {
            "node": "Image Generation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}