Files
opencode-skill/skills/seo-data/SKILL.md
2026-03-08 23:03:19 +07:00

9.0 KiB

name, description
name description
seo-data Connect to analytics services (GA4, GSC, DataForSEO, Umami) for performance data. Optional per-project configuration. Services are skipped if not configured.

📊 SEO Data - Analytics Integrations

Skill Name: seo-data
Category: quick
Load Skills: []


🚀 Purpose

Connect to analytics services for content performance data:

  • Google Analytics 4 - Traffic, engagement, conversions
  • Google Search Console - Rankings, impressions, CTR
  • DataForSEO - Competitor analysis, SERP data, keyword research
  • Umami Analytics - Privacy-first analytics (if self-hosted)

Key Feature: All services are optional. Skill skips unconfigured services silently.

Use Cases:

  1. Get page performance from all configured services
  2. Find quick-win keywords (ranking 11-20)
  3. Analyze competitor gaps
  4. Track content performance over time
  5. Identify declining content

📋 Per-Project Configuration

Each website project has its own data service config in context/data-services.json:

{
  "ga4": {
    "enabled": true,
    "property_id": "G-XXXXXXXXXX",
    "credentials_path": "./ga4-credentials.json"
  },
  "gsc": {
    "enabled": true,
    "site_url": "https://yoursite.com",
    "credentials_path": "./gsc-credentials.json"
  },
  "dataforseo": {
    "enabled": false,
    "login": "your_login",
    "password": "your_password"
  },
  "umami": {
    "enabled": true,
    "api_url": "https://analytics.yoursite.com",
    "api_key": "your_api_key"
  }
}

🔄 Workflows

Workflow 1: Get Page Performance

Input: Page URL + project context
Process:
  1. Load data-services.json
  2. Initialize enabled services only
  3. Fetch data from each service (in parallel)
  4. Aggregate results
  5. Skip failed services silently
Output:
  - GA4: Page views, engagement time, bounce rate
  - GSC: Impressions, clicks, avg position, CTR
  - DataForSEO: Keyword rankings, SERP features
  - Umami: Page views, unique visitors

Workflow 2: Find Quick Wins

Input: Project context
Process:
  1. Fetch GSC keyword data
  2. Filter keywords ranking 11-20
  3. Sort by search volume
  4. Return top opportunities
Output:
  - List of keywords with current position, search volume, URL
  - Priority score (based on traffic potential)

Workflow 3: Competitor Analysis

Input: Your domain + competitor domain + keywords
Process:
  1. Fetch DataForSEO SERP data
  2. Compare rankings
  3. Identify gaps (they rank, you don't)
  4. Calculate difficulty
Output:
  - Competitor ranking keywords
  - Gap opportunities
  - Difficulty scores

🔧 Technical Implementation

Service Manager Pattern:

class DataServiceManager:
    """Manage optional analytics connections"""
    
    def __init__(self, context_path: str):
        self.config = self._load_config(context_path)
        self.services = {}
        
        # Initialize only configured services
        if self.config.get('ga4', {}).get('enabled'):
            from ga4_connector import GA4Connector
            self.services['ga4'] = GA4Connector(
                self.config['ga4']['property_id'],
                self.config['ga4']['credentials_path']
            )
        
        if self.config.get('gsc', {}).get('enabled'):
            from gsc_connector import GSCConnector
            self.services['gsc'] = GSCConnector(
                self.config['gsc']['site_url'],
                self.config['gsc']['credentials_path']
            )
        
        if self.config.get('dataforseo', {}).get('enabled'):
            from dataforseo_client import DataForSEOClient
            self.services['dataforseo'] = DataForSEOClient(
                self.config['dataforseo']['login'],
                self.config['dataforseo']['password']
            )
        
        if self.config.get('umami', {}).get('enabled'):
            from umami_connector import UmamiConnector
            self.services['umami'] = UmamiConnector(
                self.config['umami']['api_url'],
                self.config['umami']['api_key']
            )
    
    def get_page_performance(self, url: str, days: int = 30) -> Dict:
        """Aggregate data from all available services"""
        results = {}
        
        for name, service in self.services.items():
            try:
                results[name] = service.get_page_data(url, days)
            except Exception as e:
                # Skip failed services silently
                print(f"Warning: {name} failed: {e}")
                results[name] = {'error': str(e)}
        
        return results
    
    def get_quick_wins(self, min_position: int = 11, max_position: int = 20) -> List[Dict]:
        """Find keywords ranking 11-20 (page 2, ready to push to page 1)"""
        if 'gsc' not in self.services:
            return []
        
        try:
            return self.services['gsc'].get_quick_wins(min_position, max_position)
        except Exception as e:
            print(f"Warning: GSC quick wins failed: {e}")
            return []

📁 Commands

Get Page Performance:

python3 skills/seo-data/scripts/data_aggregator.py \
  --url "https://yoursite.com/blog/article" \
  --context "./website/context/" \
  --days 30

Find Quick Wins:

python3 skills/seo-data/scripts/gsc_connector.py \
  --context "./website/context/" \
  --action quick-wins \
  --min-position 11 \
  --max-position 20

Competitor Analysis:

python3 skills/seo-data/scripts/dataforseo_client.py \
  --context "./website/context/" \
  --action competitor-gap \
  --your-domain "yoursite.com" \
  --competitor "competitor.com" \
  --keywords "keyword1,keyword2"

⚙️ Environment Variables

Optional (in unified .env or project .env):

# Google Analytics 4
GA4_PROPERTY_ID=G-XXXXXXXXXX
GA4_CREDENTIALS_PATH=path/to/ga4-credentials.json

# Google Search Console
GSC_SITE_URL=https://yoursite.com
GSC_CREDENTIALS_PATH=path/to/gsc-credentials.json

# DataForSEO
DATAFORSEO_LOGIN=your_login
DATAFORSEO_PASSWORD=your_password
DATAFORSEO_BASE_URL=https://api.dataforseo.com

# Umami Analytics
UMAMI_API_URL=https://analytics.yoursite.com
UMAMI_API_KEY=your_api_key

📊 Output Examples

Page Performance Output:

{
  "url": "https://yoursite.com/blog/podcast-hosting",
  "period": "last_30_days",
  "ga4": {
    "pageviews": 12500,
    "sessions": 9800,
    "avg_engagement_time": 245,
    "bounce_rate": 0.42,
    "conversions": 125
  },
  "gsc": {
    "impressions": 45000,
    "clicks": 3200,
    "avg_position": 8.5,
    "ctr": 0.071,
    "top_keywords": [
      {"keyword": "podcast hosting", "position": 8, "clicks": 1200},
      {"keyword": "best podcast platform", "position": 12, "clicks": 800}
    ]
  },
  "dataforseo": {
    "rankings": [
      {"keyword": "podcast hosting", "position": 8, "search_volume": 2900},
      {"keyword": "podcast platform", "position": 15, "search_volume": 1500}
    ]
  },
  "umami": {
    "pageviews": 11800,
    "unique_visitors": 8500,
    "bounce_rate": 0.38
  }
}

Quick Wins Output:

{
  "quick_wins": [
    {
      "keyword": "podcast hosting comparison",
      "current_position": 12,
      "search_volume": 1200,
      "clicks": 45,
      "impressions": 2500,
      "ctr": 0.018,
      "url": "/blog/podcast-hosting-comparison",
      "priority_score": 85,
      "recommendation": "Add more comparison data, update for 2026"
    }
  ],
  "total_opportunities": 15,
  "estimated_traffic_gain": "+2500 visits/month if all reach top 10"
}

⚠️ Important Notes

  1. All Services Optional: Skill works even with zero services configured
  2. Silent Failures: Failed services are skipped, not blocking
  3. Per-Project Config: Each website has its own data-services.json
  4. Caching: API responses cached for 24 hours to reduce costs
  5. Rate Limits: Respects API rate limits, queues requests if needed

🔌 Service Setup Guides

Google Analytics 4:

  1. Go to Google Cloud Console
  2. Create service account
  3. Download JSON credentials
  4. Add service account to GA4 property (Viewer role)
  5. Update context/data-services.json

Google Search Console:

  1. Same service account as GA4 (or create new)
  2. Add to Search Console property (Owner or Full access)
  3. Update context/data-services.json

DataForSEO:

  1. Sign up at dataforseo.com
  2. Get API login and password
  3. Add to context/data-services.json
  4. Set budget limits

Umami:

  1. Self-host Umami or use cloud
  2. Create website in Umami
  3. Generate API key
  4. Update context/data-services.json

🔄 Integration with Other Skills

  • seo-multi-channel: Fetches performance data to inform content strategy
  • seo-analyzers: Uses GSC data for keyword optimization scoring
  • seo-context: Reads data-services.json from context folder

Use this skill when you need performance data from analytics services to inform content decisions or track results.

All services are optional - the skill gracefully skips unconfigured services.