2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00
2026-01-25 08:57:55 +01:00

SEO Optimizer for WordPress

Production-ready Go application that automatically optimizes WordPress blog posts for SEO using Claude AI.

Features

  • Autonomous Optimization: Automatically selects and optimizes old blog posts
  • Budget-Conscious: Single comprehensive Claude API call per post (~€0.05/post)
  • Multi-Language Support: Alternates between English and Spanish (Polylang)
  • Comprehensive SEO: Meta tags, content improvements, internal linking, FAQ blocks
  • Draft Revisions: Creates draft revisions for human approval (never auto-publishes)
  • Smart Selection: Respects cooldown periods and content quality criteria
  • REST API: Manual triggers and status monitoring
  • Production-Ready: Docker, Kubernetes, graceful shutdown, structured logging

Architecture

┌─────────────────┐
│   Scheduler     │  Language rotation (EN → ES)
│  (2.5h cycle)   │
└────────┬────────┘
         │
         v
┌─────────────────┐
│  Post Selector  │  Select oldest posts (120+ days)
└────────┬────────┘  Content >= 500 words
         │           Cooldown: 90 days
         v
┌─────────────────┐
│  Claude AI      │  Single comprehensive prompt
│  (Sonnet 4.5)   │  - SEO meta optimization
└────────┬────────┘  - Content improvements
         │           - Internal links (3-8)
         │           - FAQ blocks
         │           - Fact checking
         v
┌─────────────────┐
│Content Builder  │  Apply all optimizations
└────────┬────────┘  Generate Gutenberg blocks
         │
         v
┌─────────────────┐
│  WordPress API  │  Create draft revision
└─────────────────┘  (pending approval)

Quick Start

Prerequisites

  • Go 1.21+
  • Docker (optional)
  • WordPress with:
    • Application Password enabled
    • Polylang plugin
    • RankMath SEO plugin
    • REST API accessible

Setup

  1. Clone and configure:

    git clone <repository>
    cd WPSideKick
    make dev-setup
    
  2. Edit credentials:

    # Edit .env with your credentials
    nano .env
    

    Required:

  3. Install dependencies:

    make deps
    
  4. Run locally:

    make run
    

Configuration

Environment Variables

Variable Description Default
WP_APP_PASSWORD WordPress Application Password Required
CLAUDE_API_KEY Claude API key Required
OPTIMIZATION_INTERVAL_HOURS Hours between optimizations 2.5
LOG_LEVEL Logging level (INFO/DEBUG) INFO
API_PORT REST API port 8080
WEBHOOK_URL Optional webhook for notifications -

Configuration File

Copy configs/config.example.yaml to configs/config.yaml and customize:

wordpress:
  base_url: "https://your-blog.com"
  username: "admin"

claude:
  model: "claude-sonnet-4-20250514"
  max_tokens: 4096
  temperature: 0.3

scheduler:
  enabled: true
  interval_hours: 2.5
  languages: ["en", "es"]

optimization:
  min_content_length: 500
  min_age_days: 30
  max_age_days: 365
  reoptimization_cooldown_days: 365

storage:
  base_path: "./data/optimizations"

Docker Deployment

# Build and start
make docker-build
make docker-run

# View logs
make logs

# Stop
make docker-stop

Docker Run

docker build -t seo-optimizer .

docker run -d \
  --name seo-optimizer \
  -p 8080:8080 \
  -e WP_APP_PASSWORD="your-password" \
  -e CLAUDE_API_KEY="your-key" \
  -e OPTIMIZATION_INTERVAL_HOURS=2.5 \
  seo-optimizer

Kubernetes Deployment

# Edit secrets in deployment.yaml first
kubectl apply -f deployments/kubernetes/deployment.yaml

# Check status
kubectl get pods -l app=seo-optimizer
kubectl logs -f deployment/seo-optimizer

# Port-forward for local access
kubectl port-forward svc/seo-optimizer 8080:8080

REST API

Endpoints

Health Check

curl http://localhost:8080/api/v1/health
# Response: {"status":"ok","version":"1.0.0"}

Manual Optimization

curl -X POST http://localhost:8080/api/v1/optimize \
  -H "Content-Type: application/json" \
  -d '{"post_id": 123, "language": "es"}'
# Response: {"job_id":"uuid","status":"accepted"}

Check Status

curl http://localhost:8080/api/v1/status/uuid
# Response: {"status":"completed","post_id":123,...}

Pending Reviews

