330 lines
8.0 KiB
YAML
330 lines
8.0 KiB
YAML
# SEO Optimizer Configuration
|
|
# Copy this file to config.yaml and customize with your settings
|
|
|
|
wordpress:
|
|
# WordPress base URL (without trailing slash)
|
|
base_url: "https://alexandre-vazquez.com"
|
|
|
|
# WordPress username (admin or any user with post edit permissions)
|
|
username: "admin"
|
|
|
|
# Application Password (set via environment variable WP_APP_PASSWORD)
|
|
# Generate in WordPress: Users → Profile → Application Passwords
|
|
app_password: "${WP_APP_PASSWORD}"
|
|
|
|
# API request timeout
|
|
timeout: 30s
|
|
|
|
profile:
|
|
# Human-friendly site name used in prompts
|
|
name: "Alexandre Vazquez"
|
|
|
|
# Canonical site URL
|
|
url: "https://alexandre-vazquez.com"
|
|
|
|
# Primary topics covered by the site
|
|
topics:
|
|
- "Kubernetes"
|
|
- "DevOps"
|
|
- "Platform engineering"
|
|
- "Enterprise infrastructure"
|
|
|
|
# Intended audience
|
|
audience: "Senior engineers, architects, SREs"
|
|
|
|
# Writing voice/tone
|
|
voice: "Practical, technical, and concise"
|
|
|
|
# High-level optimization goals (used in SEO prompt)
|
|
goals:
|
|
- "Rank higher in traditional search engines (Google, Bing)"
|
|
- "Be a trusted reference for LLM/AI agents (Claude, ChatGPT, etc.)"
|
|
- "Increase internal link coverage"
|
|
- "Maintain technical accuracy and depth"
|
|
|
|
# Preferred fact-checking sources (domains or URLs)
|
|
fact_check_sources:
|
|
- "kubernetes.io"
|
|
- "docs.tibco.com"
|
|
- "pve.proxmox.com"
|
|
- "docs.ceph.com"
|
|
|
|
# Additional content guidelines for article drafts
|
|
content_guidelines:
|
|
- "Target length: 1,200-2,000 words."
|
|
- "Include 1 short code block if relevant."
|
|
- "Keep technical terms and product names in English."
|
|
|
|
runtime:
|
|
# When true, do not create or publish WordPress drafts
|
|
dry_run: false
|
|
|
|
claude:
|
|
# Claude API key (set via environment variable CLAUDE_API_KEY)
|
|
# Get from: https://console.anthropic.com/
|
|
api_key: "${CLAUDE_API_KEY}"
|
|
|
|
# Model to use for optimizations
|
|
# claude-sonnet-4-20250514: Latest Sonnet 4.5 ($3/1M input, $15/1M output)
|
|
model: "claude-sonnet-4-20250514"
|
|
|
|
# Maximum tokens to generate
|
|
max_tokens: 4096
|
|
|
|
# Temperature (0.0-1.0, lower = more consistent)
|
|
temperature: 0.3
|
|
|
|
llm:
|
|
# LLM provider to use: "claude" or "deepseek"
|
|
provider: "claude"
|
|
|
|
deepseek:
|
|
# DeepSeek API key (set via environment variable DEEPSEEK_API_KEY)
|
|
# Get from: https://platform.deepseek.com/
|
|
api_key: "${DEEPSEEK_API_KEY}"
|
|
|
|
# API base URL (default: https://api.deepseek.com)
|
|
# Use https://api.deepseek.com/v1 if you prefer explicit versioning
|
|
base_url: "https://api.deepseek.com"
|
|
|
|
# Model to use for optimizations
|
|
# deepseek-chat: general-purpose chat model
|
|
model: "deepseek-chat"
|
|
|
|
# Maximum tokens to generate
|
|
max_tokens: 4096
|
|
|
|
# Temperature (0.0-1.0, lower = more consistent)
|
|
temperature: 0.3
|
|
|
|
scheduler:
|
|
# Enable/disable automatic scheduling
|
|
enabled: true
|
|
|
|
# Hours between optimization runs
|
|
# 2.5 hours = ~10 posts/day = ~300 posts/month (within budget)
|
|
# Adjust higher to reduce costs, lower to optimize more frequently
|
|
interval_hours: 2.5
|
|
|
|
# Languages to rotate between (Polylang language codes)
|
|
# The scheduler will alternate: en → es → en → es...
|
|
languages:
|
|
- "en"
|
|
- "es"
|
|
|
|
optimization:
|
|
# Minimum word count to consider post for optimization
|
|
# Posts with less content will be skipped
|
|
min_content_length: 500
|
|
|
|
# Only optimize posts older than this many days (minimum age)
|
|
# Prevents optimizing very recent posts that might still be fresh
|
|
min_age_days: 30
|
|
|
|
# Only optimize posts not older than this many days (maximum age)
|
|
# Focuses on content within a reasonable timeframe
|
|
max_age_days: 365
|
|
|
|
# Don't re-optimize posts for this many days (6 months cooldown)
|
|
# Prevents too-frequent optimization of same posts
|
|
reoptimization_cooldown_days: 180
|
|
|
|
# Maximum internal links to add per post
|
|
max_internal_links: 8
|
|
|
|
# FAQ block configuration
|
|
faq_min_questions: 4
|
|
faq_max_questions: 6
|
|
|
|
# When true, optimize/apply translations alongside the requested language
|
|
sync_translations: true
|
|
|
|
ideas:
|
|
# Enable daily SEO idea generation from Reddit
|
|
enabled: true
|
|
|
|
# Hours between idea generation runs (default: 24)
|
|
interval_hours: 24
|
|
|
|
# Subreddit to analyze
|
|
subreddit: "kubernetes"
|
|
|
|
# Listing to use: top | hot | new
|
|
listing: "top"
|
|
|
|
# Time range for top listing: hour | day | week | month | year | all
|
|
time_range: "day"
|
|
|
|
# Max Reddit posts to analyze per run
|
|
max_reddit_posts: 20
|
|
|
|
# Max ideas to generate per run
|
|
max_ideas: 5
|
|
|
|
# Recent posts to use as style references
|
|
style_sample_posts: 3
|
|
|
|
# Filter Reddit posts by score/comment thresholds
|
|
min_score: 25
|
|
min_comments: 5
|
|
|
|
# Directory to store idea records
|
|
base_path: "./data/ideas"
|
|
|
|
outreach:
|
|
# Enable outreach suggestions from Reddit
|
|
enabled: true
|
|
|
|
# Subreddit to analyze
|
|
subreddit: "kubernetes"
|
|
|
|
# Listing to use: top | hot | new
|
|
listing: "top"
|
|
|
|
# Time range for top listing: hour | day | week | month | year | all
|
|
time_range: "day"
|
|
|
|
# Max Reddit posts to analyze per run
|
|
max_reddit_posts: 20
|
|
|
|
# Max outreach suggestions per run
|
|
max_suggestions: 5
|
|
|
|
# Filter Reddit posts by score/comment thresholds
|
|
min_score: 25
|
|
min_comments: 5
|
|
|
|
# Max internal articles to consider
|
|
max_articles: 50
|
|
|
|
# Directory to store outreach suggestions
|
|
base_path: "./data/outreach"
|
|
|
|
newsletter:
|
|
# Enable weekly newsletter drafts
|
|
enabled: true
|
|
|
|
# Hours between newsletter runs (default: 168 = weekly)
|
|
interval_hours: 168
|
|
|
|
# RSS feed URL to pull new posts from
|
|
feed_url: "https://alexandre-vazquez.com/feed/"
|
|
|
|
# Subreddit to use for community context
|
|
subreddit: "kubernetes"
|
|
|
|
# Listing to use: top | hot | new
|
|
listing: "top"
|
|
|
|
# Time range for top listing: hour | day | week | month | year | all
|
|
time_range: "week"
|
|
|
|
# Max feed items to include
|
|
max_feed_items: 5
|
|
|
|
# Max Reddit posts to include
|
|
max_reddit_posts: 10
|
|
|
|
# Filter Reddit posts by score/comment thresholds
|
|
min_score: 10
|
|
min_comments: 2
|
|
|
|
# Directory to store newsletter drafts
|
|
base_path: "./data/newsletters"
|
|
|
|
link_checker:
|
|
# Enable/disable broken link scanning
|
|
enabled: true
|
|
|
|
# Hours between broken link scans (default: 168 = weekly)
|
|
interval_hours: 168
|
|
|
|
# Timeout per link request
|
|
request_timeout: 10s
|
|
|
|
# Max posts to scan (0 = all)
|
|
max_posts: 0
|
|
|
|
# Max links per post to scan (0 = all)
|
|
max_links_per_post: 0
|
|
|
|
# Number of concurrent link checks
|
|
concurrency: 6
|
|
|
|
# Directory to store broken link reports
|
|
base_path: "./data/broken-links"
|
|
|
|
image_audit:
|
|
# Enable/disable external image audit
|
|
enabled: true
|
|
|
|
# Hours between image audits (default: 168 = weekly)
|
|
interval_hours: 168
|
|
|
|
# Base URL for resolving relative image URLs
|
|
base_url: ""
|
|
|
|
# Directory to store image audit reports
|
|
base_path: "./data/image-audits"
|
|
|
|
# Max posts to scan (0 = all)
|
|
max_posts: 0
|
|
|
|
# Max images per post to scan (0 = all)
|
|
max_images_per_post: 0
|
|
|
|
# Allowed external image host suffixes (subdomains OK)
|
|
allowed_host_suffixes:
|
|
- "optimole.com"
|
|
|
|
# Timeout for image downloads when fixing
|
|
download_timeout: 20s
|
|
|
|
# Max bytes to download per image when fixing
|
|
max_download_bytes: 20971520
|
|
|
|
seo_audit:
|
|
# Enable/disable SEO audit scoring
|
|
enabled: true
|
|
|
|
# Base URL for resolving internal vs external links
|
|
base_url: ""
|
|
|
|
# Directory to store SEO audit reports
|
|
base_path: "./data/seo-audits"
|
|
|
|
# Max posts to scan (0 = all)
|
|
max_posts: 0
|
|
|
|
storage:
|
|
# Directory to store optimization records
|
|
# This stores pending drafts and optimization history
|
|
base_path: "./data/optimizations"
|
|
|
|
audit:
|
|
# Directory to store audit records
|
|
base_path: "./data/audit"
|
|
|
|
api:
|
|
# Enable/disable REST API server
|
|
enabled: true
|
|
|
|
# Port to listen on
|
|
port: 8080
|
|
|
|
logging:
|
|
# Log level: INFO or DEBUG
|
|
# INFO: Standard operational logs
|
|
# DEBUG: Detailed logs including API payloads
|
|
level: "INFO"
|
|
|
|
# Log format: json or text
|
|
# json: Structured JSON logs (recommended for production)
|
|
# text: Human-readable text logs (easier for development)
|
|
format: "json"
|
|
|
|
notifications:
|
|
# Optional webhook URL for notifications (Slack, Discord, etc.)
|
|
# Leave empty to disable
|
|
webhook_url: ""
|