359 lines
9.0 KiB
Markdown
359 lines
9.0 KiB
Markdown
---
|
|
name: seo-data
|
|
description: 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`:
|
|
|
|
```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**
|
|
|
|
```python
|
|
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**
|
|
|
|
```python
|
|
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**
|
|
|
|
```python
|
|
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:**
|
|
|
|
```python
|
|
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:**
|
|
|
|
```bash
|
|
python3 skills/seo-data/scripts/data_aggregator.py \
|
|
--url "https://yoursite.com/blog/article" \
|
|
--context "./website/context/" \
|
|
--days 30
|
|
```
|
|
|
|
### **Find Quick Wins:**
|
|
|
|
```bash
|
|
python3 skills/seo-data/scripts/gsc_connector.py \
|
|
--context "./website/context/" \
|
|
--action quick-wins \
|
|
--min-position 11 \
|
|
--max-position 20
|
|
```
|
|
|
|
### **Competitor Analysis:**
|
|
|
|
```bash
|
|
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):**
|
|
|
|
```bash
|
|
# 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:**
|
|
|
|
```json
|
|
{
|
|
"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:**
|
|
|
|
```json
|
|
{
|
|
"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.**
|