AutomationFlowsData & Sheets › AI Ppt Optimizer with Gpt-image-2

AI Ppt Optimizer with Gpt-image-2

ByLeo Wood @leo-wood on n8n.io

What it does: Initializes Google Sheets tabs: jobs, slides, events Creates a Google Drive root folder for optimizer jobs Reads slide images from a Google Drive input folder Sends each image to gpt-image-2. Converts base64 image results to binary Uploads edited images to Google…

Webhook trigger★★★★☆ complexity29 nodesGoogle DriveGoogle SheetsHTTP Request
Data & Sheets Trigger: Webhook Nodes: 29 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #15834 — we link there as the canonical source.

This workflow follows the Google Drive → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "e0caaa9d-8656-4a51-bf99-9e764af2702f",
      "name": "README - Run Workflow",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3664,
        640
      ],
      "parameters": {
        "color": 5,
        "width": 744,
        "height": 672,
        "content": "# Workflow 02 - Run Image Optimization\n\nThis workflow reads source slide images from a Google Drive folder.\n\nInput folder requirements:\n- Put one image per PPT slide into the folder\n- Supported MIME types: PNG, JPEG, WebP\n- File order is based on Google Drive API order; use names like `slide_001.png`, `slide_002.png`\n\nThe workflow:\n1. Creates a job folder in Google Drive\n2. Creates an `output/` folder\n3. Reads images from `inputFolderId`\n4. Calls Wisgate AI image edits\n5. Saves generated images to Drive\n6. Writes job and slide status to Google Sheets\n7. Returns the output folder link"
      },
      "typeVersion": 1
    },
    {
      "id": "01ae317d-5bc4-4ffb-b9fd-1c45cd409404",
      "name": "README - Run Webhook Body",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3664,
        1360
      ],
      "parameters": {
        "color": 4,
        "width": 736,
        "height": 494,
        "content": "# POST Body Example\n\n```json\n{\n  \"spreadsheetId\": \"YOUR_GOOGLE_SHEET_ID\",\n  \"driveRootFolderId\": \"DRIVE_ROOT_FOLDER_ID_FROM_INIT\",\n  \"inputFolderId\": \"FOLDER_WITH_SLIDE_IMAGES\",\n  \"jobName\": \"demo-job\",\n  \"timeoutMs\": 120000,\n  \"waitSeconds\": 2,\n  \"basePrompt\": \"Improve this PPT slide. Make it clean, professional, readable, and presentation-ready.\"\n}\n```\n\nWebhook path:\n`ppt-opt-run-drive-folder`\n\nThe response includes:\n- `jobId`\n- `status`\n- `outputFolderLink`"
      },
      "typeVersion": 1
    },
    {
      "id": "6a81ed66-7552-40a1-aca8-7127674f34b6",
      "name": "README - Wisgate AI Settings",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        6096,
        672
      ],
      "parameters": {
        "color": 6,
        "width": 528,
        "height": 680,
        "content": "# Image AI\n\nThis workflow uses:\n- Base URL: `https://api.wisgate.ai/v1`\n- Endpoint: `/images/edits`\n- Model: `gpt-image-2`\n\nSet one of these environment variables in n8n:\n- `WISGATE_API_KEY` recommended\n- `OPENAI_API_KEY` fallback\n\nThe HTTP Request node sends multipart/form-data:\n```json\n{\n  \"model\": \"gpt-image-2\",\n  \"response_format\": \"b64_json\",\n  \"image\": \"originalImage binary field\"\n}\n```\n\nThe source slide image is downloaded from Google Drive, sent as multipart `image`, and the returned base64 image is converted to n8n binary and uploaded to Google Drive."
      },
      "typeVersion": 1
    },
    {
      "id": "24c55a97-ae64-4fdf-a30e-f4f0b3914182",
      "name": "README - Status Logic",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4448,
        1360
      ],
      "parameters": {
        "color": 3,
        "width": 560,
        "height": 496,
        "content": "# Status Tracking\n\nGoogle Sheets is the status database.\n\n`jobs` tab:\n- One row per job\n- Stores counts and output folder link\n\n`slides` tab:\n- One row per slide image\n- Tracks status: `pending`, `processing`, `success`, `failed`, `timeout`\n\n`events` tab:\n- Append-only log\n- Records success and failure events\n\nFailure handling:\n- HTTP errors do not stop the whole workflow\n- Failed slides can be retried with Workflow 03"
      },
      "typeVersion": 1
    },
    {
      "id": "6cd395c4-9e4c-46bf-befc-1fae67fe55c8",
      "name": "Webhook - Run",
      "type": "n8n-nodes-base.webhook",
      "position": [
        3728,
        1088
      ],
      "parameters": {
        "path": "ppt-opt-run-drive-folder",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2
    },
    {
      "id": "1095b039-0156-409c-af7b-27529912e843",
      "name": "Code - Init Run",
      "type": "n8n-nodes-base.code",
      "position": [
        4000,
        1088
      ],
      "parameters": {
        "jsCode": "\nconst src = $json.body || $json || {};\nif (!src.spreadsheetId) throw new Error('Missing spreadsheetId');\nif (!src.driveRootFolderId) throw new Error('Missing driveRootFolderId');\nif (!src.inputFolderId) throw new Error('Missing inputFolderId');\nconst stamp = new Date().toISOString().replace(/[-:.TZ]/g,'').slice(0,14);\nconst rand = Math.random().toString(36).slice(2,8);\nconst jobId = `job_${stamp}_${rand}`;\nreturn [{json:{spreadsheetId:src.spreadsheetId,driveRootFolderId:src.driveRootFolderId,inputFolderId:src.inputFolderId,jobId,jobName:src.jobName || jobId,sourceType:'drive_folder_images',basePrompt:src.basePrompt || 'Create an improved professional presentation slide image inspired by the source slide. Keep the slide core message, improve readability, visual hierarchy, and polish. Return a single high-quality slide-like image.',timeoutMs:Number(src.timeoutMs || 120000),waitSeconds:Number(src.waitSeconds || 2),model:'gpt-image-2',baseUrl:'https://api.wisgate.ai/v1'}}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "631ba042-4fa0-4b95-aa45-075d28d44936",
      "name": "Drive - Create Job Folder",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        4256,
        992
      ],
      "parameters": {
        "name": "={{$json.jobId}}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        },
        "resource": "folder"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "5ba81836-df7c-4cd9-882b-cfcc68d0308f",
      "name": "Drive - Create Output Folder",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        4496,
        992
      ],
      "parameters": {
        "name": "output",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        },
        "resource": "folder"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "1fd3a273-4233-4f87-96ca-e8fd894d9ccd",
      "name": "Sheets - Append Job",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4736,
        992
      ],
      "parameters": {
        "columns": {
          "value": {
            "jobId": "={{$json.jobId}}",
            "model": "gpt-image-2",
            "status": "processing",
            "jobName": "={{$json.jobName}}",
            "createdAt": "={{$now}}",
            "updatedAt": "={{$now}}",
            "sourceType": "drive_folder_images",
            "totalSlides": "0",
            "failedSlides": "0",
            "successSlides": "0",
            "timeoutSlides": "0",
            "outputFolderId": "={{$node['Drive - Create Output Folder'].json.id}}",
            "sourceFolderId": "={{$json.inputFolderId}}",
            "driveJobFolderId": "={{$node['Drive - Create Job Folder'].json.id}}",
            "outputFolderLink": "={{'https://drive.google.com/drive/folders/' + $node['Drive - Create Output Folder'].json.id}}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": "jobs",
        "documentId": "={{$json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "7a617f30-ede3-404c-8966-bc7cb6d4c9e1",
      "name": "HTTP Drive - List Input Images",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4736,
        1184
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/drive/v3/files?q={{encodeURIComponent(\"'\" + $json.inputFolderId + \"' in parents and trashed=false and (mimeType='image/png' or mimeType='image/jpeg' or mimeType='image/webp' or mimeType='image/jpg')\")}}&fields={{encodeURIComponent('files(id,name,mimeType,webViewLink)')}}&pageSize=1000",
        "options": {
          "timeout": 30000
        },
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleDriveOAuth2Api"
      },
      "typeVersion": 4.2
    },
    {
      "id": "e53f17a6-3ffd-4cec-8a23-711cafaea043",
      "name": "Code - Expand Input Files",
      "type": "n8n-nodes-base.code",
      "position": [
        4992,
        1184
      ],
      "parameters": {
        "jsCode": "\nconst base = $node['Code - Init Run'].json;\nconst files = $json.files || [];\nif (!files.length) throw new Error('No image files found in inputFolderId');\nreturn files.map((f, idx) => { const i=idx+1; const p=String(i).padStart(3,'0'); return {json:{...base,slideIndex:i,slideKey:`${base.jobId}_slide_${p}`,originalFileName:f.name,originalDriveFileId:f.id,originalDriveUrl:f.webViewLink || `https://drive.google.com/file/d/${f.id}/view`,jobOutputFolderId:$node['Drive - Create Output Folder'].json.id,outputFileName:`slide_${p}.png`,status:'pending',attempt:0,prompt:`${base.basePrompt}\nSlide index: ${i}. Source file name: ${f.name}.`}}; });\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b4ea90ba-d06d-4b50-b727-6b7d02bc23ad",
      "name": "Sheets - Append Slide Pending",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5248,
        1184
      ],
      "parameters": {
        "columns": {
          "value": {
            "jobId": "={{$json.jobId}}",
            "prompt": "={{$json.prompt}}",
            "status": "pending",
            "attempt": "0",
            "slideKey": "={{$json.slideKey}}",
            "errorType": "",
            "startedAt": "",
            "updatedAt": "={{$now}}",
            "finishedAt": "",
            "slideIndex": "={{$json.slideIndex}}",
            "errorMessage": "",
            "outputDriveUrl": "",
            "outputFileName": "={{$json.outputFileName}}",
            "originalDriveUrl": "={{$json.originalDriveUrl}}",
            "originalFileName": "={{$json.originalFileName}}",
            "jobOutputFolderId": "={{$json.jobOutputFolderId}}",
            "outputDriveFileId": "",
            "originalDriveFileId": "={{$json.originalDriveFileId}}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": "slides",
        "documentId": "={{$json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "42efa446-45bf-4cb8-b2b0-6e47a45d4313",
      "name": "Sheets - Update Job Total",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5488,
        1184
      ],
      "parameters": {
        "operation": "upsert",
        "documentId": "={{$json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "da8440d6-8ce0-4287-9f09-f8e6a9bd463e",
      "name": "Loop Slides",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        5728,
        1184
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "3dd498f7-6011-4a5e-9aea-bc26a9ca120f",
      "name": "Sheets - Mark Processing",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5968,
        1184
      ],
      "parameters": {
        "operation": "upsert",
        "documentId": "={{$json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "ec29b77c-a1c8-452a-85df-47cf145ff98e",
      "name": "Code - Parse Edit Response",
      "type": "n8n-nodes-base.code",
      "position": [
        6480,
        1184
      ],
      "parameters": {
        "jsCode": "\nconst source = $node['Loop Slides'].json;\nconst resp = $json;\nconst b64 = resp.data?.[0]?.b64_json;\nif (b64) { return [{json:{...source,status:'success',attempt:Number(source.attempt||0)+1,errorType:'',errorMessage:'',finishedAt:new Date().toISOString()},binary:{outputImage:{data:b64,mimeType:'image/png',fileName:source.outputFileName}}}]; }\nconst text = JSON.stringify(resp.error || resp.message || resp).slice(0,3000) || 'Unknown error';\nconst lower = text.toLowerCase();\nconst status = lower.includes('timeout') ? 'timeout' : 'failed';\nconst errorType = status === 'timeout' ? 'TIMEOUT_120S' : 'API_ERROR';\nreturn [{json:{...source,status,errorType,errorMessage:text,attempt:Number(source.attempt||0)+1,finishedAt:new Date().toISOString()}}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "f403ee5d-20a4-4a9c-aff4-8621b2c22e4c",
      "name": "IF - Success",
      "type": "n8n-nodes-base.if",
      "position": [
        6688,
        1184
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{$json.status}}",
              "rightValue": "success"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "caa56618-0ff6-444c-a3c1-b8f11f6d8a20",
      "name": "Drive - Upload Output Image",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        6928,
        1088
      ],
      "parameters": {
        "name": "={{$json.outputFileName}}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "814d0fb9-96ee-4e6d-8f2a-ab6c63ad3255",
      "name": "Sheets - Update Slide Success",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        7168,
        1088
      ],
      "parameters": {
        "operation": "upsert",
        "documentId": "={{$json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "9ee8a96b-4c59-43b0-ab2f-e52c03bff726",
      "name": "Sheets - Event Success",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        7408,
        1088
      ],
      "parameters": {
        "columns": {
          "value": {
            "jobId": "={{$json.jobId}}",
            "status": "success",
            "eventId": "={{'evt_' + Date.now() + '_' + Math.random().toString(36).slice(2,8)}}",
            "message": "Output image edited and uploaded to Drive",
            "slideKey": "={{$json.slideKey}}",
            "createdAt": "={{$now}}",
            "eventType": "edit_success",
            "slideIndex": "={{$json.slideIndex}}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": "events",
        "documentId": "={{$json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "9b9512b1-d394-4bdc-89ab-2449add7128e",
      "name": "Sheets - Update Slide Failed",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        6928,
        1312
      ],
      "parameters": {
        "operation": "upsert",
        "documentId": "={{$json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "fd82971d-73c1-44c1-8c36-ef932130c6db",
      "name": "Sheets - Event Failed",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        7168,
        1312
      ],
      "parameters": {
        "columns": {
          "value": {
            "jobId": "={{$json.jobId}}",
            "status": "={{$json.status}}",
            "eventId": "={{'evt_' + Date.now() + '_' + Math.random().toString(36).slice(2,8)}}",
            "message": "={{($json.errorType || 'ERROR') + ': ' + ($json.errorMessage || '')}}",
            "slideKey": "={{$json.slideKey}}",
            "createdAt": "={{$now}}",
            "eventType": "edit_failed",
            "slideIndex": "={{$json.slideIndex}}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": "events",
        "documentId": "={{$json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "0470b74f-3a74-4839-9253-cde99994d4e7",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        7648,
        1184
      ],
      "parameters": {
        "amount": "={{$node[\"Code - Init Run\"].json.waitSeconds || 2}}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "01a30a29-2821-4499-b1cb-8eaed58fabe1",
      "name": "Sheets - Read Slides",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5968,
        1504
      ],
      "parameters": {
        "options": {},
        "sheetName": "slides",
        "documentId": "={{$node[\"Code - Init Run\"].json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "4461deba-984c-4665-97a2-834e82fab888",
      "name": "Code - Summarize Job",
      "type": "n8n-nodes-base.code",
      "position": [
        6208,
        1504
      ],
      "parameters": {
        "jsCode": "\nconst job = $node['Code - Init Run'].json;\nconst rows = $input.all().map(i => i.json).filter(r => r.jobId === job.jobId);\nconst totalSlides = rows.length;\nconst successSlides = rows.filter(r => r.status === 'success').length;\nconst failedSlides = rows.filter(r => r.status === 'failed').length;\nconst timeoutSlides = rows.filter(r => r.status === 'timeout').length;\nconst status = (failedSlides || timeoutSlides) ? 'completed_with_errors' : 'done';\nconst outputFolderId = $node['Drive - Create Output Folder'].json.id;\nreturn [{json:{...job,status,totalSlides,successSlides,failedSlides,timeoutSlides,outputFolderId,outputFolderLink:`https://drive.google.com/drive/folders/${outputFolderId}`}}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d3da94f5-2ad6-4385-bcd4-6fe9c5f3e11a",
      "name": "Sheets - Update Job Summary",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        6448,
        1504
      ],
      "parameters": {
        "operation": "upsert",
        "documentId": "={{$json.spreadsheetId}}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "b806297f-068f-44a0-a32d-5b4033f1a60a",
      "name": "Code - Final Response",
      "type": "n8n-nodes-base.code",
      "position": [
        6688,
        1504
      ],
      "parameters": {
        "jsCode": "return [{json:{ok:true,jobId:$json.jobId,status:$json.status,totalSlides:$json.totalSlides,successSlides:$json.successSlides,failedSlides:$json.failedSlides,timeoutSlides:$json.timeoutSlides,outputFolderId:$json.outputFolderId,outputFolderLink:$json.outputFolderLink,message:'Processing complete. Use outputFolderLink to access generated images.'}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "a8dde34f-6505-4d44-b13f-ffc9dd28bb7a",
      "name": "Drive - Download Original Image",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        6144,
        1184
      ],
      "parameters": {
        "fileId": "={{$json.originalDriveFileId}}",
        "options": {
          "binaryPropertyName": "originalImage"
        },
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "806c8c5d-1595-4f5c-a2e9-a216921dd85a",
      "name": "HTTP - AI Edit Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        6320,
        1184
      ],
      "parameters": {
        "url": "={{$json.baseUrl}}/images/edits",
        "method": "POST",
        "options": {
          "timeout": "={{$json.timeoutMs}}"
        },
        "sendBody": true,
        "contentType": "multipart-form-data",
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "model",
              "value": "gpt-image-2"
            },
            {
              "name": "prompt",
              "value": "={{$json.prompt}}"
            },
            {
              "name": "n",
              "value": "1"
            },
            {
              "name": "size",
              "value": "1536x1024"
            },
            {
              "name": "response_format",
              "value": "b64_json"
            },
            {
              "name": "image",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "originalImage"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{$env.WISGATE_API_KEY || $env.OPENAI_API_KEY}}"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    }
  ],
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Loop Slides",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Slides": {
      "main": [
        [
          {
            "node": "Sheets - Read Slides",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sheets - Mark Processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF - Success": {
      "main": [
        [
          {
            "node": "Drive - Upload Output Image",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sheets - Update Slide Failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook - Run": {
      "main": [
        [
          {
            "node": "Code - Init Run",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Init Run": {
      "main": [
        [
          {
            "node": "Drive - Create Job Folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Append Job": {
      "main": [
        [
          {
            "node": "HTTP Drive - List Input Images",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Summarize Job": {
      "main": [
        [
          {
            "node": "Sheets - Update Job Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP - AI Edit Image": {
      "main": [
        [
          {
            "node": "Code - Parse Edit Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Read Slides": {
      "main": [
        [
          {
            "node": "Code - Summarize Job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Event Failed": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Event Success": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Mark Processing": {
      "main": [
        [
          {
            "node": "Drive - Download Original Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Expand Input Files": {
      "main": [
        [
          {
            "node": "Sheets - Append Slide Pending",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Drive - Create Job Folder": {
      "main": [
        [
          {
            "node": "Drive - Create Output Folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Update Job Total": {
      "main": [
        [
          {
            "node": "Loop Slides",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Parse Edit Response": {
      "main": [
        [
          {
            "node": "IF - Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Drive - Upload Output Image": {
      "main": [
        [
          {
            "node": "Sheets - Update Slide Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Update Job Summary": {
      "main": [
        [
          {
            "node": "Code - Final Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Drive - Create Output Folder": {
      "main": [
        [
          {
            "node": "Sheets - Append Job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Update Slide Failed": {
      "main": [
        [
          {
            "node": "Sheets - Event Failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Append Slide Pending": {
      "main": [
        [
          {
            "node": "Sheets - Update Job Total",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sheets - Update Slide Success": {
      "main": [
        [
          {
            "node": "Sheets - Event Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Drive - List Input Images": {
      "main": [
        [
          {
            "node": "Code - Expand Input Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Drive - Download Original Image": {
      "main": [
        [
          {
            "node": "HTTP - AI Edit Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

What it does: Initializes Google Sheets tabs: jobs, slides, events Creates a Google Drive root folder for optimizer jobs Reads slide images from a Google Drive input folder Sends each image to gpt-image-2. Converts base64 image results to binary Uploads edited images to Google…

Source: https://n8n.io/workflows/15834/ — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

Transform your n8n instance management with this advanced automation system featuring artificial intelligence-driven workflow selection. This template provides comprehensive maintenance operations wit

n8n, HTTP Request, Google Sheets +1
Data & Sheets

Convalidaciones Académicas - Estructura Base. Uses googleSheets, emailSend, googleDrive, httpRequest. Webhook trigger; 35 nodes.

Google Sheets, Email Send, Google Drive +2
Data & Sheets

TrackCollect. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, moveBinaryData. Webhook trigger; 31 nodes.

Google Sheets, HTTP Request, @N Octo N/N8N Nodes Json Database +2
Data & Sheets

FlowV4. Uses googleSheets, emailSend, googleDrive, httpRequest. Webhook trigger; 31 nodes.

Google Sheets, Email Send, Google Drive +2
Data & Sheets

This workflow automatically saves files received via LINE Messaging API into Google Drive and logs the file details into a Google Sheet. It checks the file type against allowed types, organizes files

Google Sheets, Google Drive, HTTP Request