Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

14 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SecondSell β€” AI-Powered Second-Hand Product Uploader for WooCommerce

A mobile-first web app that lets you photograph second-hand products, generate complete WooCommerce listings with Claude AI, and publish them in seconds β€” without touching the slow WordPress admin.


Screenshot

SecondSell running on Android Chrome

Running on Android Chrome. The app lives entirely inside the browser β€” no native install required.


How It Works

πŸ“± Camera / gallery
      β”‚
      β–Ό
Sharp β€” detect orientation
  Portrait  β†’ 9:16 β†’ 720Γ—1280
  Landscape β†’ 16:9 β†’ 1280Γ—720    (smart attention crop, WebP q80)
  Square    β†’ 1:1  β†’ 1080Γ—1080
      β”‚
      β–Ό
WP REST API ──────────────────► WordPress Media Library
/wp-json/wp/v2/media             (real attachment ID returned)
      β”‚
      β–Ό
Claude claude-sonnet-4-6 ──────► Full product listing
researches specs + user notes     title / descriptions / SKU / tags / price
+ analyses uploaded photos
      β”‚
      β–Ό
User reviews & edits
      β”‚
      β–Ό
WC REST API ───────────────────► WooCommerce product (live instantly)
/wp-json/wc/v3/products          handles all DB writes + cache + hooks

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                SecondSell App (Railway)                 β”‚
β”‚                                                         β”‚
β”‚  POST /api/auth/login   β†’ cookie-based session auth     β”‚
β”‚  POST /api/upload       β†’ Sharp + WP REST API           β”‚
β”‚  POST /api/ai/describe  β†’ Claude claude-sonnet-4-6      β”‚
β”‚  GET  /api/products/categories β†’ WC REST API            β”‚
β”‚  POST /api/products     β†’ WC REST API                   β”‚
β”‚  GET  /api/health       β†’ WP/WC reachability check      β”‚
β”‚                                                         β”‚
β”‚  public/  (vanilla JS, mobile-first, no bundler)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚ WP/WC REST API
           β–Ό
   WordPress + WooCommerce
   (images + products)

Prerequisites

Requirement Notes
WordPress 5.6+ Application Passwords feature
WooCommerce 3.7+ wp_wc_product_meta_lookup table
HTTPS on WordPress Required for Application Passwords
Anthropic API key console.anthropic.com

Setup

1. Install

git clone <repo> && cd secondsell
npm install

2. WordPress Application Password

  1. WP Admin β†’ Users β†’ Edit your profile
  2. Scroll to Application Passwords
  3. Name: SecondSell β†’ Add New Application Password
  4. Copy the generated password β€” it's shown once

3. WooCommerce REST API Key

  1. WP Admin β†’ WooCommerce β†’ Settings β†’ Advanced β†’ REST API
  2. Add key β€” Description: SecondSell, User: admin, Permissions: Read/Write
  3. Copy the Consumer Key and Consumer Secret

4. Environment variables

cp .env.example .env
WP_URL=https://your-wordpress-site.com
WP_USER=your-wp-username
WP_APP_PASSWORD="xxxx xxxx xxxx xxxx xxxx xxxx"

WC_CONSUMER_KEY=ck_...
WC_CONSUMER_SECRET=cs_...

BASIC_AUTH_USER=admin
BASIC_AUTH_PASS="your-app-password"

ANTHROPIC_API_KEY=sk-ant-...

Note: If your password contains #, !, or other shell-special characters, wrap it in double quotes in .env.

5. Run locally

npm run dev
# β†’ http://localhost:3000

For camera access on iOS/Android, use HTTPS (e.g. ngrok) β€” browsers require HTTPS for getUserMedia.


Deploy to Railway

  1. Push to GitHub
  2. Railway β†’ New Project β†’ Deploy from GitHub repo
  3. Set all env vars in Railway β†’ Service β†’ Variables

No Railway Volume needed β€” images live in WordPress's own media library.


Repository Layout

/
β”œβ”€β”€ images/                    ← screenshots and documentation assets (committed to git)
β”œβ”€β”€ public/                    ← frontend (vanilla JS, mobile-first, no bundler)
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ login.html
β”‚   β”œβ”€β”€ css/style.css
β”‚   └── js/app.js
β”œβ”€β”€ routes/                    ← Express route handlers
β”‚   β”œβ”€β”€ upload.js              ← Sharp pipeline + optional background removal
β”‚   β”œβ”€β”€ ai.js                  ← Claude claude-sonnet-4-6
β”‚   β”œβ”€β”€ products.js            ← WooCommerce product/category API
β”‚   β”œβ”€β”€ auth.js                ← Login / logout
β”‚   └── health.js              ← WP/WC reachability check
β”œβ”€β”€ middleware/auth.js          ← HMAC-SHA256 cookie session guard
β”œβ”€β”€ utils/wcApi.js             ← WP + WC REST API client
β”œβ”€β”€ server.js                  ← Express app entry point
└── .env.example               ← environment variable template

