Auto-sync from website-creator

This commit is contained in:
Kunthawat Greethong
2026-03-08 23:03:19 +07:00
commit 9be686f587
117 changed files with 24737 additions and 0 deletions

358
skills/seo-data/SKILL.md Normal file
View File

@@ -0,0 +1,358 @@
---
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.**