This workflow corresponds to n8n.io template #17326 — we link there as the canonical source.
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 →
{
"id": "0MxmpAAh0NhjkYW2",
"name": "Turn Shopify orders into personalized upsell photos with Dreem.ai",
"tags": [],
"nodes": [
{
"id": "a5eff233-84b0-40a7-b299-753851c9a63a",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"width": 480,
"height": 864,
"content": "## Turn Shopify orders into personalized upsell photos with Dreem.ai\n\n### How it works\n\nThis workflow starts when a new Shopify order is placed, retrieves the purchased item, and pulls the store catalog. It selects the newest arrival as an upsell pairing, sends the purchased item and selected product to Dreem.ai to generate a personalized paired-look image, then waits for the render result. Once checked, it posts either the completed pairing or a timeout notification to Slack.\n\n### Setup steps\n\n- Connect and authorize the Shopify trigger and Shopify nodes with the correct store credentials and permissions to read orders, products, and catalog data.\n- Configure the Dreem.ai node with the required API credentials and generation settings for the paired-look render.\n- Set the Slack credentials, target channel, and message templates for both successful delivery and timeout alerts.\n- Review the custom code in \u201cPick Newest Arrival\u201d to ensure it matches the catalog fields and sorting logic used by the Shopify store.\n\n### Customization\n\nAdjust the product-selection logic to recommend items by category, inventory, margin, or customer history instead of simply choosing the newest arrival. The wait duration, completion condition, Dreem.ai prompt/settings, and Slack message content can also be tuned."
},
"typeVersion": 1
},
{
"id": "2872aebd-5bb6-4524-aa7a-4de7cf62d5ac",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
192
],
"parameters": {
"color": 7,
"width": 640,
"height": 336,
"content": "## Capture Shopify order\n\nStarts from a new Shopify order and gathers the purchased product plus catalog data needed for the upsell recommendation. These nodes form the left-side Shopify intake cluster."
},
"typeVersion": 1
},
{
"id": "414cd85b-422c-4399-bcbf-e06b87849e3d",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1232,
160
],
"parameters": {
"color": 7,
"width": 400,
"height": 368,
"content": "## Select and generate look\n\nChooses the newest catalog arrival and sends it with the purchased item to Dreem.ai to create a personalized paired-look image. This is the central recommendation and image-generation cluster."
},
"typeVersion": 1
},
{
"id": "cce70909-4302-4249-931b-05ecbd4092b4",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1664,
160
],
"parameters": {
"color": 7,
"width": 416,
"height": 368,
"content": "## Wait and check render\n\nPauses for Dreem.ai rendering and evaluates whether the generated image is complete before routing to the appropriate outcome. These nodes sit together as the render-status decision cluster."
},
"typeVersion": 1
},
{
"id": "a283bc74-74a9-43e8-b0b8-d3abe797e9c7",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2112,
0
],
"parameters": {
"color": 7,
"height": 672,
"content": "## Notify Slack outcome\n\nSends the final Slack notification, either delivering the completed paired-look image or reporting that the render timed out. The two Slack endpoints form the right-side output cluster."
},
"typeVersion": 1
},
{
"id": "9b947bdf-8018-4325-8e6a-6dd9629205d7",
"name": "When New Order Placed",
"type": "n8n-nodes-base.shopifyTrigger",
"position": [
608,
368
],
"parameters": {
"topic": "orders/create",
"authentication": "accessToken"
},
"typeVersion": 1
},
{
"id": "71be3c2b-066d-4437-a5c1-173c1cd0d401",
"name": "Retrieve Purchased Item Details",
"type": "n8n-nodes-base.shopify",
"position": [
832,
368
],
"parameters": {
"resource": "product",
"operation": "get",
"productId": "={{ $json.line_items[0].product_id }}",
"authentication": "accessToken",
"additionalFields": {}
},
"typeVersion": 1
},
{
"id": "7586cb38-2320-4fc9-83ae-e165c38facef",
"name": "Fetch Product Catalog",
"type": "n8n-nodes-base.shopify",
"position": [
1056,
368
],
"parameters": {
"resource": "product",
"operation": "getAll",
"returnAll": true,
"authentication": "accessToken",
"additionalFields": {}
},
"executeOnce": true,
"typeVersion": 1
},
{
"id": "9b4ece18-0247-464e-af08-cd23dcc19453",
"name": "Select Latest Product",
"type": "n8n-nodes-base.code",
"position": [
1280,
368
],
"parameters": {
"jsCode": "const purchased = $('Retrieve Purchased Item Details').first().json;\nconst order = $('When New Order Placed').first().json;\nconst arrival = $('Fetch Product Catalog').all()\n .map(i => i.json)\n .filter(p => p.id !== purchased.id && (p.images || []).length > 0)\n .sort((a, b) => new Date(b.created_at) - new Date(a.created_at))[0];\nif (!arrival) return [];\nreturn [{ json: {\n customerEmail: order.email || 'unknown',\n purchasedTitle: purchased.title,\n purchasedImage: (purchased.images || [])[0]?.src,\n arrivalTitle: arrival.title,\n arrivalImage: arrival.images[0].src\n} }];"
},
"typeVersion": 2
},
{
"id": "47e26788-517b-4c9a-968a-34288371fce9",
"name": "Await Image Rendering",
"type": "n8n-nodes-base.wait",
"position": [
1712,
368
],
"parameters": {
"resume": "webhook",
"options": {},
"httpMethod": "POST",
"resumeUnit": "minutes",
"resumeAmount": 20,
"limitWaitTime": true
},
"typeVersion": 1.1
},
{
"id": "fb599a71-90d8-4bb5-8482-d364361f5e8c",
"name": "Check Render Completion",
"type": "n8n-nodes-base.if",
"position": [
1936,
368
],
"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": "0d968f7c-d410-44ec-93c0-0286057629a0",
"name": "Send Pairing to Slack",
"type": "n8n-nodes-base.slack",
"position": [
2160,
272
],
"parameters": {
"text": "=:dress: *Your Closet pairing* for {{ $('Select Latest Product').item.json.customerEmail }}\nOwns: {{ $('Select Latest Product').item.json.purchasedTitle }} \u00b7 New arrival: {{ $('Select Latest Product').item.json.arrivalTitle }}\nStyled together: {{ $('Await Image Rendering').item.json.body.outputs[0].files[0].url }}\nDrop it in the post-purchase email.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.5
},
{
"id": "3401fd64-0273-41da-bc01-72f937f5d8ef",
"name": "Notify Render Timeout",
"type": "n8n-nodes-base.slack",
"position": [
2160,
512
],
"parameters": {
"text": "Your Closet pairing render timed out (or the paired-look request was rejected).",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.5
},
{
"id": "c53e0df7-a24c-4f0e-a990-75af6259572c",
"name": "Generate Upsell Image with Dreem",
"type": "n8n-nodes-dreem.dreem",
"position": [
1488,
368
],
"parameters": {
"talentId": "b2c80190-4a00-4718-9d3f-c531472d5984",
"shotCodes": [
"model_front_women"
],
"callbackUrl": "={{ $execution.resumeUrl }}",
"outputFormat": "jpeg",
"frontImageUrl": "={{ $json.arrivalImage }}",
"authentication": "apiKey",
"stylingImageUrls": {
"imageValues": [
{
"url": "={{ $json.purchasedImage }}"
}
]
},
"outputAspectRatio": 5
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "25ebec0a-a65e-46f5-a804-8ed01ba58074",
"nodeGroups": [],
"connections": {
"Await Image Rendering": {
"main": [
[
{
"node": "Check Render Completion",
"type": "main",
"index": 0
}
]
]
},
"Fetch Product Catalog": {
"main": [
[
{
"node": "Select Latest Product",
"type": "main",
"index": 0
}
]
]
},
"Select Latest Product": {
"main": [
[
{
"node": "Generate Upsell Image with Dreem",
"type": "main",
"index": 0
}
]
]
},
"When New Order Placed": {
"main": [
[
{
"node": "Retrieve Purchased Item Details",
"type": "main",
"index": 0
}
]
]
},
"Check Render Completion": {
"main": [
[
{
"node": "Send Pairing to Slack",
"type": "main",
"index": 0
}
],
[
{
"node": "Notify Render Timeout",
"type": "main",
"index": 0
}
]
]
},
"Retrieve Purchased Item Details": {
"main": [
[
{
"node": "Fetch Product Catalog",
"type": "main",
"index": 0
}
]
]
},
"Generate Upsell Image with Dreem": {
"main": [
[
{
"node": "Await Image Rendering",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
On every Shopify order, this workflow pairs the purchased item with your newest arrival and generates one personalized on-model photo in dreem.ai: the new piece as the main garment, the customer's purchase styled into the look. Can be added to your email provider. A Shopify…
Source: https://n8n.io/workflows/17326/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates the synchronization of product prices across Shopify and WooCommerce platforms to ensure retail consistency. It triggers when a price change is detected in either system, appli
This n8n template automatically sends personalized recovery emails to customers who abandon their shopping carts. Recover 15-25% of lost sales with intelligent, well-timed follow-up emails that includ
This automation triggers when a new order is placed in your Shopify store. It then waits a short period, intelligently identifies complementary products based on the customer's purchase, retrieves tho
07 - Shopify Order → Fulfillment + Thank You Email. Uses shopifyTrigger, shopify, gmail. Event-driven trigger; 5 nodes.
E-commerce Automation Team Communication