AutomationFlowsAI & RAG › E-commerce Product Fine-tuning with Bright Data and Openai

E-commerce Product Fine-tuning with Bright Data and Openai

ByDaniel Shashko @tomax on n8n.io

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Event trigger★★★★☆ complexityAI-powered9 nodes@Brightdata/N8N Nodes BrightdataOpenAIHTTP RequestChat TriggerAgentOpenAI Chat
AI & RAG Trigger: Event Nodes: 9 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Chat Trigger 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "93bc29f2-3004-4daa-8def-89cf9b4ad46a",
      "name": "When clicking 'Execute workflow'",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "8a6e68ec-ff87-4c6b-b629-34021258a582",
      "name": "BrightData",
      "type": "@brightdata/n8n-nodes-brightdata.brightData",
      "position": [
        220,
        0
      ],
      "parameters": {
        "urls": "[\n  {\"url\":\"https://www.amazon.com/AmazonBasics-Multipurpose-Copy-Printer-Paper/dp/B01FV0F8H8/ref=zg_bs_g_office-products_d_sccl_1/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Scotch-Shipping-Packaging-Dispenser-142-6/dp/B000J07BRQ/ref=zg_bs_g_office-products_d_sccl_2/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Amazon-Basics-Premium-Colored-Multicolor/dp/B07D93R5HV/ref=zg_bs_g_office-products_d_sccl_3/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/HP-Cartridge-Black-3YM57AN-Tri-Color/dp/B08412PTS8/ref=zg_bs_g_office-products_d_sccl_4/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/HP-Printer-Paper-Print20-200060R/dp/B001AFL8GY/ref=zg_bs_g_office-products_d_sccl_5/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Scotch-Shipping-Packaging-Dispenser-142L/dp/B000MVV6AA/ref=zg_bs_g_office-products_d_sccl_6/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Amazon-Basics-50-Sheet-Legal-Inches/dp/B00QSR9URI/ref=zg_bs_g_office-products_d_sccl_7/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Sharpie-Permanent-Markers-Resistant-Coloring/dp/B00006IFHD/ref=zg_bs_g_office-products_d_sccl_8/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/AmazonBasics-Thermal-Laminating-Plastic-Laminator/dp/B079KL4C91/ref=zg_bs_g_office-products_d_sccl_9/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/YSAGi-Leather-Protector-Non-Slip-Waterproof/dp/B0BMTPC44X/ref=zg_bs_g_office-products_d_sccl_10/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/EZlifego-Multipurpose-Removable-Transparent-Household/dp/B07VNSXY31/ref=zg_bs_g_office-products_d_sccl_11/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/BIC-Highlighter-Chisel-Assorted-5-Count/dp/B000Q5ZGIA/ref=zg_bs_g_office-products_d_sccl_12/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Academic-Planner-2025-2026-Monthly-Calendar/dp/B0DXPSZDP9/ref=zg_bs_g_office-products_d_sccl_22/142-6608713-4877828?psc=1\"}\n]\n",
        "resource": "webScrapper",
        "dataset_id": {
          "__rl": true,
          "mode": "list",
          "value": "gd_l1vijixj9g2vp7563",
          "cachedResultName": "Amazon best seller products"
        },
        "requestOptions": {}
      },
      "credentials": {
        "brightdataApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7a817929-aa8a-4813-9fd0-e778c46ad173",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        440,
        0
      ],
      "parameters": {
        "jsCode": "// get all incoming items\nconst allInputItems = $input.all(); \n\nlet jsonlString = \"\";\n// define the training prompt\nconst systemMessage = \"You are an expert marketing assistant specializing in writing compelling and informative product descriptions.\";\n\n// loop through each item retrieved from the input\nfor (const item of allInputItems) {\n  const product = item.json; \n\n  // validate if the product data exists and is an object\n  if (!product || typeof product !== 'object') {\n    console.warn('Skipping an item because product data is missing or not an object:', item);\n    continue;\n  }\n\n  // extract product data\n  const title = product.title || \"N/A\";\n  const brand = product.brand || \"N/A\";\n  let featuresString = \"Not specified\";\n  if (product.features && Array.isArray(product.features) && product.features.length > 0) {\n    featuresString = product.features.slice(0, 5).join(', '); \n  }\n  // create a snippet of the original product description for training\n  const originalDescSnippet = (product.description || \"No original description available.\").substring(0, 250) + \"...\";\n  // create prompt with specific details about the product\n  const userPrompt = `Generate a product description for the following item. Title: ${title}. Brand: ${brand}. Key Features: ${featuresString}. Original Description Snippet: ${originalDescSnippet}.`;\n\n  // create template for the kind of description the AI should generate\n  let idealDescription = `Discover the ${title} from ${brand}, a top-choice for discerning customers. `;\n  idealDescription += `Key highlights include: ${featuresString}. `;\n  if (product.rating) {\n    idealDescription += `Boasting an impressive customer rating of ${product.rating} out of 5 stars! `;\n  }\n  idealDescription += `This product, originally described as \"${originalDescSnippet}\", is perfect for anyone seeking quality and reliability. `;\n  idealDescription += `Don't miss out on the ${product.availability === \"In Stock\" ? \"readily available\" : \"upcoming\"} ${title} \u2013 enhance your collection today!`;\n\n  // create a training example object in the format expected by OpenAI\n  const trainingExample = {\n    messages: [\n      { role: \"system\", content: systemMessage },\n      { role: \"user\", content: userPrompt },\n      { role: \"assistant\", content: idealDescription }\n    ]\n  };\n  jsonlString += JSON.stringify(trainingExample) + \"\\n\";\n}\n\n// remove any leading or trailing whitespace\nconst fileContentString = jsonlString.trim();\n\n// check if any product data was actually processed\nif (fileContentString.length === 0) {\n  console.warn(\"No product data was processed, outputting empty file content.\");\n  return [{ \n    json: { error: \"No products processed\", fileNameToUse: \"data.jsonl\" },\n    binary: {} \n  }];\n}\n\n// convert the final JSONL string into a Buffer (raw binary data)\nconst buffer = Buffer.from(fileContentString, 'utf-8');\n// define the filename that will be used when this data is sent to OpenAI\nconst actualFileNameForOpenAI = \"data.jsonl\";\n// define the MIME type for the file\nconst mimeType = 'application/jsonl'; \n\n// prepare the binary data for output\nconst binaryData = await this.helpers.prepareBinaryData(buffer, actualFileNameForOpenAI, mimeType);\n\n// return the processed data\nreturn [{\n  json: {\n    processedFileName: actualFileNameForOpenAI \n  },\n  binary: {\n    // the \"Input Data Field Name\" in the OpenAI node\n    \"data.jsonl\": binaryData \n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "9e8f8656-79c5-4d8a-8e27-f07907ba852e",
      "name": "OpenAI",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        660,
        0
      ],
      "parameters": {
        "options": {
          "purpose": "fine-tune"
        },
        "resource": "file",
        "binaryPropertyName": "data.jsonl"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "f391f934-1804-41ad-9ad5-303c613999b6",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        840,
        0
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/fine_tuning/jobs",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"training_file\": \"{{ $json.id }}\",\n  \"model\": \"gpt-4o-mini-2024-07-18\"\n} ",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "openAiApi"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "add8279c-fdaf-4e6c-9b6b-242a85295cf5",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        0,
        200
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "72c8af8d-45e0-4ae8-b10b-723e8bf1f61c",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        220,
        200
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "392b85ba-0ded-4838-ba17-df858e7f922d",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        260,
        420
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_FINE_TUNED_MODEL_ID"
        },
        "options": {
          "responseFormat": "text"
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "cab8fbc8-5cff-4b14-a36d-d7d89a83cf6e",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -380,
        -480
      ],
      "parameters": {
        "width": 280,
        "height": 1080,
        "content": "This n8n workflow automates scraping Amazon product data and uses it for fine-tuning a custom OpenAI model for marketing copy.\n\n## Steps Overview\n\n1. **Manual Trigger:**  \n   The workflow starts when you click \"Execute workflow\" in n8n.\n\n2. **Bright Data Node:**  \n   Scrapes product data from a list of Amazon URLs using Bright Data's web scraper integration.\n\n3. **Code Node:**  \n   Processes the scraped product data:\n   - Generates training examples (system prompt, user prompt, assistant response) for each product.\n   - Aggregates these examples into a `.jsonl` file formatted for OpenAI fine-tuning.\n\n4. **OpenAI File Upload Node:**  \n   Uploads the `.jsonl` training file to OpenAI, declaring it for use in fine-tuning.\n\n5. **HTTP Request Node:**  \n   Starts a fine-tuning job for an OpenAI GPT model using the uploaded file.\n\n6. **Chat/Agent Subworkflow:**  \n   Contains a chat trigger and an AI agent. This uses the newly fine-tuned OpenAI model to generate product descriptions or marketing content via chat.\n\n---\n\n**Important:**  \nYou must replace the placeholder API credentials and IDs in the workflow (Bright Data API, OpenAI API, and the fine-tuned model ID in the agent node) with your own valid keys and model identifiers for the workflow to function correctly.\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Code": {
      "main": [
        [
          {
            "node": "OpenAI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "BrightData": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking 'Execute workflow'": {
      "main": [
        [
          {
            "node": "BrightData",
            "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 contains community nodes that are only compatible with the self-hosted version of n8n.

Source: https://n8n.io/workflows/5199/ — 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

Fine-tuning with OpenAI models. Uses manualTrigger, googleDrive, agent, chatTrigger. Event-driven trigger; 9 nodes.

Google Drive, Agent, Chat Trigger +3
AI & RAG

Fine-tuning with OpenAI models. Uses manualTrigger, googleDrive, agent, chatTrigger. Event-driven trigger; 9 nodes.

Google Drive, Agent, Chat Trigger +3
AI & RAG

This n8n workflow automates fine-tuning OpenAI models through these key steps: Manual Trigger: Starts with the "When clicking ‘Test workflow’" event to initiate the process. Downloads a file from Goog

Google Drive, Agent, Chat Trigger +3
AI & RAG

🎯 Create viral TikToks, Shorts, Reels, podcasts, and ASMR videos in minutes — all on autopilot.

OpenAI, HTTP Request, Form Trigger +7
AI & RAG

Generate AI viral videos with NanoBanana & VEO3, shared on socials via Blotato 2. Uses @blotato/n8n-nodes-blotato, googleSheets, lmChatOpenAi, toolThink. Event-driven trigger; 94 nodes.

@Blotato/N8N Nodes Blotato, Google Sheets, OpenAI Chat +9