Image Processing

Input orientation Detected by Cropped to Output
Portrait (tall) ratio < 0.80 9:16 720 Γ— 1280 WebP
Landscape (wide) ratio > 1.25 16:9 1280 Γ— 720 WebP
Square / near-sq 0.80 – 1.25 1:1 1080 Γ— 1080 WebP
  • Crop strategy: sharp.strategy.attention β€” analyses saliency and entropy to keep the focal point centred.
  • Never upscaled: small images stay small.
  • EXIF rotation applied before any resize.
  • WebP quality 80 β€” typically 40–120 KB per image.

API Reference

POST /api/auth/login

{ "username": "admin", "password": "secret" }

Sets ss_session cookie on success.


GET /api/products/categories

Returns live WooCommerce categories:

{ "success": true, "categories": [{ "id": 15, "name": "Electronics", "count": 8 }] }

POST /api/upload

Optimise + upload images to WordPress media library.

Request: multipart/form-data, field images, up to 10 files.

Response:

{
  "images": [
    {
      "id": 247,
      "url": "https://site.com/wp-content/uploads/2026/03/uuid.webp",
      "width": 720,
      "height": 1280,
      "orientation": "portrait",
      "aspect": "9:16",
      "sizeKb": 68
    }
  ]
}

POST /api/ai/describe

Generate a product listing with Claude. Passes uploaded image URLs as vision content.

Request:

{
  "productName": "Sony WH-1000XM4",
  "condition": "good",
  "userContext": "Includes case and USB-C cable",
  "imageUrls": ["https://..."]
}

condition: new | like_new | good | fair | poor


POST /api/products

Create a WooCommerce product via REST API.

Request:

{
  "title": "Sony WH-1000XM4 Wireless Headphones",
  "shortDescription": "Industry-leading ANC, 30h battery.",
  "fullDescription": "<h3>Overview</h3><p>…</p>",
  "price": "185.00",
  "sku": "SH-SONY-WH1000XM4-001",
  "quantity": 1,
  "categoryId": 15,
  "images": [{ "id": 247, "url": "https://…" }],
  "tags": ["sony", "headphones"]
}

GET /api/health

{
  "status": "ok",
  "wpUrl": "https://site.com",
  "wpApi": "reachable",
  "wcApi": "configured",
  "claude": "configured"
}

Troubleshooting

Symptom Cause Fix
Login fails # in password not quoted Wrap BASIC_AUTH_PASS in double quotes in .env
Upload 401 Wrong WP_USER / WP_APP_PASSWORD Regenerate WordPress Application Password
Upload 403 REST API blocked by security plugin Wordfence β†’ allow REST API; re-save Permalinks
Product 401 Wrong consumer key/secret Regenerate WC API key with Read/Write
Product 403 Key is Read-only Edit key β†’ set Permissions to Read/Write
AI fails Wrong/truncated API key Copy full key from console.anthropic.com
Wrong crop EXIF not applied Sharp .rotate() is called first β€” should be handled

Project Structure

β”œβ”€β”€ server.js
β”œβ”€β”€ middleware/auth.js           HMAC-SHA256 cookie session
β”œβ”€β”€ routes/
β”‚   β”œβ”€β”€ auth.js                 Login / logout
β”‚   β”œβ”€β”€ upload.js               Sharp optimise β†’ WP media
β”‚   β”œβ”€β”€ ai.js                   Claude description + vision
β”‚   β”œβ”€β”€ products.js             WC categories + product creation
β”‚   └── health.js               System status
β”œβ”€β”€ utils/
β”‚   └── wcApi.js                WP + WC REST API client
β”œβ”€β”€ public/
β”‚   β”œβ”€β”€ index.html              4-step mobile UI
β”‚   β”œβ”€β”€ login.html              Login page
β”‚   β”œβ”€β”€ css/style.css           Mobile-first glassmorphism styles
β”‚   └── js/app.js               Vanilla JS
β”œβ”€β”€ specs/                      Feature specifications
β”œβ”€β”€ CLAUDE.md                   AI coding guide
β”œβ”€β”€ CONSTITUTION.md             Project rules
└── .env.example

Security

  • All credentials in environment variables β€” never in source code
  • Cookie session uses HMAC-SHA256 β€” no plaintext tokens
  • WP Application Password is scoped and revocable
  • WC API key is scoped to Read/Write products only
  • Multer enforces image/* type and 30 MB size limit
  • Sharp processes all uploads in memory β€” raw bytes never written to disk
  • API responses never include stack traces

Developer

Eduardo Arana & Soda [bot]


License

MIT

About

A mobile-first web app that lets you photograph second-hand products, generate complete WooCommerce

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages