AINode.jsAutomation

Product Image Analyzer for E-commerce

TT
TopicTrick Team
Product Image Analyzer for E-commerce

Product Image Analyzer for E-commerce

Adding products to an online store manually is slow. Upload a product photo and this tool generates the complete listing — title, description, bullet points, tags, category, and attributes — ready to publish to Shopify or WooCommerce.

This is Tool 18 of the Build 50 AI Automation Tools course.


What You'll Build

  • POST /analyze — upload product image(s), receive complete listing data
  • Extracts attributes, generates title and description
  • POST /analyze/bulk — process entire product catalog folders

Setup

bash
mkdir product-analyzer && cd product-analyzer
npm init -y
npm install express multer openai dotenv
bash
# .env
OPENAI_API_KEY=sk-your-key-here
PORT=3000

Product Analysis Service

js
// src/services/productService.js
import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

export async function analyzeProductImages(imageBuffers, mimetypes, brandVoice = '') {
  const voiceNote = brandVoice
    ? `Brand voice: ${brandVoice}`
    : 'Use clear, benefit-focused e-commerce product copy.';

  const imageContents = imageBuffers.map((buf, i) => ({
    type: 'image_url',
    image_url: {
      url: `data:${mimetypes[i]};base64,${buf.toString('base64')}`,
      detail: 'high',
    },
  }));

  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      {
        role: 'system',
        content: `You are an expert e-commerce product catalog specialist. ${voiceNote}
Analyze the product image(s) and generate a complete product listing.
Return ONLY a JSON object — no markdown:
{
  "productTitle": "SEO-optimised product title (60-80 chars)",
  "category": "suggested category path (e.g. 'Clothing > Women > Dresses')",
  "shortDescription": "2-3 sentence product description for product cards",
  "longDescription": "150-200 word detailed product description for the product page",
  "bulletPoints": ["5-7 key feature/benefit bullet points"],
  "attributes": {
    "color": ["all visible colors"],
    "material": "string or null",
    "pattern": "string or null",
    "style": "string or null",
    "targetGender": "men | women | unisex | kids | null",
    "ageGroup": "adult | teen | child | null",
    "occasion": ["suitable occasions"],
    "care": "string or null — care instructions if visible"
  },
  "tags": ["15-20 relevant search tags and keywords"],
  "seoMetaTitle": "60-char SEO title",
  "seoMetaDescription": "155-char SEO meta description",
  "suggestedPrice": {
    "currency": "USD",
    "low": number,
    "high": number,
    "rationale": "string"
  },
  "condition": "new | used | refurbished",
  "confidenceScore": 0.0-1.0
}`,
      },
      {
        role: 'user',
        content: [
          { type: 'text', text: 'Analyze this product and generate a complete listing:' },
          ...imageContents,
        ],
      },
    ],
    temperature: 0.3,
    response_format: { type: 'json_object' },
  });

  return JSON.parse(response.choices[0].message.content);
}

API Routes + Server

js
// src/server.js
import 'dotenv/config';
import express from 'express';
import multer from 'multer';
import { analyzeProductImages } from './services/productService.js';

const app = express();
app.use(express.json());
const upload = multer({
  storage: multer.memoryStorage(),
  limits: { fileSize: 20 * 1024 * 1024 },
  fileFilter: (_req, file, cb) => {
    ['image/jpeg', 'image/png', 'image/webp'].includes(file.mimetype)
      ? cb(null, true)
      : cb(new Error('Images only'));
  },
});

// Single product (up to 5 images for different angles)
app.post('/analyze', upload.array('images', 5), async (req, res, next) => {
  try {
    if (!req.files?.length) return res.status(400).json({ error: 'At least one image required' });
    const buffers = req.files.map(f => f.buffer);
    const mimetypes = req.files.map(f => f.mimetype);
    const result = await analyzeProductImages(buffers, mimetypes, req.body.brandVoice);
    res.json({ success: true, imageCount: req.files.length, listing: result });
  } catch (err) { next(err); }
});

app.get('/health', (_req, res) => res.json({ status: 'ok' }));
app.use((err, _req, res, _next) => res.status(500).json({ error: err.message }));
app.listen(process.env.PORT ?? 3000, () => console.log('Product Analyzer running'));

Testing

bash
# Analyze a product with multiple angles
curl -X POST http://localhost:3000/analyze \
  -F "images=@product-front.jpg" \
  -F "images=@product-back.jpg" \
  -F "images=@product-detail.jpg" \
  -F "brandVoice=casual and eco-conscious, targeting millennials"

Sample response:

json
{
  "listing": {
    "productTitle": "Men's Organic Cotton Slim-Fit Chinos — Navy Blue",
    "category": "Clothing > Men > Pants > Chinos",
    "shortDescription": "Classic slim-fit chinos made from 100% GOTS-certified organic cotton. Tailored for all-day comfort with a modern, versatile silhouette.",
    "bulletPoints": [
      "100% GOTS-certified organic cotton — better for you and the planet",
      "Slim-fit cut with room to move — not restrictive",
      "Pre-washed for softness and reduced shrinkage",
      "YKK zipper and reinforced bartack stitching for durability",
      "Versatile navy: dressed up with a blazer, down with a t-shirt",
      "Machine washable at 30°C — easy care"
    ],
    "attributes": {
      "color": ["navy blue"],
      "material": "100% organic cotton",
      "style": "slim-fit chinos",
      "targetGender": "men",
      "occasion": ["casual", "smart-casual", "business-casual"]
    },
    "tags": ["mens chinos", "organic cotton pants", "slim fit trousers", "navy chinos", "sustainable menswear"],
    "suggestedPrice": { "currency": "USD", "low": 55, "high": 75, "rationale": "Organic cotton premium + quality construction" },
    "confidenceScore": 0.91
  }
}

Shopify Auto-Create Integration

js
async function createShopifyProduct(listing, imageUrl, shopifyStore, accessToken) {
  const product = {
    title: listing.productTitle,
    body_html: `<p>${listing.longDescription}</p><ul>${listing.bulletPoints.map(b => `<li>${b}</li>`).join('')}</ul>`,
    product_type: listing.category.split(' > ')[0],
    tags: listing.tags.join(', '),
    images: [{ src: imageUrl }],
    metafields: [
      { namespace: 'seo', key: 'title', value: listing.seoMetaTitle, type: 'single_line_text_field' },
      { namespace: 'seo', key: 'description', value: listing.seoMetaDescription, type: 'single_line_text_field' },
    ],
  };

  const response = await fetch(`https://${shopifyStore}/admin/api/2024-01/products.json`, {
    method: 'POST',
    headers: { 'X-Shopify-Access-Token': accessToken, 'Content-Type': 'application/json' },
    body: JSON.stringify({ product }),
  });

  return response.json();
}

Build 50 AI Automation Tools — Tool 18 of 50

Product image analysis is live. Continue to Tool 19 to build a receipt scanner and expense tracker.


    Summary

    • Sending multiple product angle images in one API call gives GPT-4o the context to generate far more accurate listings
    • The confidenceScore field lets you filter listings that need human review before publishing
    • Shopify/WooCommerce API integration closes the loop from image upload to live product listing
    • The suggestedPrice field provides a market positioning estimate based on visible product quality
    • Batch the bulk endpoint with a folder watch to process new product photos automatically overnight

    Continue to Tool 19: Receipt Scanner & Expense Tracker →