AINode.jsAutomation
Product Image Analyzer for E-commerce
TT
TopicTrick Team
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 dotenvbash
# .env
OPENAI_API_KEY=sk-your-key-here
PORT=3000Product 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 →
