WP Manifestindependent plugin directory
manifest / ai / woocommerce-ai-product-writer

WooCommerce AI Product Writer

Generate WooCommerce product descriptions using Claude or OpenAI directly from the product editor.

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/gonzaloccastro/woocommerce-ai-product-writer/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Built as a hands-on project while completing Anthropic's "Building with Claude API" course.

A WordPress plugin that generates WooCommerce product descriptions using Claude (Anthropic) or OpenAI directly from the product editor — no copy-pasting between tabs, no external tools.


The problem

Writing product descriptions is one of the biggest time sinks in WooCommerce catalog management. Existing AI writing tools require leaving WordPress, context-switching to a separate app, and manually copying the result back. I built this to eliminate that friction.

What it does

A metabox on the WooCommerce product editor reads the product name and category, sends them to a configured AI provider, and inserts the generated description directly into the TinyMCE editor in one click.


What I learned building this

This project was the practical application of Anthropic's "Building with Claude API" course. Here are the specific things I had to understand to make it work:

The Messages API structure. Claude uses a messages array where each turn has a role and content. For a single-turn task like this, you send one user message and read content[0].text from the response. The equivalent in OpenAI is choices[0].message.content — structurally similar, different envelope.

The anthropic-version header. Unlike OpenAI, Anthropic requires a version header on every request (anthropic-version: 2023-06-01). Without it, the API rejects the request. This is Anthropic's way of ensuring API contracts don't break when they evolve the API.

Token economics. Every request has input tokens (the prompt you send) and output tokens (what Claude returns). For a task like this — ~100 token prompt, ~60 token output — Claude Haiku costs around $0.0005 per generation. Knowing this lets you make model choices deliberately rather than guessing.

Provider abstraction. The most important architectural decision was isolating all provider-specific logic in class-ai-client.php. The AJAX handler never knows which API is being called. If a client wants to switch from Claude to OpenAI, it's one dropdown change in Settings — no code changes. This is what the course means by "provider-agnostic design."

API key security in WordPress. The course covers key handling in general; adapting it to WordPress required learning about autoload=false in wp_options — ensuring the API key is never loaded in memory on regular page requests, only when a generation is triggered.


Features

  • Claude-first, provider-agnostic — defaults to Claude Haiku, also supports OpenAI GPT-4o mini
  • Writing tone — Formal, Conversational, or Technical, applied per prompt
  • Direct editor insertion — inserts into TinyMCE or plain-text editor, whichever is active
  • No Composer required — upload the folder and activate
  • WordPress security standards — nonces, capability checks, sanitization, escaping throughout
  • Translation-ready — all strings wrapped in __() / _e()

How the API call works

No SDK, no Python, no intermediary — just a direct HTTP POST from PHP:

// This is the complete Claude API integration
$response = wp_remote_post(
    'https://api.anthropic.com/v1/messages',
    [
        'headers' => [
            'Content-Type'      => 'application/json',
            'x-api-key'         => $this->api_key,
            'anthropic-version' => '2023-06-01',    // required — OpenAI doesn't have this
        ],
        'body' => wp_json_encode([
            'model'      => 'claude-haiku-4-5-20251001',
            'max_tokens' => 300,
            'messages'   => [
                ['role' => 'user', 'content' => $prompt]
            ],
        ]),
    ]
);

// Claude's response envelope: content[0].text
$description = trim( $body['content'][0]['text'] );

The API is language-agnostic. What Anthropic's Python SDK does internally is the same thing — build this request and parse this response. PHP can do it natively.


Architecture decisions

Why a separate class-ai-client.php? The AJAX handler's job is security and routing: verify nonce, check capability, sanitize input, return JSON. It shouldn't know that Claude's response envelope is content[0].text while OpenAI's is choices[0].message.content. That's the client's responsibility. Adding a third provider means adding one case in the client — nothing else changes.

Why autoload=false for the API key? WordPress autoloads options by default — meaning they're fetched on every request and held in memory. An API key only needs to exist during an AJAX generation call. Storing it with autoload=false ensures it's never in memory on front-end page loads or unrelated admin screens.

Why check_ajax_referer() AND current_user_can()? A nonce proves the request came from your form. A capability check proves the user can do this action. A logged-in subscriber could craft a POST with a valid nonce — the capability check (edit_products) is what stops them.

Why wp_remote_post() instead of curl? WordPress's HTTP API respects server proxy and SSL configurations, returns WP_Error on failure (not false), and has a 30-second timeout — intentional, since AI APIs can be slow on first token.


File structure

woocommerce-ai-product-writer/
├── woocommerce-ai-product-writer.php  # Plugin headers, constants, boot
├── uninstall.php                      # Cleans options on deletion
├── includes/
│   ├── class-core.php                 # Singleton orchestrator
│   ├── class-settings.php             # Settings page, option getters
│   ├── class-metabox.php              # Metabox registration, asset enqueue
│   └── class-ajax-handler.php         # AJAX security, routing, response
├── api/
│   └── class-ai-client.php            # Provider abstraction (Claude / OpenAI)
├── admin/
│   ├── views/settings-page.php
│   ├── css/metabox.css
│   └── js/metabox.js
└── languages/
    └── woocommerce-ai-product-writer.pot

Requirements

  • WordPress 6.0+
  • WooCommerce 7.0+
  • PHP 7.4+
  • An API key from Anthropic or OpenAI

Installation

  1. Download or clone this repository.
  2. Upload the woocommerce-ai-product-writer folder to /wp-content/plugins/.
  3. Activate from Plugins > Installed Plugins.
  4. Go to WooCommerce > AI Product Writer.
  5. Select your provider, paste your API key, choose a tone, and save.
  6. Open any product — the AI Product Writer metabox appears in the right column.

Security

  • All AJAX requests verified with check_ajax_referer() + current_user_can('edit_products')
  • API key stored with autoload=false, never logged, never rendered in the DOM
  • All $_POST inputs sanitized with sanitize_text_field( wp_unslash() )
  • All HTML output escaped at point of echo (esc_html, esc_attr, esc_url)
  • defined('ABSPATH') || exit at the top of every PHP file
  • Clean uninstall: all options removed when the plugin is deleted

Extending

Add a new provider: add the slug to WCAPW_Settings::VALID_PROVIDERS, add a radio label in render_field_provider(), and add a case + private method in WCAPW_AI_Client.

Change the prompt: edit WCAPW_AI_Client::build_prompt() — isolated from all HTTP logic.


This plugin is part of a portfolio of WordPress + AI integrations built to demonstrate real-world application of the Claude API in a WordPress/WooCommerce context. See also:


License

GPL v2 or later — see LICENSE.


Gonzalo Castro — WordPress & WooCommerce developer, Buenos Aires. Working with agencies in Canada and LATAM since 2020.

LinkedIn · GitHub