curl http://localhost:8080/api/v1/pending
# Response: {"count":2,"records":[...]}

Optimization Details (by Post ID)

curl http://localhost:8080/api/v1/optimization/123
# Response: { ... optimization record ... }

Apply Draft

curl -X POST http://localhost:8080/api/v1/apply-draft \
  -H "Content-Type: application/json" \
  -d '{"draft_post_id": 456}'
# Response: {"status":"applied","message":"Draft applied to original post and draft deleted"}

Optimization Records (File Storage)

Optimizations are stored on disk for audit and review:

  • Base path: storage.base_path (default ./data/optimizations)
  • Subfolders: pending/, applied/, rejected/, skipped/
  • Files: {post_id}_{unix_timestamp}.json containing the full Claude response

How It Works

Post Selection

The optimizer selects posts based on:

  • Age: Last modified between 30 and 365 days ago
  • Content: >= 500 words
  • Cooldown: Not optimized in last 12 months
  • Status: Published only
  • Order: Oldest first

Optimization Process

  1. SEO Meta: Optimized title (50-60 chars) and description (150-160 chars)
  2. Content Changes: Keyword injection, heading improvements, technical updates
  3. Internal Links: 3-8 relevant internal links with descriptive anchors
  4. FAQ Block: 4-6 questions in RankMath format (if appropriate)
  5. Validation: Fact-checking and broken link fixes
  6. Draft Creation: WordPress draft revision (requires manual approval)

Cost Tracking

  • Model: Claude Sonnet 4.5
  • Pricing: $3/1M input tokens, $15/1M output tokens
  • Est. per post: 8K input + 2K output ≈ $0.054 (€0.05)
  • Budget: €10/month ≈ 200 posts
  • Interval: 2.5 hours ≈ 10 posts/day ≈ 300 posts/month

Monitoring

Logs

# Docker Compose
docker-compose logs -f

# Kubernetes
kubectl logs -f deployment/seo-optimizer

# JSON format (default)
{
  "time":"2026-01-24T10:30:00Z",
  "level":"INFO",
  "msg":"Optimization completed",
  "post_id":123,
  "cost_usd":0.054,
  "changes":8,
  "links":5,
  "duration_seconds":45.2
}

Health Check

# HTTP
curl http://localhost:8080/api/v1/health

# Docker
docker inspect --format='{{.State.Health.Status}}' seo-optimizer

Development

Build

# Local build
make build

# Production build (optimized)
make build-prod

# Run with debug logging
make run-debug

Testing

# Run all tests
make test

# With coverage
make test-coverage

# Quick tests
make test-quick

Code Quality

# Format code
make fmt

# Lint (requires golangci-lint)
make lint

# All checks
make all

Troubleshooting

WordPress Connection Issues

Problem: "WordPress API error: status 401"

Solution:

  1. Verify WordPress Application Password is correct
  2. Check WordPress REST API is accessible: curl https://your-blog.com/wp-json/wp/v2/posts
  3. Ensure username and password are properly set in .env

Claude API Errors

Problem: "Claude API error: status 401"

Solution:

  1. Verify Claude API key is correct
  2. Check API key has sufficient credits
  3. Test API key: curl https://api.anthropic.com/v1/messages -H "x-api-key: YOUR_KEY"

No Posts Selected

Problem: "No eligible posts found for optimization"

Possible causes:

  • All posts are too recent (< 120 days old)
  • All posts were recently optimized (< 90 days ago)
  • Posts don't meet minimum word count (500 words)

Solution:

  • Adjust max_age_days or reoptimization_cooldown_days in config
  • Check post modification dates in WordPress

Budget Exceeded

Problem: Costs exceeding €10/month

Solution:

  • Increase interval_hours (e.g., 3.0 or 4.0)
  • Reduce optimization frequency
  • Monitor costs in logs: grep "cost_usd" logs/*.log

Security

  • No Auto-Publish: Creates draft revisions only
  • Local API: No authentication (assumes local/trusted network)
  • Credentials: Use environment variables, never commit secrets
  • Non-Root: Docker runs as non-root user (UID 1000)

License

[Add your license here]

Support

Roadmap

  • Prometheus metrics export
  • Advanced retry strategies
  • Image optimization suggestions
  • Schema markup generation
  • Multi-site support
  • Category-specific optimization strategies
S
Description
No description provided
Readme 706 KiB
Languages
Go 76%
JavaScript 14.5%
CSS 4.6%
HTML 3.8%
Makefile 0.8%
Other 0.3%