{
  "id": "KKMpzsD5MVzOnaPY",
  "name": "Seedance AI Lighting Look Dev with Multi-Variation Rendering & Review Workflow",
  "tags": [],
  "nodes": [
    {
      "id": "375eb5ba-b93e-4fcb-9e79-61a22345ab42",
      "name": "n8n Form: Lighting Brief",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        864,
        624
      ],
      "parameters": {
        "options": {},
        "formTitle": "Lighting & Look Dev Reference Request",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Shot Code",
              "placeholder": "SQ010_SH020",
              "requiredField": true
            },
            {
              "fieldLabel": "Sequence Code",
              "placeholder": "SQ010"
            },
            {
              "fieldLabel": "Project ID",
              "placeholder": "PROJ-001"
            },
            {
              "fieldLabel": "Plate Image URL",
              "placeholder": "https://your-server.com/onset_still.jpg",
              "requiredField": true
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "Lighting Mood Description",
              "placeholder": "Overcast soft light with cool blue shadows, golden hour warmth on edges, cinematic film look",
              "requiredField": true
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "Scene Type",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Exterior Day"
                  },
                  {
                    "option": "Exterior Night"
                  },
                  {
                    "option": "Interior Day"
                  },
                  {
                    "option": "Interior Night"
                  },
                  {
                    "option": "Golden Hour"
                  },
                  {
                    "option": "Overcast"
                  },
                  {
                    "option": "Storm / Dramatic"
                  }
                ]
              },
              "requiredField": true
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "CG Subject Type",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Character / Human"
                  },
                  {
                    "option": "Vehicle"
                  },
                  {
                    "option": "Creature"
                  },
                  {
                    "option": "Hard Surface Object"
                  },
                  {
                    "option": "Environment / Set Extension"
                  }
                ]
              },
              "requiredField": true
            },
            {
              "fieldType": "email",
              "fieldLabel": "Supervisor Email",
              "placeholder": "user@example.com"
            }
          ]
        },
        "formDescription": "Submit a lighting brief to generate AI look development references for your sequence."
      },
      "typeVersion": 2.2
    },
    {
      "id": "59bf9a33-20d9-43d0-91f6-e73204fd07a3",
      "name": "Validate & Extract Lighting Brief",
      "type": "n8n-nodes-base.code",
      "position": [
        1104,
        624
      ],
      "parameters": {
        "jsCode": "const form = $input.first().json;\n\nconst sceneTypeMap = {\n  'Exterior Day':      'ext_day',\n  'Exterior Night':    'ext_night',\n  'Interior Day':      'int_day',\n  'Interior Night':    'int_night',\n  'Golden Hour':       'golden_hour',\n  'Overcast':          'overcast',\n  'Storm / Dramatic':  'storm'\n};\n\nconst cgSubjectMap = {\n  'Character / Human':          'character',\n  'Vehicle':                    'vehicle',\n  'Creature':                   'creature',\n  'Hard Surface Object':        'hard_surface',\n  'Environment / Set Extension':'environment'\n};\n\nconst data = {\n  shotCode:          (form['Shot Code'] || '').trim(),\n  sequenceCode:      (form['Sequence Code'] || form['Shot Code']?.split('_')[0] || 'SEQ-000').trim(),\n  projectId:         (form['Project ID'] || 'PROJ-001').trim(),\n  plateImageUrl:     (form['Plate Image URL'] || '').trim(),\n  moodDescription:   (form['Lighting Mood Description'] || '').trim(),\n  sceneType:         sceneTypeMap[form['Scene Type']] || 'ext_day',\n  cgSubjectType:     cgSubjectMap[form['CG Subject Type']] || 'character',\n  supervisorEmail:   (form['Supervisor Email'] || '').trim(),\n  requestTimestamp:  new Date().toISOString()\n};\n\nif (!data.shotCode) throw new Error('Shot Code is required');\nif (!data.plateImageUrl) throw new Error('Plate Image URL is required');\nif (!data.moodDescription) throw new Error('Lighting Mood Description is required');\n\nreturn [{ json: data }];"
      },
      "typeVersion": 2
    },
    {
      "id": "c2905198-c1be-4330-80bf-e90859468603",
      "name": "Fan-Out: 5 Lighting Variations",
      "type": "n8n-nodes-base.code",
      "position": [
        1344,
        624
      ],
      "parameters": {
        "jsCode": "const d = $input.first().json;\nconst mood = d.moodDescription;\nconst scene = d.sceneType;\nconst subject = d.cgSubjectType;\n\nconst variations = [\n  {\n    variantId:   'LLD-KEY',\n    lightType:   'key_light',\n    label:       'Key Light Setup',\n    lightIcon:   '\u2600\ufe0f',\n    safePrompt:  JSON.stringify(`${mood}. Strong single key light source from upper left at 45 degrees, deep shadows on opposite side, rim light separating subject from background. CG ${subject} on neutral grey turntable, ${scene} lighting conditions. Photorealistic look development reference, cinema quality --duration 5 --camerafixed true`).slice(1,-1)\n  },\n  {\n    variantId:   'LLD-SOFT',\n    lightType:   'soft_diffuse',\n    label:       'Soft Diffuse Setup',\n    lightIcon:   '\ud83c\udf25\ufe0f',\n    safePrompt:  JSON.stringify(`${mood}. Overcast sky dome lighting, no hard shadows, soft wrap light from all directions, subtle ambient occlusion in crevices. CG ${subject} on neutral grey turntable, ${scene} lighting conditions. Photorealistic look development reference, cinema quality --duration 5 --camerafixed true`).slice(1,-1)\n  },\n  {\n    variantId:   'LLD-DRAM',\n    lightType:   'dramatic_contrast',\n    label:       'High Contrast / Dramatic',\n    lightIcon:   '\ud83c\udfad',\n    safePrompt:  JSON.stringify(`${mood}. High contrast dramatic lighting, deep blacks, strong highlights, noir-inspired single source from side. CG ${subject} on neutral grey turntable, ${scene} lighting conditions. Photorealistic look development reference, cinema quality --duration 5 --camerafixed true`).slice(1,-1)\n  },\n  {\n    variantId:   'LLD-PLATE',\n    lightType:   'plate_match',\n    label:       'Plate Match Reference',\n    lightIcon:   '\ud83c\udfac',\n    safePrompt:  JSON.stringify(`${mood}. Lighting precisely matched to the reference plate photograph provided \u2014 same colour temperature, same shadow direction, same light intensity and falloff. CG ${subject} composited into scene, matching all plate lighting exactly. Photorealistic VFX look development reference --duration 5 --camerafixed true`).slice(1,-1)\n  },\n  {\n    variantId:   'LLD-COMP',\n    lightType:   'comp_grade',\n    label:       'Comp Grade Preview',\n    lightIcon:   '\ud83c\udfa8',\n    safePrompt:  JSON.stringify(`${mood}. Final comp-graded look with colour correction, film grain, lens vignette, chromatic aberration, colour grade matching ${scene} aesthetic. CG ${subject} fully integrated into environment. Cinematic final frame look development reference --duration 5 --camerafixed true`).slice(1,-1)\n  }\n];\n\nreturn variations.map(v => ({ json: { ...v, ...d } }));"
      },
      "typeVersion": 2
    },
    {
      "id": "c064167b-db01-4d96-a078-c064a893bfee",
      "name": "Build Lighting Request Body",
      "type": "n8n-nodes-base.code",
      "position": [
        1584,
        624
      ],
      "parameters": {
        "jsCode": "const input = $input.first().json;\n\nconst body = {\n  model: 'seedance-1-5-pro-251215',\n  content: [\n    { type: 'text', text: input.safePrompt },\n    { type: 'image_url', image_url: { url: input.plateImageUrl } }\n  ],\n  generate_audio: false,\n  ratio: '16:9',\n  duration: 5,\n  watermark: false\n};\n\nreturn [{\n  json: {\n    ...input,\n    requestBody: JSON.stringify(body),\n    mode: 'image_to_video'\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "454e12e0-aae0-4d4c-b718-47fdd3a063cd",
      "name": "Seedance: Generate Lighting Ref",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1824,
        624
      ],
      "parameters": {
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.parse($json.requestBody) }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "a1ca548b-c755-4dd8-b886-2edaec700e82",
      "name": "Merge Lighting Job ID + Metadata",
      "type": "n8n-nodes-base.code",
      "position": [
        2064,
        624
      ],
      "parameters": {
        "jsCode": "const httpResult = $input.first().json;\nconst variantData = $('Build Lighting Request Body').first().json;\nreturn [{ json: { ...variantData, id: httpResult.id, jobStatus: httpResult.status } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "a427d110-7600-4374-9869-2c36464f5556",
      "name": "Poll: Check Lighting Job Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2304,
        624
      ],
      "parameters": {
        "url": "=",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "1f4cc5a1-630c-498a-803f-73f5763fe3fe",
      "name": "Wait 20s",
      "type": "n8n-nodes-base.wait",
      "position": [
        2784,
        848
      ],
      "parameters": {
        "amount": 20
      },
      "typeVersion": 1.1
    },
    {
      "id": "79c42c07-2566-466d-afd1-dcb6506e11f9",
      "name": "Lighting Render Complete?",
      "type": "n8n-nodes-base.if",
      "position": [
        2544,
        656
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "lld-cond-001",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "succeeded"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "c161fcde-2468-4986-841a-fc55ace2f065",
      "name": "Build Lighting Asset Metadata",
      "type": "n8n-nodes-base.code",
      "position": [
        2864,
        640
      ],
      "parameters": {
        "jsCode": "const input = $input.first().json;\nconst variantData = $('Merge Lighting Job ID + Metadata').first().json;\n\nlet videoUrl = null;\nif (input.content && input.content.video_url) {\n  videoUrl = input.content.video_url;\n}\nif (!videoUrl) {\n  videoUrl = input.output_url || input.video_url || `URL not found. Job ID: ${input.id}`;\n}\n\nreturn [{\n  json: {\n    variantId:        variantData.variantId,\n    lightType:        variantData.lightType,\n    lightIcon:        variantData.lightIcon,\n    label:            variantData.label,\n    shotCode:         variantData.shotCode,\n    sequenceCode:     variantData.sequenceCode,\n    projectId:        variantData.projectId,\n    videoUrl:         videoUrl,\n    plateImageUrl:    variantData.plateImageUrl,\n    moodDescription:  variantData.moodDescription,\n    sceneType:        variantData.sceneType,\n    cgSubjectType:    variantData.cgSubjectType,\n    supervisorEmail:  variantData.supervisorEmail,\n    jobId:            input.id,\n    resolution:       input.resolution,\n    duration:         input.duration,\n    generatedAt:      new Date().toISOString(),\n    tags: {\n      asset_type:    'lighting_lookdev',\n      light_type:    variantData.lightType,\n      scene_type:    variantData.sceneType,\n      cg_subject:    variantData.cgSubjectType,\n      shot_code:     variantData.shotCode,\n      ai_generated:  true,\n      review_status: 'pending_review',\n      workflow:      'lighting_lookdev_builder'\n    }\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "06443249-3d4d-47a2-9d6c-4e0a66cbd470",
      "name": "Download Lighting Ref Video",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3104,
        640
      ],
      "parameters": {
        "url": "={{ $json.videoUrl }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "2a92844c-9e37-475e-92e0-df2cb1b1bd9a",
      "name": "Google Drive: Upload Lighting Ref",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        3376,
        640
      ],
      "parameters": {
        "name": "={{ $json.shotCode }}_lighting_{{ $json.lightType }}_{{ $json.variantId }}.mp4",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "1fL57MP1QWsF0O_n7WuqfzJ0hO6I9Csrh",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1fL57MP1QWsF0O_n7WuqfzJ0hO6I9Csrh",
          "cachedResultName": "Simulation FX Concept Generator "
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "c8b347e6-ee4e-41b8-a06e-307358816665",
      "name": "Aggregate + Build Lookbook",
      "type": "n8n-nodes-base.code",
      "position": [
        3632,
        640
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst metaItems = $('Build Lighting Asset Metadata').all();\n\n// Build lookbook HTML content for Confluence\nconst lookbookRows = metaItems.map(item => {\n  const d = item.json;\n  return `<tr>\n    <td><strong>${d.lightIcon} ${d.label}</strong></td>\n    <td>${d.lightType}</td>\n    <td><a href=\"${d.videoUrl}\">Watch Reference</a></td>\n    <td>${d.resolution || '720p'}</td>\n    <td>${d.generatedAt}</td>\n  </tr>`;\n}).join('\\n');\n\nconst lookbookHtml = `\n<h1>\ud83c\udfac Lighting Look Development \u2013 ${metaItems[0].json.shotCode}</h1>\n<p><strong>Sequence:</strong> ${metaItems[0].json.sequenceCode} | <strong>Project:</strong> ${metaItems[0].json.projectId}</p>\n<p><strong>Scene Type:</strong> ${metaItems[0].json.sceneType} | <strong>CG Subject:</strong> ${metaItems[0].json.cgSubjectType}</p>\n<p><strong>Lighting Mood:</strong> ${metaItems[0].json.moodDescription}</p>\n<p><strong>Reference Plate:</strong> <a href=\"${metaItems[0].json.plateImageUrl}\">View Plate</a></p>\n<h2>Generated Lighting Variations</h2>\n<table>\n  <thead>\n    <tr><th>Variation</th><th>Light Type</th><th>Video</th><th>Resolution</th><th>Generated</th></tr>\n  </thead>\n  <tbody>\n    ${lookbookRows}\n  </tbody>\n</table>\n<h2>Usage Notes</h2>\n<p>These AI-generated references are for look development guidance only. Use as visual targets when setting up CG lighting rigs. Match colour temperature, shadow direction, and light intensity to the selected option.</p>\n<p><em>Generated by AI Lighting Look Dev Builder \u2014 ${new Date().toISOString()}</em></p>\n`;\n\nconst slackLines = metaItems.map(item => {\n  const d = item.json;\n  return `${d.lightIcon} *${d.label}* (${d.variantId})\\n> \ud83c\udfac <${d.videoUrl}|Watch Reference>\\n> \ud83d\udca1 Type: ${d.lightType}\\n> \ud83d\udcc5 ${d.generatedAt}`;\n}).join('\\n\\n');\n\nconst first = metaItems[0].json;\n\nreturn [{\n  json: {\n    shotCode:        first.shotCode,\n    sequenceCode:    first.sequenceCode,\n    projectId:       first.projectId,\n    moodDescription: first.moodDescription,\n    sceneType:       first.sceneType,\n    cgSubjectType:   first.cgSubjectType,\n    supervisorEmail: first.supervisorEmail,\n    plateImageUrl:   first.plateImageUrl,\n    lookbookHtml:    lookbookHtml,\n    slackLines:      slackLines,\n    totalVariations: metaItems.length,\n    generatedAt:     new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "aa2478cb-3436-443a-9b42-da96ab41d89b",
      "name": "Slack: Notify Lighting Team",
      "type": "n8n-nodes-base.slack",
      "position": [
        4256,
        640
      ],
      "parameters": {
        "text": "={{ $json.message.content }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0ANFAL4WJ2",
          "cachedResultName": "social"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.3
    },
    {
      "id": "3eab15cf-4cbc-44cc-bb13-1f7a42f953fd",
      "name": "On Workflow Error",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        864,
        1120
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "8ef92e9d-57b9-400b-8b36-67ffa6853f74",
      "name": "Slack: Error Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        1104,
        1120
      ],
      "parameters": {
        "text": "=\u274c *Lighting Look Dev Generator Failed*\n\nError: {{ $json.message }}\nTime: {{ new Date().toISOString() }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0ANFAL4WJ2",
          "cachedResultName": "social"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.3
    },
    {
      "id": "f3cab4af-4ffc-41f4-81ca-762adfe6adb2",
      "name": "AI - Generate the slack message",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        3856,
        640
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {
          "maxTokens": 300,
          "temperature": 0.7
        },
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a VFX production assistant. Your job is to write a clear, professional Slack message for a lighting team when their AI look development references are ready. \n\nRules:\n- Write in a concise, professional tone\n- Use Slack markdown formatting (bold with *asterisks*, code with backticks)\n- Include all the key details: shot code, mood, scene type, variations ready\n- Keep it scannable \u2014 use line breaks and emoji for visual hierarchy\n- End with a clear call to action for the team\n- Never include raw HTML, JSON, or technical URLs in the message\n- Output ONLY the Slack message text, nothing else"
            },
            {
              "content": "=Generate a Slack notification message for the lighting team using this data:\n\nShot Code: {{ $json.shotCode }}\nSequence: {{ $json.sequenceCode }}\nProject: {{ $json.projectId }}\nScene Type: {{ $json.sceneType }}\nCG Subject: {{ $json.cgSubjectType }}\nLighting Mood: {{ $json.moodDescription }}\nTotal Variations Generated: {{ $json.totalVariations }}\nGenerated At: {{ $json.generatedAt }}\nSupervisor Email: {{ $json.supervisorEmail }}\n\nVariation Details:\n{{ $json.slackLines }}\n\nWrite a Slack message that tells the lighting team their look dev references are ready, summarises the key lighting details, lists the variations with their watch links, and asks them to review and pick their preferred direction before starting the CG lighting rig."
            }
          ]
        }
      },
      "typeVersion": 1.7
    },
    {
      "id": "b1464e45-ac82-4f0b-8347-b0a1f2ba6ff4",
      "name": "Record the log in Notion",
      "type": "n8n-nodes-base.notion",
      "position": [
        3904,
        384
      ],
      "parameters": {
        "title": "Look Dev Reference DB",
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "330802b9-1fa0-8027-8e92-f1c712bad8fd",
          "cachedResultUrl": "https://www.notion.so/330802b91fa080278e92f1c712bad8fd",
          "cachedResultName": "Lighting & Look Dev Reference DB"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "lookbookHtml|rich_text",
              "textContent": "={{ $json.lookbookHtml }}"
            },
            {
              "key": "shotCode|title",
              "title": "={{ $json.shotCode }}"
            }
          ]
        }
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2a3df8cd-7a37-4842-a037-7456c5b7d4f3",
      "name": "Sticky Note: Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -32,
        -224
      ],
      "parameters": {
        "width": 626,
        "height": 478,
        "content": "## \ud83c\udfac AI Lighting Look Dev Builder\n\n### How it works\nA lighting TD or VFX supervisor submits a brief via a web form \u2014 shot code, scene type, CG subject, mood description, and a reference plate image URL. The workflow fans out into **five parallel AI video generation jobs**, each targeting a distinct lighting setup: Key Light, Soft Diffuse, Dramatic, Plate Match, and Comp Grade. Each render is polled until complete, downloaded, and uploaded to Google Drive with structured naming. Once all five are ready, an HTML lookbook lands in Notion and GPT drafts a contextual Slack notification for the lighting team.\n\n### Setup steps\n1. Add your **Seedance API key** to the two HTTP Request nodes (replace `YOUR_SEEDANCE_API_KEY`)\n2. Connect **Google Drive OAuth2** credentials and update the target folder ID\n3. Connect **Notion API** credentials and point to your Look Dev database\n4. Connect **Slack OAuth2** and set your lighting team channel ID in both Slack nodes\n5. Connect **OpenAI API** credentials for Slack message generation\n6. Submit a test brief via the form trigger to verify the full render-to-delivery pipeline"
      },
      "typeVersion": 1
    },
    {
      "id": "ffdf2baa-d5fc-4ac6-8590-6647f5ac1645",
      "name": "Sticky Note: Form Intake",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        336
      ],
      "parameters": {
        "color": 7,
        "width": 490,
        "height": 490,
        "content": "## \ud83d\udccb Form Intake & Validation\nCaptures the lighting brief from a web form and validates all required fields \u2014 shot code, plate URL, mood description, and scene type \u2014 before anything reaches the AI pipeline. Bad data is rejected here, not downstream."
      },
      "typeVersion": 1
    },
    {
      "id": "d99a0f25-c3d4-4b30-82cf-d267033a5435",
      "name": "Sticky Note: Prompt Fan-Out",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        336
      ],
      "parameters": {
        "color": 7,
        "width": 458,
        "height": 490,
        "content": "## \ud83d\udd00 Prompt Fan-Out\nExpands the single brief into five distinct lighting prompts \u2014 Key Light, Soft Diffuse, Dramatic, Plate Match, and Comp Grade \u2014 and wraps each as a multimodal Seedance request with the plate image attached."
      },
      "typeVersion": 1
    },
    {
      "id": "a88a4761-33d0-4c92-bc2c-fb758f9c0bc0",
      "name": "Sticky Note: AI Generation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1744,
        352
      ],
      "parameters": {
        "color": 7,
        "width": 490,
        "height": 458,
        "content": "## \ud83c\udfa5 AI Video Generation\nSubmits each lighting prompt to the Seedance image-to-video API. Job IDs returned by the API are merged with original metadata so the polling loop tracks the correct render per variation."
      },
      "typeVersion": 1
    },
    {
      "id": "ea1a3887-ce44-449b-b886-4454f202cc8d",
      "name": "Sticky Note: Polling Loop",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2256,
        368
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 666,
        "content": "## \ud83d\udd04 Render Polling Loop\nChecks each render job's status every 20 seconds. The workflow loops until the API confirms success \u2014 only then does the variation proceed to asset extraction and storage."
      },
      "typeVersion": 1
    },
    {
      "id": "fa19fa7b-41d1-4cc9-b904-050768f4fd25",
      "name": "Sticky Note: Asset Storage",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3008,
        368
      ],
      "parameters": {
        "color": 7,
        "width": 776,
        "height": 666,
        "content": "## \ud83d\udcbe Asset Storage\nDownloads each rendered video and uploads it to Google Drive with a structured filename (`SHOT_lighting_TYPE_VARIANT.mp4`). Asset metadata is tagged with scene type, CG subject, shot code, and review status for pipeline tracking."
      },
      "typeVersion": 1
    },
    {
      "id": "5302e920-38f5-4bd3-8607-8426db742c6a",
      "name": "Sticky Note: Lookbook",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3808,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 598,
        "height": 762,
        "content": "## \ud83d\udce3 Lookbook & Notifications\nAggregates all five variations into an HTML lookbook page saved to Notion. GPT-4o-mini writes a team-facing Slack message with variation links, lighting mood context, and a clear review call-to-action."
      },
      "typeVersion": 1
    },
    {
      "id": "b6961e01-8adf-4bc8-82d9-f3d60adb2687",
      "name": "Sticky Note: Security",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4512,
        736
      ],
      "parameters": {
        "color": 3,
        "width": 308,
        "height": 250,
        "content": "## \ud83d\udd10 Credentials & Security\nUse OAuth2 for Slack, Google Drive, and Notion. Store your Seedance and OpenAI keys as n8n credentials \u2014 never hardcode tokens in HTTP Request headers. Replace all `YOUR_*` placeholders before publishing or sharing this template."
      },
      "typeVersion": 1
    },
    {
      "id": "ccee1a2f-fc70-4d91-be17-145f46b99872",
      "name": "Section: Error Handler",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        976
      ],
      "parameters": {
        "color": 7,
        "width": 492,
        "height": 328,
        "content": "## \u26a0\ufe0f Error Handler\nCatches any failure across the entire workflow and immediately sends a Slack alert to the ops channel. Wire this to every sub-workflow or critical node to ensure no silent failures."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b404fb72-de26-4fa0-829a-d2df931e086c",
  "connections": {
    "Wait 20s": {
      "main": [
        [
          {
            "node": "Poll: Check Lighting Job Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On Workflow Error": {
      "main": [
        [
          {
            "node": "Slack: Error Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "n8n Form: Lighting Brief": {
      "main": [
        [
          {
            "node": "Validate & Extract Lighting Brief",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lighting Render Complete?": {
      "main": [
        [
          {
            "node": "Build Lighting Asset Metadata",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 20s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate + Build Lookbook": {
      "main": [
        [
          {
            "node": "Record the log in Notion",
            "type": "main",
            "index": 0
          },
          {
            "node": "AI - Generate the slack message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Lighting Request Body": {
      "main": [
        [
          {
            "node": "Seedance: Generate Lighting Ref",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Lighting Ref Video": {
      "main": [
        [
          {
            "node": "Google Drive: Upload Lighting Ref",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Lighting Asset Metadata": {
      "main": [
        [
          {
            "node": "Download Lighting Ref Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fan-Out: 5 Lighting Variations": {
      "main": [
        [
          {
            "node": "Build Lighting Request Body",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI - Generate the slack message": {
      "main": [
        [
          {
            "node": "Slack: Notify Lighting Team",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll: Check Lighting Job Status": {
      "main": [
        [
          {
            "node": "Lighting Render Complete?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Seedance: Generate Lighting Ref": {
      "main": [
        [
          {
            "node": "Merge Lighting Job ID + Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Lighting Job ID + Metadata": {
      "main": [
        [
          {
            "node": "Poll: Check Lighting Job Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive: Upload Lighting Ref": {
      "main": [
        [
          {
            "node": "Aggregate + Build Lookbook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate & Extract Lighting Brief": {
      "main": [
        [
          {
            "node": "Fan-Out: 5 Lighting Variations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}