Files
social-media-automation/docs/ANALYTICS.md
Consultoría AS e2882ce72b docs: Add comprehensive documentation for all new features
- FEATURES_OVERVIEW.md: Complete summary of all system features
- ANALYTICS.md: Analytics and reporting system documentation
- ODOO_INTEGRATION.md: Odoo ERP integration guide
- AB_TESTING.md: A/B testing system documentation
- CONTENT_RECYCLING.md: Content recycling system docs
- THREAD_SERIES.md: Thread series and scheduled posts
- IMAGE_TEMPLATES.md: Visual template system documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 03:17:23 +00:00

265 lines
6.2 KiB
Markdown

# Analytics y Reportes
Sistema completo de métricas y análisis de rendimiento para optimizar tu estrategia de contenido.
## Modelos de Datos
### PostMetrics
Registra métricas de cada post a lo largo del tiempo.
```python
PostMetrics:
id: int
post_id: int (FK -> posts)
platform: str # x, threads, instagram, facebook
likes: int
comments: int
shares: int
impressions: int
reach: int
saves: int
clicks: int
replies: int
quotes: int
engagement_rate: float
recorded_at: datetime
```
### AnalyticsReport
Reportes agregados (diarios, semanales, mensuales).
```python
AnalyticsReport:
id: int
report_type: str # daily, weekly, monthly
period_start: date
period_end: date
platform: str (opcional)
total_posts: int
total_impressions: int
total_engagements: int
avg_engagement_rate: float
top_posts: JSON # Lista de mejores posts
best_times: JSON # Mejores horarios
content_performance: JSON # Por tipo de contenido
platform_breakdown: JSON # Por plataforma
summary_text: str # Texto para Telegram
```
## API Endpoints
### GET /api/analytics/dashboard
Obtiene datos del dashboard principal.
**Parámetros:**
- `days` (int, default=30): Período a analizar
- `platform` (str, opcional): Filtrar por plataforma
**Respuesta:**
```json
{
"period_days": 30,
"total_posts": 45,
"total_impressions": 125000,
"total_engagements": 3500,
"total_likes": 2800,
"total_comments": 450,
"total_shares": 250,
"avg_engagement_rate": 2.8,
"platform_breakdown": {
"x": {"posts": 20, "engagements": 1500},
"threads": {"posts": 25, "engagements": 2000}
},
"content_breakdown": {
"tip_tech": {"posts": 15, "engagements": 1200},
"producto": {"posts": 10, "engagements": 800}
},
"pending_interactions": 12
}
```
### GET /api/analytics/top-posts
Obtiene los posts con mejor rendimiento.
**Parámetros:**
- `days` (int, default=30): Período a analizar
- `limit` (int, default=10): Máximo de posts
- `platform` (str, opcional): Filtrar por plataforma
**Respuesta:**
```json
{
"posts": [
{
"id": 123,
"content": "Tip: Usa IA para...",
"content_type": "tip_tech",
"platforms": ["x", "threads"],
"published_at": "2025-01-15T10:00:00",
"likes": 150,
"comments": 25,
"shares": 30,
"impressions": 5000,
"engagement_rate": 4.1
}
],
"count": 10
}
```
### GET /api/analytics/optimal-times
Calcula los mejores horarios para publicar basado en datos históricos.
**Parámetros:**
- `platform` (str, opcional): Filtrar por plataforma
- `days` (int, default=90): Días de datos a analizar
**Respuesta:**
```json
{
"optimal_times": [
{
"day": 1,
"day_name": "Mar",
"hour": 12,
"hour_formatted": "12:00",
"avg_engagement_rate": 4.5,
"sample_size": 15
}
],
"analysis_period_days": 90,
"platform": "x"
}
```
### GET /api/analytics/engagement-trend
Obtiene tendencia de engagement para gráficos.
**Parámetros:**
- `days` (int, default=30): Período
- `platform` (str, opcional): Plataforma
**Respuesta:**
```json
{
"trend": [
{
"date": "2025-01-01",
"posts": 3,
"impressions": 5000,
"engagements": 200
}
],
"period_days": 30,
"platform": null
}
```
### GET /api/analytics/reports
Obtiene reportes históricos.
**Parámetros:**
- `report_type` (str): daily, weekly, monthly
- `limit` (int, default=10): Máximo de reportes
### POST /api/analytics/reports/generate
Genera un nuevo reporte.
**Parámetros:**
- `report_type` (str): weekly (otros tipos próximamente)
### POST /api/analytics/reports/send-telegram
Genera y envía reporte por Telegram.
### GET /api/analytics/posts/{post_id}/metrics
Obtiene métricas detalladas de un post específico.
**Respuesta:**
```json
{
"post_id": 123,
"current_metrics": {"likes": 150, "comments": 25},
"published_at": "2025-01-15T10:00:00",
"platforms": ["x", "threads"],
"metrics_history": [
{
"recorded_at": "2025-01-15T12:00:00",
"likes": 50,
"comments": 10,
"engagement_rate": 2.5
}
]
}
```
## Tareas Programadas
### fetch_post_metrics
- **Frecuencia:** Cada 15 minutos
- **Función:** Obtiene métricas actualizadas de las APIs de cada plataforma
- **Posts afectados:** Publicados en los últimos 7 días
### generate_weekly_analytics_report
- **Frecuencia:** Domingos a las 9:00 AM
- **Función:** Genera reporte semanal completo
- **Acciones:**
- Calcula métricas agregadas
- Compara con semana anterior
- Genera texto para Telegram
- Envía notificación (si está configurado)
### recalculate_optimal_times
- **Frecuencia:** Lunes a las 2:00 AM
- **Función:** Recalcula mejores horarios basado en últimos 90 días
## Dashboard
Accede al dashboard de analytics en `/dashboard/analytics`.
### Características:
- **Cards de métricas:** Posts, impresiones, engagements, tasa
- **Gráfico de tendencia:** Chart.js con impresiones y engagements
- **Desglose por plataforma:** Comparativa visual
- **Top posts:** Lista de mejores performers
- **Mejores horarios:** Mapa de calor visual
- **Rendimiento por contenido:** Por tipo de publicación
## Configuración
```bash
# .env
ANALYTICS_FETCH_INTERVAL=15 # minutos
TELEGRAM_REPORT_ENABLED=true
TELEGRAM_REPORT_DAY=6 # 0=Lunes, 6=Domingo
```
## Ejemplo de Uso
```python
from app.services.analytics_service import analytics_service
# Obtener stats del dashboard
stats = await analytics_service.get_dashboard_stats(days=30, platform="x")
# Obtener top posts
top = await analytics_service.get_top_posts(days=7, limit=5)
# Generar reporte semanal
report = await analytics_service.generate_weekly_report()
print(report.summary_text) # Texto formateado para Telegram
```
## Cálculos
### Engagement Rate
```
engagement_rate = (likes + comments + shares) / impressions * 100
```
### Score de Horario Óptimo
```
Para cada combinación (día, hora):
promedio_engagement = sum(engagement_rates) / count(posts)
ordenar por promedio_engagement descendente
```