{
  "id": "X02B99OKDKpjMcpl",
  "name": "Refresh product photos for slow-selling Shopify products with Dreem.ai",
  "tags": [],
  "nodes": [
    {
      "id": "66ed196f-1179-4a2b-8228-f5747595a7de",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -32,
        -128
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Refresh product photos for slow-selling Shopify products with Dreem.ai\n\n### How it works\n\nThis workflow runs monthly to find Shopify products that have recent sales underperformance, then refreshes their product imagery with Dreem.ai. It batches the slow-moving products, generates fresh on-model photos, waits for render completion, and publishes completed images back to Shopify. Slack notifications report skipped renders and the overall refresh completion.\n\n### Setup steps\n\n- Configure the schedule trigger for the desired monthly run time and timezone.\n- Connect Shopify credentials with permissions to read orders/products and update product media.\n- Configure Dreem.ai credentials and the image-generation settings used by the \"Generate Fresh On-Model\" node.\n- Connect Slack credentials and select the channels or users for skipped-item and completion notifications.\n- Review the custom code in \"Find Slow Movers\" to ensure the slow-selling criteria match the store's sales and inventory strategy.\n\n### Customization\n\nAdjust the slow-mover logic, batch size, render wait duration, Dreem.ai prompt/style settings, and Slack message content to fit the catalog and merchandising workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "65751869-815a-4660-b02b-f1f611da5dbd",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        528,
        240
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 352,
        "content": "## Collect Shopify sales data\n\nStarts the monthly workflow and retrieves the recent order and product data needed to evaluate product performance."
      },
      "typeVersion": 1
    },
    {
      "id": "07d764a8-b262-468f-bb21-4181aa6af412",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1200,
        240
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 336,
        "content": "## Identify and batch slow movers\n\nUses custom logic to find slow-selling products, then feeds them one at a time through the refresh loop."
      },
      "typeVersion": 1
    },
    {
      "id": "ceeaa303-8d4a-4b77-a6e3-793ddd07c755",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1936,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 336,
        "content": "## Generate and verify photos\n\nCreates a fresh on-model image with Dreem.ai, waits for rendering, and checks whether the generated asset is complete before continuing."
      },
      "typeVersion": 1
    },
    {
      "id": "2c6191bb-2cac-4fe5-b977-5c7c02daa9fd",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2576,
        144
      ],
      "parameters": {
        "color": 7,
        "height": 448,
        "content": "## Publish completed images\n\nUpdates Shopify with successfully rendered product imagery, then returns control to the batching loop for the next slow-moving product."
      },
      "typeVersion": 1
    },
    {
      "id": "78cf88c0-c13e-4420-9679-c97876a16ced",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2960,
        432
      ],
      "parameters": {
        "color": 7,
        "height": 432,
        "content": "## Report skipped renders\n\nSends a Slack notification for products whose Dreem.ai render did not complete, then routes back to the loop to continue processing."
      },
      "typeVersion": 1
    },
    {
      "id": "1ea7d839-acdd-4ca5-91bf-a331c4f244f0",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1952,
        -160
      ],
      "parameters": {
        "color": 7,
        "height": 368,
        "content": "## Send completion notice\n\nPosts a Slack message when the slow-mover batch has finished processing all eligible products."
      },
      "typeVersion": 1
    },
    {
      "id": "55bfa2b1-4d9c-47b9-bd0d-fa2d2435ab5d",
      "name": "When Monthly at 9am",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        576,
        416
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 1 * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b92f8bec-21db-43c9-af60-1de2c25aa41d",
      "name": "Fetch Recent Orders from Shopify",
      "type": "n8n-nodes-base.shopify",
      "position": [
        800,
        416
      ],
      "parameters": {
        "limit": 250,
        "options": {
          "status": "any"
        },
        "operation": "getAll",
        "authentication": "accessToken"
      },
      "typeVersion": 1
    },
    {
      "id": "265cdd79-efd2-4322-bf9b-82d84f7ced83",
      "name": "Retrieve Product List",
      "type": "n8n-nodes-base.shopify",
      "position": [
        1024,
        416
      ],
      "parameters": {
        "resource": "product",
        "operation": "getAll",
        "returnAll": true,
        "authentication": "accessToken",
        "additionalFields": {}
      },
      "executeOnce": true,
      "typeVersion": 1
    },
    {
      "id": "74024650-8bbe-413c-bc7b-186e62136396",
      "name": "Identify Slow Selling Products",
      "type": "n8n-nodes-base.code",
      "position": [
        1248,
        416
      ],
      "parameters": {
        "jsCode": "const cutoff = Date.now() - 30*24*3600*1000;\nconst sold = new Set();\nfor (const item of $('Fetch Recent Orders from Shopify').all()) {\n  const o = item.json;\n  if (new Date(o.created_at).getTime() < cutoff) continue;\n  for (const li of (o.line_items || [])) if (li.product_id) sold.add(String(li.product_id));\n}\nconst slow = $('Retrieve Product List').all()\n  .map(i => i.json)\n  .filter(p => !sold.has(String(p.id)) && (p.images || []).length > 0)\n  .slice(0, 5);\nreturn slow.map(p => ({ json: p }));"
      },
      "typeVersion": 2
    },
    {
      "id": "817f36dd-71b5-4243-bb2f-416869f7e43c",
      "name": "Notify Refresh Completion",
      "type": "n8n-nodes-base.slack",
      "position": [
        2000,
        48
      ],
      "parameters": {
        "text": "Slow-mover refresh complete \u2014 up to 5 products with no sales in 30 days got fresh on-model imagery.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.5
    },
    {
      "id": "822185c0-805f-49b4-bb8e-e796c437af85",
      "name": "Generate New Product Images",
      "type": "n8n-nodes-dreem.dreem",
      "position": [
        1984,
        432
      ],
      "parameters": {
        "talentId": "b2c80190-4a00-4718-9d3f-c531472d5984",
        "shotCodes": [
          "model_front_women"
        ],
        "callbackUrl": "={{ $execution.resumeUrl }}",
        "outputFormat": "jpeg",
        "frontImageUrl": "={{ $json.images[0].src }}",
        "authentication": "apiKey",
        "outputAspectRatio": 5
      },
      "typeVersion": 1
    },
    {
      "id": "ddb0e4f1-81fb-4a6e-8143-3979c7b5815b",
      "name": "Wait for Image Rendering",
      "type": "n8n-nodes-base.wait",
      "position": [
        2192,
        432
      ],
      "parameters": {
        "resume": "webhook",
        "options": {},
        "httpMethod": "POST",
        "resumeUnit": "minutes",
        "resumeAmount": 20,
        "limitWaitTime": true
      },
      "typeVersion": 1.1
    },
    {
      "id": "01d58ea5-982b-4bdd-acef-5e886c8edc26",
      "name": "Check Rendering Completion",
      "type": "n8n-nodes-base.if",
      "position": [
        2400,
        432
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.body?.status ?? $json.status }}",
              "rightValue": "completed"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "97449007-9f2d-4ea0-8e58-36371fbbfac2",
      "name": "Update Product Photos on Shopify",
      "type": "n8n-nodes-base.shopify",
      "position": [
        2624,
        432
      ],
      "parameters": {
        "resource": "product",
        "operation": "update",
        "productId": "={{ $('Batch Process Products').item.json.id }}",
        "updateFields": {
          "images": "={{ ($('Batch Process Products').item.json.images || []).map(i => ({ id: i.id })).concat(($('Wait for Image Rendering').item.json.body.outputs || []).map(o => ({ src: o.files[0].url }))) }}"
        },
        "authentication": "accessToken"
      },
      "typeVersion": 1
    },
    {
      "id": "76c4ee2a-f097-4ff5-bf7a-28b23cb8302c",
      "name": "Batch Process Products",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1456,
        416
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "920d02e6-96ee-44ae-9360-dcd7dbfcf794",
      "name": "Notify Skipped Product Update",
      "type": "n8n-nodes-base.slack",
      "position": [
        3008,
        704
      ],
      "parameters": {
        "text": "=Slow-mover refresh skipped *{{ $('Batch Process Products').item.json.title }}*.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.5
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "99086eb9-b8b0-4709-a977-07a9ef022d3c",
  "nodeGroups": [],
  "connections": {
    "When Monthly at 9am": {
      "main": [
        [
          {
            "node": "Fetch Recent Orders from Shopify",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve Product List": {
      "main": [
        [
          {
            "node": "Identify Slow Selling Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Batch Process Products": {
      "main": [
        [
          {
            "node": "Notify Refresh Completion",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Generate New Product Images",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Image Rendering": {
      "main": [
        [
          {
            "node": "Check Rendering Completion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Rendering Completion": {
      "main": [
        [
          {
            "node": "Update Product Photos on Shopify",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Skipped Product Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate New Product Images": {
      "main": [
        [
          {
            "node": "Wait for Image Rendering",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Skipped Product Update": {
      "main": [
        [
          {
            "node": "Batch Process Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Identify Slow Selling Products": {
      "main": [
        [
          {
            "node": "Batch Process Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Recent Orders from Shopify": {
      "main": [
        [
          {
            "node": "Retrieve Product List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Product Photos on Shopify": {
      "main": [
        [
          {
            "node": "Batch Process Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}