Google Drive to Shopify, CSVs ready in Google Sheets
Bulk product uploads sound simple until you’re staring at a folder of images, a half-filled spreadsheet, and a Shopify import that keeps failing on tiny formatting issues. The work is repetitive, but the mistakes are expensive.
Shopify store owners feel it when new inventory arrives. Ecommerce managers feel it during seasonal drops. And agency teams get stuck doing it for client after client. This Shopify CSV automation turns raw product images into a Shopify-ready CSV in Google Sheets, so you can review, upload, and move on.
You’ll see how the workflow pulls images from Google Drive, uses AI to generate product data, uploads assets to Shopify, and outputs a clean import CSV your team can trust.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: Google Drive to Shopify, CSVs ready in Google Sheets
flowchart LR
subgraph sg0["Schedule Flow"]
direction LR
n12@{ icon: "mdi:database", form: "rounded", label: "Get row(s) in sheet", pos: "b", h: 48 }
n13@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger1", pos: "b", h: 48 }
n14@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items2", pos: "b", h: 48 }
n44@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch", pos: "b", h: 48 }
n45@{ icon: "mdi:brain", form: "rounded", label: "Gemini", pos: "b", h: 48 }
n46@{ icon: "mdi:memory", form: "rounded", label: "Memory", pos: "b", h: 48 }
n47@{ icon: "mdi:robot", form: "rounded", label: "Structured", pos: "b", h: 48 }
n48@{ icon: "mdi:robot", form: "rounded", label: "Bridal item", pos: "b", h: 48 }
n49@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash", pos: "b", h: 48 }
n50["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML"]
n51@{ icon: "mdi:database", form: "rounded", label: "update bridal data", pos: "b", h: 48 }
n52@{ icon: "mdi:brain", form: "rounded", label: "Gemini1", pos: "b", h: 48 }
n53@{ icon: "mdi:memory", form: "rounded", label: "Memory1", pos: "b", h: 48 }
n54@{ icon: "mdi:robot", form: "rounded", label: "Structured1", pos: "b", h: 48 }
n55@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash1", pos: "b", h: 48 }
n56["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML1"]
n57@{ icon: "mdi:robot", form: "rounded", label: "Chain item", pos: "b", h: 48 }
n58@{ icon: "mdi:database", form: "rounded", label: "update chain data", pos: "b", h: 48 }
n59@{ icon: "mdi:brain", form: "rounded", label: "Gemini2", pos: "b", h: 48 }
n60@{ icon: "mdi:memory", form: "rounded", label: "Memory2", pos: "b", h: 48 }
n61@{ icon: "mdi:robot", form: "rounded", label: "Structured2", pos: "b", h: 48 }
n62@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash2", pos: "b", h: 48 }
n63["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML2"]
n64@{ icon: "mdi:brain", form: "rounded", label: "Gemini3", pos: "b", h: 48 }
n65@{ icon: "mdi:memory", form: "rounded", label: "Memory3", pos: "b", h: 48 }
n66@{ icon: "mdi:robot", form: "rounded", label: "Structured3", pos: "b", h: 48 }
n67@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash3", pos: "b", h: 48 }
n68["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML3"]
n69@{ icon: "mdi:robot", form: "rounded", label: "Rakhi item", pos: "b", h: 48 }
n70@{ icon: "mdi:database", form: "rounded", label: "update Rakhi data", pos: "b", h: 48 }
n71@{ icon: "mdi:brain", form: "rounded", label: "Gemini5", pos: "b", h: 48 }
n72@{ icon: "mdi:memory", form: "rounded", label: "Memory5", pos: "b", h: 48 }
n73@{ icon: "mdi:robot", form: "rounded", label: "Structured5", pos: "b", h: 48 }
n74@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash5", pos: "b", h: 48 }
n75["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML5"]
n76@{ icon: "mdi:brain", form: "rounded", label: "Gemini6", pos: "b", h: 48 }
n77@{ icon: "mdi:memory", form: "rounded", label: "Memory6", pos: "b", h: 48 }
n78@{ icon: "mdi:robot", form: "rounded", label: "Structured6", pos: "b", h: 48 }
n79@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash6", pos: "b", h: 48 }
n80["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML6"]
n81@{ icon: "mdi:brain", form: "rounded", label: "Gemini7", pos: "b", h: 48 }
n82@{ icon: "mdi:memory", form: "rounded", label: "Memory7", pos: "b", h: 48 }
n83@{ icon: "mdi:robot", form: "rounded", label: "Structured7", pos: "b", h: 48 }
n84@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash7", pos: "b", h: 48 }
n85["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML7"]
n86@{ icon: "mdi:robot", form: "rounded", label: "Bindi item", pos: "b", h: 48 }
n87@{ icon: "mdi:database", form: "rounded", label: "update Bindi data", pos: "b", h: 48 }
n88@{ icon: "mdi:database", form: "rounded", label: "update Pandents data", pos: "b", h: 48 }
n89@{ icon: "mdi:robot", form: "rounded", label: "Pandents item", pos: "b", h: 48 }
n90@{ icon: "mdi:robot", form: "rounded", label: "Jewellery Accessories item", pos: "b", h: 48 }
n91@{ icon: "mdi:database", form: "rounded", label: "update Jewellery Accessories..", pos: "b", h: 48 }
n92@{ icon: "mdi:brain", form: "rounded", label: "Gemini8", pos: "b", h: 48 }
n93@{ icon: "mdi:memory", form: "rounded", label: "Memory8", pos: "b", h: 48 }
n94@{ icon: "mdi:robot", form: "rounded", label: "Structured8", pos: "b", h: 48 }
n95@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash8", pos: "b", h: 48 }
n96["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML8"]
n97@{ icon: "mdi:brain", form: "rounded", label: "Gemini9", pos: "b", h: 48 }
n98@{ icon: "mdi:memory", form: "rounded", label: "Memory9", pos: "b", h: 48 }
n99@{ icon: "mdi:robot", form: "rounded", label: "Structured9", pos: "b", h: 48 }
n100@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash9", pos: "b", h: 48 }
n101["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML10"]
n102@{ icon: "mdi:brain", form: "rounded", label: "Gemini10", pos: "b", h: 48 }
n103@{ icon: "mdi:memory", form: "rounded", label: "Memory10", pos: "b", h: 48 }
n104@{ icon: "mdi:robot", form: "rounded", label: "Structured10", pos: "b", h: 48 }
n105@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash10", pos: "b", h: 48 }
n106["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML11"]
n107@{ icon: "mdi:brain", form: "rounded", label: "Gemini11", pos: "b", h: 48 }
n108@{ icon: "mdi:memory", form: "rounded", label: "Memory11", pos: "b", h: 48 }
n109@{ icon: "mdi:robot", form: "rounded", label: "Structured11", pos: "b", h: 48 }
n110@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash11", pos: "b", h: 48 }
n111["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML12"]
n112@{ icon: "mdi:brain", form: "rounded", label: "Gemini12", pos: "b", h: 48 }
n113@{ icon: "mdi:memory", form: "rounded", label: "Memory12", pos: "b", h: 48 }
n114@{ icon: "mdi:robot", form: "rounded", label: "Structured12", pos: "b", h: 48 }
n115@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash12", pos: "b", h: 48 }
n116["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML13"]
n117@{ icon: "mdi:brain", form: "rounded", label: "Gemini13", pos: "b", h: 48 }
n118@{ icon: "mdi:memory", form: "rounded", label: "Memory13", pos: "b", h: 48 }
n119@{ icon: "mdi:robot", form: "rounded", label: "Structured13", pos: "b", h: 48 }
n120@{ icon: "mdi:brain", form: "rounded", label: "Gemini 2.5flash13", pos: "b", h: 48 }
n121["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>text to HTML14"]
n122@{ icon: "mdi:robot", form: "rounded", label: "Hair accessories item", pos: "b", h: 48 }
n123@{ icon: "mdi:database", form: "rounded", label: "update Hair accessories data", pos: "b", h: 48 }
n124@{ icon: "mdi:robot", form: "rounded", label: "Combo item", pos: "b", h: 48 }
n125@{ icon: "mdi:database", form: "rounded", label: "update Combo data", pos: "b", h: 48 }
n126@{ icon: "mdi:robot", form: "rounded", label: "Rings item", pos: "b", h: 48 }
n127@{ icon: "mdi:database", form: "rounded", label: "update Rings data", pos: "b", h: 48 }
n128@{ icon: "mdi:robot", form: "rounded", label: "Bangles item", pos: "b", h: 48 }
n129@{ icon: "mdi:database", form: "rounded", label: "update Bangles data", pos: "b", h: 48 }
n130@{ icon: "mdi:robot", form: "rounded", label: "Earrings item", pos: "b", h: 48 }
n131@{ icon: "mdi:database", form: "rounded", label: "update Earrings data", pos: "b", h: 48 }
n132@{ icon: "mdi:robot", form: "rounded", label: "Necklace item", pos: "b", h: 48 }
n133@{ icon: "mdi:database", form: "rounded", label: "update Necklace data", pos: "b", h: 48 }
n134@{ icon: "mdi:robot", form: "rounded", label: "Brooch item", pos: "b", h: 48 }
n135@{ icon: "mdi:database", form: "rounded", label: "update Brooch data", pos: "b", h: 48 }
n136@{ icon: "mdi:cog", form: "rounded", label: "Wait2", pos: "b", h: 48 }
n136 --> n14
n45 -.-> n48
n46 -.-> n48
n44 --> n132
n44 --> n130
n44 --> n128
n44 --> n126
n44 --> n124
n44 --> n122
n44 --> n90
n44 --> n89
n44 --> n86
n44 --> n69
n44 --> n134
n44 --> n48
n44 --> n57
n52 -.-> n57
n59 -.-> n69
n64 -.-> n134
n71 -.-> n86
n76 -.-> n90
n81 -.-> n89
n92 -.-> n122
n97 -.-> n126
n53 -.-> n57
n60 -.-> n69
n65 -.-> n134
n72 -.-> n86
n77 -.-> n90
n82 -.-> n89
n93 -.-> n122
n98 -.-> n126
n102 -.-> n124
n107 -.-> n130
n112 -.-> n128
n117 -.-> n132
n103 -.-> n124
n108 -.-> n130
n113 -.-> n128
n118 -.-> n132
n86 --> n75
n57 --> n56
n124 --> n106
n69 --> n63
n126 --> n101
n47 -.-> n48
n48 --> n50
n134 --> n68
n54 -.-> n57
n61 -.-> n69
n66 -.-> n134
n73 -.-> n86
n78 -.-> n90
n83 -.-> n89
n94 -.-> n122
n99 -.-> n126
n128 --> n116
n104 -.-> n124
n109 -.-> n130
n114 -.-> n128
n119 -.-> n132
n50 --> n51
n130 --> n111
n132 --> n121
n89 --> n85
n56 --> n58
n63 --> n70
n68 --> n135
n75 --> n87
n80 --> n91
n85 --> n88
n96 --> n123
n101 --> n127
n106 --> n125
n111 --> n131
n116 --> n129
n121 --> n133
n49 -.-> n47
n55 -.-> n54
n62 -.-> n61
n67 -.-> n66
n74 -.-> n73
n79 -.-> n78
n84 -.-> n83
n95 -.-> n94
n100 -.-> n99
n14 --> n44
n105 -.-> n104
n110 -.-> n109
n115 -.-> n114
n120 -.-> n119
n13 --> n12
n87 --> n136
n125 --> n136
n70 --> n136
n127 --> n136
n58 --> n136
n135 --> n136
n51 --> n136
n12 --> n14
n129 --> n136
n131 --> n136
n133 --> n136
n88 --> n136
n122 --> n96
n90 --> n80
n123 --> n136
n91 --> n136
end
subgraph sg1["Schedule Flow"]
direction LR
n33@{ icon: "mdi:database", form: "rounded", label: "Get row(s) in sheet2", pos: "b", h: 48 }
n34@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger4", pos: "b", h: 48 }
n35@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items4", pos: "b", h: 48 }
n36@{ icon: "mdi:database", form: "rounded", label: "Update row in sheet3", pos: "b", h: 48 }
n37@{ icon: "mdi:robot", form: "rounded", label: "AI Agent2", pos: "b", h: 48 }
n38@{ icon: "mdi:memory", form: "rounded", label: "Simple Memory2", pos: "b", h: 48 }
n39@{ icon: "mdi:robot", form: "rounded", label: "Auto-fixing Output Parser", pos: "b", h: 48 }
n40@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Parser", pos: "b", h: 48 }
n41@{ icon: "mdi:brain", form: "rounded", label: "Google Gemini Chat Model2", pos: "b", h: 48 }
n43@{ icon: "mdi:cog", form: "rounded", label: "Wait1", pos: "b", h: 48 }
n138@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model1", pos: "b", h: 48 }
n43 --> n36
n37 --> n43
n38 -.-> n37
n35 --> n37
n34 --> n33
n138 -.-> n39
n33 --> n35
n36 --> n35
n40 -.-> n39
n39 -.-> n37
n41 -.-> n37
end
subgraph sg2["START Flow"]
direction LR
n24@{ icon: "mdi:swap-vertical", form: "rounded", label: "query_folder_name1", pos: "b", h: 48 }
n25@{ icon: "mdi:cog", form: "rounded", label: "Search_folders1", pos: "b", h: 48 }
n26@{ icon: "mdi:cog", form: "rounded", label: "image_within_folder1", pos: "b", h: 48 }
n27@{ icon: "mdi:swap-vertical", form: "rounded", label: "looping1", pos: "b", h: 48 }
n28@{ icon: "mdi:database", form: "rounded", label: "add_image_data2", pos: "b", h: 48 }
n29@{ icon: "mdi:cog", form: "rounded", label: "sku_sort", pos: "b", h: 48 }
n30["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>variant_numbering1"]
n31["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>sku_structuring1"]
n32["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/form.svg' width='40' height='40' /></div><br/>START"]
n32 --> n24
n27 --> n28
n29 --> n30
n25 --> n26
n28 --> n27
n31 --> n29
n24 --> n25
n30 --> n27
n26 --> n31
end
subgraph sg3["When clicking ‘Execute workflow’ Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "When clicking ‘Execute workf..", pos: "b", h: 48 }
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HTTP Request"]
n2["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HTTP Request1"]
n3@{ icon: "mdi:cog", form: "rounded", label: "Download file", pos: "b", h: 48 }
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HTTP Request2"]
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HTTP Request3"]
n15@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items", pos: "b", h: 48 }
n16@{ icon: "mdi:database", form: "rounded", label: "Update row in sheet2", pos: "b", h: 48 }
n137@{ icon: "mdi:database", form: "rounded", label: "get product data", pos: "b", h: 48 }
n1 --> n3
n3 --> n2
n2 --> n4
n4 --> n5
n5 --> n16
n15 --> n1
n137 --> n15
n16 --> n15
n0 --> n137
end
subgraph sg4["Schedule Flow"]
direction LR
n6@{ icon: "mdi:robot", form: "rounded", label: "Analyze an image", pos: "b", h: 48 }
n7@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger", pos: "b", h: 48 }
n8@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items1", pos: "b", h: 48 }
n9@{ icon: "mdi:cog", form: "rounded", label: "Download file1", pos: "b", h: 48 }
n10@{ icon: "mdi:database", form: "rounded", label: "Update row in sheet", pos: "b", h: 48 }
n11@{ icon: "mdi:database", form: "rounded", label: "pending_image_to analyze", pos: "b", h: 48 }
n42@{ icon: "mdi:cog", form: "rounded", label: "Wait", pos: "b", h: 48 }
n42 --> n10
n9 --> n6
n6 --> n42
n8 --> n9
n7 --> n11
n10 --> n8
n11 --> n8
end
subgraph sg5["Schedule Flow"]
direction LR
n17@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger2", pos: "b", h: 48 }
n18@{ icon: "mdi:database", form: "rounded", label: "get finalized data", pos: "b", h: 48 }
n19["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>structuring columns"]
n20["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>structuring body content"]
n21@{ icon: "mdi:database", form: "rounded", label: "Append row in sheet", pos: "b", h: 48 }
n22@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items3", pos: "b", h: 48 }
n23@{ icon: "mdi:cog", form: "rounded", label: "nothing", pos: "b", h: 48 }
n22 --> n23
n22 --> n19
n17 --> n18
n18 --> n22
n21 --> n22
n19 --> n20
n20 --> n21
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n13,n34,n32,n0,n7,n17 trigger
class n47,n48,n54,n57,n61,n66,n69,n73,n78,n83,n86,n89,n90,n94,n99,n104,n109,n114,n119,n122,n124,n126,n128,n130,n132,n134,n37,n39,n40,n6 ai
class n45,n49,n52,n55,n59,n62,n64,n67,n71,n74,n76,n79,n81,n84,n92,n95,n97,n100,n102,n105,n107,n110,n112,n115,n117,n120,n41,n138 aiModel
class n46,n53,n60,n65,n72,n77,n82,n93,n98,n103,n108,n113,n118,n38 ai
class n44 decision
class n12,n51,n58,n70,n87,n88,n91,n123,n125,n127,n129,n131,n133,n135,n33,n36,n28,n16,n137,n10,n11,n18,n21 database
class n1,n2,n4,n5 api
class n50,n56,n63,n68,n75,n80,n85,n96,n101,n106,n111,n116,n121,n30,n31,n19,n20 code
classDef customIcon fill:none,stroke:none
class n50,n56,n63,n68,n75,n80,n85,n96,n101,n106,n111,n116,n121,n30,n31,n32,n1,n2,n4,n5,n19,n20 customIcon
The Challenge: Turning Images Into Import-Ready Product Data
If your catalog is image-first (jewelry, fashion, accessories), your “product data” often starts as photos and a SKU list, not neatly structured fields. Someone has to name files, match variants, write titles and descriptions, guess categories, upload images, copy URLs, then rebuild everything into Shopify’s CSV format. And then you do it again because one column header was off, or the HTML description broke, or variants didn’t map cleanly. It’s not hard work. It’s fragile work, and it drains your attention fast.
It adds up fast. Here’s where it breaks down in real stores.
- Every manual copy-paste between Drive, Sheets, and Shopify is a chance to mismatch a SKU and create the wrong variant.
- Writing product titles, tags, and HTML descriptions for dozens of items turns into a long afternoon of “good enough” content.
- Shopify CSV imports fail for annoying reasons (missing handles, bad headers, wrong image URL structure), and troubleshooting eats the time you thought you saved.
- When the process lives in someone’s head, scaling to weekly drops becomes stressful and inconsistent.
The Fix: Convert Google Drive Images Into a Shopify-Ready CSV
This workflow treats your Google Drive folder as the start of your product pipeline. You drop product images into a specific “pending” folder structure, using a consistent filename pattern that includes SKU and color code (for example, 12345GR). From there, n8n scans the folder, pulls each image, and analyzes them one-by-one using an AI image analysis step that prioritizes accuracy over speed. The AI generates the product basics you normally have to invent manually: category, title, Shopify-ready HTML description, tags, and attributes. Next, the workflow uploads the images to Shopify, retrieves the CDN URLs, and maps those URLs back onto the right product rows. Finally, it writes everything into Google Sheets in Shopify’s import CSV structure so you can review it, export it, and upload with far fewer surprises.
The workflow starts with a manual or scheduled trigger. Then it pulls images from Google Drive and uses Google Sheets as the “control center” for organizing rows, variants, and generated content. Shopify receives the images via API upload, and the final output is a clean CSV-ready sheet for bulk import.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you’re onboarding 50 products for a new collection, and each product has 3 variant images. Manually, it’s easy to spend about 5 minutes per product on filenames and mapping, another 10 minutes writing copy, plus a few minutes uploading and pasting image URLs. That’s roughly 15 minutes per product, or about 12 hours for the batch. With this workflow, you prep the Drive folder once, then let the AI and Shopify upload steps run; most teams end up spending about an hour reviewing the Google Sheet before importing.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Drive to store product image folders.
- Google Sheets to generate and review the CSV output.
- Shopify Admin API access token (create it in Shopify admin apps).
- AI provider API key (get it from your AI vendor dashboard).
Skill level: Intermediate. You’ll connect accounts, paste API keys, and confirm Shopify CSV fields match your store setup.
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A folder scan kicks it off. You run the workflow manually (or on a schedule) and it scans Google Drive for images inside your pending/<brand_name> folder structure. Filenames are parsed to pull SKU and color code so variants don’t get mixed up.
Google Sheets becomes the staging area. The workflow writes a row per item (and per variant where needed), so you have a structured place to track what was found, what was generated, and what is ready for upload.
AI fills in the missing product details. Images are analyzed one-by-one, which is slower but frankly safer for real catalogs. The workflow identifies the main category (like Jewelry), then generates titles, HTML descriptions, tags, and attributes based on that category logic.
Shopify receives the images and returns clean URLs. Images are uploaded through Shopify (often via HTTP request or Shopify nodes), and the workflow captures the CDN URLs. Those URLs are mapped back into the correct CSV fields in Google Sheets.
You can easily modify category prompts and CSV columns to match your niche and import rules. See the full implementation guide below for customization options.
Watch Out For
- Google Drive and Google Sheets OAuth credentials can expire or be missing folder permissions. If the scan suddenly returns nothing, check the n8n credential connection status and confirm the “pending” folder is shared correctly.
- If you’re using Wait nodes or relying on Shopify to finish processing uploads, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses or missing CDN URLs.
- Default AI prompts are generic, and generic content looks generic. Add your brand voice, material details you care about, and “do not guess” rules early or you will be editing outputs forever.
Common Questions
About an hour if your accounts and tokens are ready.
Yes, but someone needs to be comfortable connecting OAuth accounts and pasting API keys. Once it’s connected, day-to-day use is basically “drop images in Drive, run, review in Sheets.”
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in AI API costs and Shopify API usage.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
You can adjust the category detection and copy style by editing the AI prompts used for image analysis and content generation. If you don’t sell jewelry or fashion, change the “main category” logic so the workflow routes into the right attributes for your niche. Common customizations include adding metafields, generating multi-language descriptions, and mapping to your preferred option names (like Size, Material, or Finish).
Usually it’s an expired access token or an app that doesn’t have the right Admin API scopes. Regenerate the Shopify access token, update it in n8n, then try a single-image run to confirm uploads work. If it fails only on larger batches, it can be rate limiting or timeouts during image upload. In that case, slow the workflow down and keep the one-by-one approach.
It scales well because images are processed one at a time, so you can run big batches without chaos. On n8n Cloud, capacity depends on your plan’s monthly executions. If you self-host, there’s no execution limit, but your server and Shopify API limits become the bottleneck. Practically, most stores run this as a batch job for new collections, then spot-check the Sheet before importing.
Often, yes, because this flow needs branching logic, file handling (reading images), and multi-step transformations that get awkward and pricey in simpler automation tools. n8n is also easier to self-host, which matters if you’re running large batches. Zapier or Make can still work if you keep the scope small and don’t need per-image AI analysis. The real question is maintenance: do you want a robust pipeline you can extend, or a quick connector that tops out fast? Talk to an automation expert if you want a second opinion based on your catalog size.
Once this is in place, new products stop feeling like a data-entry project. You get a reviewable Google Sheet, a Shopify-ready CSV, and a workflow that doesn’t panic when the next collection shows up.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.