AutomationFlowsAI & RAG › Synchronizing Woocommerce Inventory and Creating Products with Google Gemini…

Synchronizing Woocommerce Inventory and Creating Products with Google Gemini…

Original n8n title: Synchronizing Woocommerce Inventory and Creating Products with Google Gemini AI and Browseract

ByMadame AI Team | Kai @madame-ai on n8n.io

This workflow is essential for e-commerce operators, dropshippers, and inventory managers who need to ensure their product pricing and stock levels are synchronized with multiple third-party suppliers, minimizing overselling and maximizing profit.

Event trigger★★★★★ complexityAI-powered31 nodesWooCommerceN8N Nodes Browseract WorkflowsGoogle Gemini ChatSlackAgentGoogle Sheets
AI & RAG Trigger: Event Nodes: 31 Complexity: ★★★★★ AI nodes: yes Added:

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

This workflow follows the Agent → 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
{
  "id": "xWJadnVEYEmfvsH5",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Advanced WooCommerce Product Reconciliation & Synchronization",
  "tags": [],
  "nodes": [
    {
      "id": "359efd1f-8b53-4856-aa26-48103897473d",
      "name": "Get many products",
      "type": "n8n-nodes-base.wooCommerce",
      "position": [
        256,
        -144
      ],
      "parameters": {
        "options": {
          "search": "={{ $json.Name }}"
        },
        "operation": "getAll"
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "5d014a7c-5952-41de-8be2-08435144fab4",
      "name": "Update a product",
      "type": "n8n-nodes-base.wooCommerce",
      "onError": "continueErrorOutput",
      "position": [
        944,
        -160
      ],
      "parameters": {
        "imagesUi": {},
        "resource": "product",
        "operation": "update",
        "productId": "={{ $json.id }}",
        "metadataUi": {},
        "dimensionsUi": {},
        "updateFields": {
          "regularPrice": "={{ $('BrowserAct JSON Breakdown').item.json.Price }}",
          "stockQuantity": "={{ $('BrowserAct JSON Breakdown').item.json.Quantity }}"
        }
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f3091026-476d-48e7-8768-0015c03564a1",
      "name": "Get Product Stock Data",
      "type": "n8n-nodes-browseract-workflows.browserAct",
      "onError": "continueErrorOutput",
      "position": [
        -512,
        -80
      ],
      "parameters": {
        "workflowId": "58839712632662919",
        "runMaxWaitTime": 900,
        "inputParameters": {
          "parameters": [
            {
              "name": "Target_Url",
              "value": "={{ $json[\"Inventory page\"] }}"
            }
          ]
        },
        "additionalFields": {
          "saveBrowserData": true
        },
        "runPollingInterval": 30
      },
      "credentials": {
        "browserActApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "16539d4b-2817-4dc2-abac-2c58bc3ad5d8",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        736,
        240
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e7b713db-9a9b-41e1-accd-2c7a3fe6b737",
      "name": "Send a message",
      "type": "n8n-nodes-base.slack",
      "position": [
        -512,
        -240
      ],
      "parameters": {
        "text": "The product syncing process finished.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09LWT82KHN",
          "cachedResultName": "new_product_added"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "60842653-3eec-4b3f-a80a-cf8cf3da97d7",
      "name": "Create a product",
      "type": "n8n-nodes-base.wooCommerce",
      "onError": "continueErrorOutput",
      "position": [
        960,
        48
      ],
      "parameters": {
        "name": "={{ $('BrowserAct Json Breakdown').item.json.Name }}",
        "imagesUi": {},
        "resource": "product",
        "operation": "create",
        "metadataUi": {},
        "dimensionsUi": {},
        "additionalFields": {
          "sku": "=SKU_{{ $('BrowserAct Json Breakdown').item.json.Name }}",
          "description": "={{ $json.output }}",
          "manageStock": true,
          "regularPrice": "={{ $('BrowserAct Json Breakdown').item.json.Price}}",
          "stockQuantity": "={{ $('BrowserAct Json Breakdown').item.json.Quantity }}"
        }
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8b95853a-0792-4c73-bbfe-07c8921844e5",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        1392,
        16
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "358f3506-7b05-48e8-9e75-d9315c22b90e",
      "name": "Add Missing Product",
      "type": "n8n-nodes-browseract-workflows.browserAct",
      "onError": "continueErrorOutput",
      "position": [
        336,
        64
      ],
      "parameters": {
        "workflowId": "58839211174254215",
        "runMaxWaitTime": 900,
        "inputParameters": {
          "parameters": [
            {
              "name": "Product_Name",
              "value": "={{ $('BrowserAct JSON Breakdown').item.json.Name }}"
            },
            {
              "name": "Supplier_Link",
              "value": "https://www.digikey.co.uk/en/"
            }
          ]
        },
        "additionalFields": {},
        "runPollingInterval": 30
      },
      "credentials": {
        "browserActApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7de632a3-0a8e-483e-95b0-5751bb738968",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1088,
        -96
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "1384104c-8f59-459a-a563-f814fa395e91",
      "name": "Sticky Note - Intro",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1136,
        96
      ],
      "parameters": {
        "width": 672,
        "height": 560,
        "content": "## Try It Out!\n### This sophisticated n8n template automates WooCommerce inventory management by scraping supplier stock data, updating existing products, and intelligently creating new ones with AI-formatted descriptions.\n\n### How it works\n* The workflow reads a list of suppliers and their inventory page URLs from a **Google Sheet**.\n* It **loops** through each supplier.\n* For each supplier, it uses **BrowserAct** to scrape the current product stock and price data.\n* It then **loops** through each product found in the scraped data.\n* The workflow searches **WooCommerce** to see if the product already exists.\n* **If the product exists:** It updates the price and stock quantity in WooCommerce.\n* **If the product DOES NOT exist:**\n    * It optionally checks if the product category matches a predefined type.\n    * If it matches, it runs a **second BrowserAct** workflow to scrape detailed product attributes from another source (e.g., DigiKey).\n    * An **AI Agent (Gemini)** transforms these attributes into a specific HTML table format for the product description.\n    * Finally, it creates the new product in **WooCommerce** with all scraped details and the AI-generated description.\n* Error handling is included to send **Slack** alerts if updates or creations fail.\n\n### Requirements\n* **BrowserAct** API account for web scraping.\n* **BrowserAct** n8n Community Node -> ([n8n Nodes BrowserAct](https://www.npmjs.com/package/n8n-nodes-browseract-workflows))\n* **Google Sheets** credentials for the supplier list.\n* **WooCommerce** credentials for product management.\n* **Google Gemini** account for the AI Agent.\n* **Slack** credentials for error alerts.\n* BrowserAct templates named **\u201cWooCommerce Inventory & Stock Synchronization\u201d** and **\u201cWooCommerce Product Data Reconciliation\u201d**.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/UpnCKd7GaU) or Visit Our [Blog](https://www.browseract.com/blog)!\n"
      },
      "typeVersion": 1
    },
    {
      "id": "6e2da3a0-7637-427e-9b54-c2c30032cc91",
      "name": "Sticky Note - How to Use",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        384
      ],
      "parameters": {
        "width": 528,
        "height": 264,
        "content": "## How to use\n\n1.  **Set up Credentials:** Add your credentials for **BrowserAct**, **Google Sheets**, **WooCommerce**, **Google Gemini**, and **Slack**.\n2.  **Set up BrowserAct Templates:** Ensure you have the **\u201cGet Product Stock Data\u201d** and **\u201cAdd Missing Product\u201d** templates in your BrowserAct account.\n3.  **Prepare Your Input Sheet:** In the 'Get row(s) in sheet' node, point it to your spreadsheet. It must have columns like `Inventory page` (URL for stock check), `Name` (supplier name), and potentially `Product Type` if using the category filter.\n4.  **Set Slack Channel:** Update the **Channel ID** in the **Slack** error notification node.\n5.  **Configure Category Check (Optional):** Adjust the logic in the `If1` node if you want to filter which missing products get created based on category.\n6.  **Activate Workflow:** Manually trigger the workflow or replace the trigger with a `Schedule Trigger` for automation."
      },
      "typeVersion": 1
    },
    {
      "id": "82e23aaf-ceca-4015-9136-bf23ff035997",
      "name": "Sticky Note - Need Help",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        224
      ],
      "parameters": {
        "width": 336,
        "height": 152,
        "content": "### Need Help?\n* #### [How to Find Your BrowseAct API Key & Workflow ID](https://www.youtube.com/watch?v=pDjoZWEsZlE)\n* #### [How to Connect n8n to Browseract](https://www.youtube.com/watch?v=RoYMdJaRdcQ)\n* #### [How to Use & Customize BrowserAct Templates](https://www.youtube.com/watch?v=CPZHFUASncY)\n* #### [How to Use the BrowserAct N8N Community Node](https://youtu.be/j0Nlba2pRLU)\n* #### [STOP Overselling! Auto-Sync WooCommerce Inventory from ANY Supplier](https://youtu.be/khLtyM2ktoU)"
      },
      "typeVersion": 1
    },
    {
      "id": "9d902298-8b60-4646-abaf-e7383878b6ff",
      "name": "Sticky Note - Input & Scrape Loop",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        -432
      ],
      "parameters": {
        "color": 6,
        "width": 624,
        "height": 176,
        "content": "### \ud83d\udccb 1. Input & Scrape Loop\n\n* **Trigger:** Starts the process manually or on a schedule.\n* **Google Sheets:** Fetches your list of suppliers and their inventory page URLs.\n* **Loop Over Items:** Processes each supplier one by one.\n* **Get Product Stock Data (BrowserAct):** Runs the first scraper to get the list of products currently in stock for the supplier.\n* **Code Node:** Parses the scraped stock data into individual product items.\n* **Slack Node:** Send Alert to Slack channel"
      },
      "typeVersion": 1
    },
    {
      "id": "14b77e15-d220-4687-b260-1679b1d7649f",
      "name": "Sticky Note - Product Processing Loop",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        -400
      ],
      "parameters": {
        "color": 5,
        "width": 560,
        "height": 200,
        "content": "### \ud83d\udd04 2. Product Processing Loop & Update Existing Product\nThis section runs for every product scraped from the supplier.\n\n* **Loop Over Items1:** Handles each product individually.\n* **Get many products (WooCommerce):** Searches your store to see if this product already exists based on its name.\n* **If (Product Exists?):** This crucial node routes the workflow based on whether the product was found.\nIf the product *was* found in WooCommerce:\n\n* **Update a product (WooCommerce):** This node takes the scraped `Price` and `Quantity` and updates the existing product record. It's set to continue on error and trigger a Slack alert if the update fails. "
      },
      "typeVersion": 1
    },
    {
      "id": "7b291eaf-c4a1-46fd-9083-cf7e81a57ff0",
      "name": "Sticky Note - Create New Product",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        368
      ],
      "parameters": {
        "color": 4,
        "width": 480,
        "height": 216,
        "content": "### \u2728 4. Create New Product (If Missing)\n\nIf the product was *not* found:\n\n* **If1 (Category Check - Optional):** Filters if you only want to add products matching a specific type.\n* **Add Missing Product (BrowserAct):** Runs a *second* scraper to get detailed attributes from another source.\n* **Code Node:** Parses these detailed attributes.\n* **AI Agent:** Uses Gemini to transform the attributes into an HTML table for the description.\n* **Create a product (WooCommerce):** Creates the new product using all scraped data and the AI description. Also includes error handling."
      },
      "typeVersion": 1
    },
    {
      "id": "bd5c0de3-4b7a-4f31-9d78-3dda3bcd1c2b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -176
      ],
      "parameters": {
        "color": 5,
        "width": 1184,
        "height": 208,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "f75b433a-1c8c-458b-aecf-879a6881f23d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        112,
        48
      ],
      "parameters": {
        "color": 4,
        "width": 976,
        "height": 304,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "06d9505d-d672-469e-b0d0-36fdf1a5abd9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -960,
        -240
      ],
      "parameters": {
        "color": 6,
        "width": 848,
        "height": 320,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "7535c929-96b9-451e-bf9e-c6a6b440d6b3",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        48
      ],
      "parameters": {
        "color": 3,
        "height": 208,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "98d804e1-f59d-4020-844c-d7e04b86a57c",
      "name": "Sticky Note - Create New Product1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        272
      ],
      "parameters": {
        "color": 3,
        "height": 104,
        "content": "\u2705 4. Error Handling\n\nWhen the process encounters an error, the **Slack** node notifies the team."
      },
      "typeVersion": 1
    },
    {
      "id": "b5cb6c9a-edc9-4aef-9750-e95985d80e34",
      "name": "Send Error 2",
      "type": "n8n-nodes-base.slack",
      "position": [
        544,
        224
      ],
      "parameters": {
        "text": "An error has occurred inside the Second BrowserAct node.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09LWT82KHN",
          "cachedResultName": "new_product_added"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b5d687e7-5781-4b29-b96e-a1cff88d6dea",
      "name": "Send Error",
      "type": "n8n-nodes-base.slack",
      "position": [
        1184,
        96
      ],
      "parameters": {
        "text": "Error Occur on Updating Or Creating Data",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09LWT82KHN",
          "cachedResultName": "new_product_added"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "d4812931-1bca-4892-9133-88c36e1558e5",
      "name": "Loop Over Suppliers",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -720,
        -96
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "703e314d-8e2a-4bec-90ee-76397090591e",
      "name": "Loop Over Products",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -64,
        -96
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "b6239845-f5f7-4bfa-9c69-89508b96793c",
      "name": "Send BrowserAct Error",
      "type": "n8n-nodes-base.slack",
      "position": [
        -288,
        80
      ],
      "parameters": {
        "text": "An error has occurred inside the first BrowserAct node.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09LWT82KHN",
          "cachedResultName": "new_product_added"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "e7b9c737-521c-4b52-bc41-7bb63b92a3eb",
      "name": "Check the Category",
      "type": "n8n-nodes-base.if",
      "position": [
        160,
        80
      ],
      "parameters": {
        "options": {
          "ignoreCase": true
        },
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "013b4904-dd59-4fe7-90c9-a1fbbd3cab83",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Loop Over Products').item.json.Category }}",
              "rightValue": "={{ $item(\"0\").$node[\"Get Suppliers & Links\"].json[\"Product Type\"] }}"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "59f6c99e-fffc-48d6-beb2-8c08c34d40e3",
      "name": "Check for Product availability",
      "type": "n8n-nodes-base.if",
      "position": [
        544,
        -144
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "657542ba-f1ec-43ef-be60-9c3600b0dd99",
              "operator": {
                "type": "object",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "fdbbae9a-fad8-4180-9e8b-b3a9013eace9",
      "name": "BrowserAct JSON Breakdown",
      "type": "n8n-nodes-base.code",
      "position": [
        -288,
        -96
      ],
      "parameters": {
        "jsCode": "// Get the JSON string using the exact path provided by the user.\nconst jsonString = $input.first().json.output.string;\n\nlet parsedData;\n\n// Check if the string exists before attempting to parse\nif (!jsonString) {\n    // Return an empty array or throw an error if no string is found\n    // Throwing an error is usually better to stop the workflow if data is missing.\n    throw new Error(\"Input string is empty or missing at the specified path: $input.first().json.output.string\");\n}\n\ntry {\n    // 1. Parse the JSON string into a JavaScript array of objects\n    parsedData = JSON.parse(jsonString);\n} catch (error) {\n    // Handle JSON parsing errors (e.g., if the string is malformed)\n    throw new Error(`Failed to parse JSON string: ${error.message}`);\n}\n\n// 2. Ensure the parsed data is an array\nif (!Array.isArray(parsedData)) {\n    throw new Error('Parsed data is not an array. It cannot be split into multiple items.');\n}\n\n// 3. Map the array of objects into the n8n item format { json: object }\n// Each element in this array will be treated as a new item by n8n, achieving the split.\nconst outputItems = parsedData.map(item => ({\n    json: item,\n}));\n\n// 4. Return the new array of items\nreturn outputItems;"
      },
      "typeVersion": 2
    },
    {
      "id": "68ac7520-266b-45d1-b4ef-888cde19c635",
      "name": "BrowserAct Json Breakdown",
      "type": "n8n-nodes-base.code",
      "position": [
        512,
        48
      ],
      "parameters": {
        "jsCode": "// Get the JSON string using the exact path provided by the user.\nconst jsonString = $input.first().json.output.string;\n\nlet parsedData;\n\n// Check if the string exists before attempting to parse\nif (!jsonString) {\n    // Return an empty array or throw an error if no string is found\n    // Throwing an error is usually better to stop the workflow if data is missing.\n    throw new Error(\"Input string is empty or missing at the specified path: $input.first().json.output.string\");\n}\n\ntry {\n    // 1. Parse the JSON string into a JavaScript array of objects\n    parsedData = JSON.parse(jsonString);\n} catch (error) {\n    // Handle JSON parsing errors (e.g., if the string is malformed)\n    throw new Error(`Failed to parse JSON string: ${error.message}`);\n}\n\n// 2. Ensure the parsed data is an array\nif (!Array.isArray(parsedData)) {\n    throw new Error('Parsed data is not an array. It cannot be split into multiple items.');\n}\n\n// 3. Map the array of objects into the n8n item format { json: object }\n// Each element in this array will be treated as a new item by n8n, achieving the split.\nconst outputItems = parsedData.map(item => ({\n    json: item,\n}));\n\n// 4. Return the new array of items\nreturn outputItems;"
      },
      "typeVersion": 2
    },
    {
      "id": "5b2bbcd8-551a-4ad5-bd8a-c8c9a08cd4f8",
      "name": "Create the HTML Data Table",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        688,
        48
      ],
      "parameters": {
        "text": "=input :  {{ $json.Product_Attributes }}\n\nsend data to ouput like this \n\n\"Output\": \"data\"\n",
        "options": {
          "systemMessage": "You are an AI assistant specialized in data transformation. Your task is to convert input text containing product specifications into a specific HTML `<table>` format. You must follow the instructions precisely to replicate the target HTML structure.\n\n**Task:**\nConvert the provided key-value text into an HTML table, matching the exact structure, tags, and CSS classes from the target specification.\n\n**Instructions:**\n\n1.  **Parse Input:** The input is a block of plain text with key-value pairs separated by a colon (`:`) and a newline.\n\n2.  **Generate Table:**\n\n      * Start with `<table id=\"product-attributes\" class=\"MuiTable-root mui-css-1ssfo\">`.\n      * Add a `<tbody class=\"MuiTableBody-root mui-css-1xnox0e\">`.\n\n3.  **Generate Rows (`<tr>`):**\n\n      * Create a `<tr class=\"MuiTableRow-root mui-css-c9pui3\">` for each of the attributes listed above, in that order.\n      * Each row must contain specific `<td>` cells as defined below.\n\n4.  **Generate Cells (`<td>`):**\n\n      * **Cell 1: Attribute Name (Key)**\n\n          * Wrap the key (e.g., \"Mfr\", \"Series\") in this structure:\n\n        <!-- end list -->\n\n        ```html\n        <td class=\"MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium tss-css-my7fuh-tableCellBold mui-css-4ro0k3\">\n        <div class=\"tss-css-8y8kah-tableCellBreak\">[ATTRIBUTE_NAME]</div></td>\n        ```\n\n      * **Cell 2: Attribute Value**\n\n          * Start with this structure:\n\n        <!-- end list -->\n\n        ```html\n        <td class=\"MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium tss-css-110lnqa-tableCell mui-css-4ro0k3\">\n        <div class=\"tss-css-1agxsdl-tableCellDescription\">\n        </div></td>\n        ```\n\n          * **Value Formatting (Content):**\n              * **For `Category`:** If the value contains a comma (`,`), split the value by the comma. Wrap each part in its own `<div>` and `<a>` tag like this (using `#` for `href`):\n                ```html\n                <div><a class=\"tss-css-yusyu7-anchor\" href=\"#\" rel=\"opener\">[Part 1]</a></div>\n                <div><a class=\"tss-css-yusyu7-anchor\" href=\"#\" rel=\"opener\">[Part 2]</a></div>\n                ```\n              * **For `Mfr`, `Series`, `Power (Watts)`, `Base Product Number`:** Wrap the value in an `<a>` tag like this (using `#` for `href`):\n                ```html\n                <a class=\"tss-css-yusyu7-anchor\" href=\"#\" rel=\"opener\" data-testid=\"product-attributes-link\">[VALUE]</a>\n                ```\n              * **For ALL OTHER attributes:** Wrap the value in a `<div>` tag like this:\n                ```html\n                <div class=\"tss-css-tsu9t4-packageName\">[VALUE]</div>\n                ```\n\n      * **Cell 3: Empty/Action Cell**\n\n          * **For the `Category` row:** Use this *exact* cell:\n            ```html\n            <td class=\"MuiTableCell-root MuiTableCell-body MuiTableCell-alignRight MuiTableCell-sizeMedium tss-css-my7fuh-tableCellBold print-hide mui-css-115xzy4\" data-testid=\"attributes-table-search-column\"><div class=\"MuiFormGroup-root tss-css-1kh0d0a-tableCellHeadDescription mui-css-1h7anqn\" role=\"radiogroup\"></div></td>\n            ```\n          * **For the `Base Product Number` row:** **DO NOT** add this third cell. This row only has two `<td>` cells.\n          * **For ALL OTHER rows:** Use this *exact* cell:\n            ```html\n            <td class=\"MuiTableCell-root MuiTableCell-body MuiTableCell-alignRight MuiTableCell-sizeMedium tss-css-1vs9p76-tableCellCheckBox print-hide mui-css-115xzy4\" data-testid=\"attributes-table-search-column\"><div class=\"tss-css-8y8kah-tableCellBreak\"><div></div></div></td>\n            ```\n\n5.  **Finalize:**\n\n      * Close the table with `</tbody>` and `</table>`.\n      * **Crucially: Only output the final HTML code.** \nDo not include any other text, explanations, or markdown formatting (like \\`\\`\\`html) around your response.\n\nremove any \"\\n\" before sending to output\n"
        },
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "fde001d3-f383-47ea-a38c-3f86ebb1a886",
      "name": "Get Suppliers & Links",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -928,
        -96
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1TeICFGUZisbOwkrOiDzObI2nW5smNErlmK5ncGER1wY/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1TeICFGUZisbOwkrOiDzObI2nW5smNErlmK5ncGER1wY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1TeICFGUZisbOwkrOiDzObI2nW5smNErlmK5ncGER1wY/edit?usp=drivesdk",
          "cachedResultName": "Product Suppliers"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "4733f40a-31cf-4065-85e4-b79b2336d974",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Loop Over Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Error": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Create a product": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ],
        [
          {
            "node": "Send Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update a product": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many products": {
      "main": [
        [
          {
            "node": "Check for Product availability",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check the Category": {
      "main": [
        [
          {
            "node": "Add Missing Product",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Products": {
      "main": [
        [
          {
            "node": "Loop Over Suppliers",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get many products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Missing Product": {
      "main": [
        [
          {
            "node": "BrowserAct Json Breakdown",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Error 2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Suppliers": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get Product Stock Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Suppliers & Links": {
      "main": [
        [
          {
            "node": "Loop Over Suppliers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Product Stock Data": {
      "main": [
        [
          {
            "node": "BrowserAct JSON Breakdown",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send BrowserAct Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Create the HTML Data Table",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "BrowserAct JSON Breakdown": {
      "main": [
        [
          {
            "node": "Loop Over Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "BrowserAct Json Breakdown": {
      "main": [
        [
          {
            "node": "Create the HTML Data Table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create the HTML Data Table": {
      "main": [
        [
          {
            "node": "Create a product",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for Product availability": {
      "main": [
        [
          {
            "node": "Update a product",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Check the Category",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Get Suppliers & Links",
            "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

This workflow is essential for e-commerce operators, dropshippers, and inventory managers who need to ensure their product pricing and stock levels are synchronized with multiple third-party suppliers, minimizing overselling and maximizing profit.

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

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

This workflow is ideal for venture capitalists, sales teams, or market researchers who need to automatically track and compile lists of recently funded companies.

Agent, Google Sheets, Output Parser Structured +3
AI & RAG

This workflow is essential for product managers, marketing teams, and founders who need to quickly gather and distill actionable insights from competitor launches to inform their own product strategy

N8N Nodes Browseract Workflows, Agent, Output Parser Structured +3
AI & RAG

CV → Match → Screen → Decide, all automated

HTTP Request, Information Extractor, Google Sheets +7
AI & RAG

Never miss a competitor price change again.

@Decodo/N8N Nodes Decodo, Google Gemini Chat, Output Parser Structured +3
AI & RAG

This workflow automates the process of synchronizing your Shopify catalog to WooCommerce, enriching product data along the way. It uses AI to identify the best external sources (like Amazon or G2) for

Google Gemini Chat, Agent, Output Parser Structured +4