- 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>
6.4 KiB
6.4 KiB
Reciclaje de Contenido
Sistema para republica contenido exitoso y maximizar su alcance.
Descripción
El reciclaje de contenido permite:
- Identificar posts con alto engagement
- Republicarlos con modificaciones opcionales
- Trackear rendimiento de versiones recicladas
- Automatizar el proceso de reciclaje
Modelo de Datos
RecycledPost
RecycledPost:
id: int
original_post_id: int (FK -> posts)
new_post_id: int (FK -> posts)
recycle_number: int # 1, 2, 3... (veces reciclado)
modifications: JSON
# {"content_changed": true, "hashtags_updated": true, "image_changed": false}
modification_notes: str
original_engagement_rate: float
new_engagement_rate: float
status: str # pending, published, cancelled
reason: str # high_performer, evergreen, seasonal, manual
recycled_at: datetime
scheduled_for: datetime
Campos en Post
# Campos añadidos al modelo Post
is_recyclable: bool # Si puede ser reciclado (default True)
recycled_from_id: int (FK -> posts) # Post original si es reciclado
recycle_count: int # Veces que este post ha sido reciclado
Configuración
# En recycling_service.py
MIN_DAYS_SINCE_PUBLISH = 30 # No reciclar posts recientes
MIN_ENGAGEMENT_RATE = 2.0 # Mínimo 2% engagement
MAX_RECYCLE_COUNT = 3 # Máximo 3 veces por post
API Endpoints
GET /api/recycling/candidates
Obtiene posts candidatos para reciclar.
Parámetros:
platform(str): Filtrar por plataformacontent_type(str): Filtrar por tipo de contenidomin_engagement_rate(float, default=2.0): Engagement mínimomin_days(int, default=30): Días desde publicaciónlimit(int, default=20): Máximo candidatos
Respuesta:
{
"candidates": [
{
"id": 123,
"content": "Tip: Usa IA para automatizar...",
"full_content": "...",
"content_type": "tip_tech",
"platforms": ["x"],
"published_at": "2024-12-01T10:00:00",
"days_since_publish": 58,
"engagement_rate": 4.5,
"recycle_count": 0,
"score": 3.8,
"metrics": {"likes": 150, "comments": 30}
}
],
"count": 10,
"filters": {
"min_engagement_rate": 2.0,
"min_days": 30
}
}
POST /api/recycling/{post_id}
Recicla un post específico.
Body (opcional):
{
"content": "Versión actualizada del contenido...",
"hashtags": ["#nuevo", "#hashtag"],
"image_url": "https://...",
"scheduled_for": "2025-02-01T10:00:00",
"platforms": ["x", "threads"],
"reason": "high_performer"
}
Respuesta:
{
"message": "Post recycled successfully",
"success": true,
"new_post_id": 456,
"recycle_record_id": 1,
"scheduled_for": "2025-02-01T10:00:00",
"platforms": ["x", "threads"]
}
POST /api/recycling/auto
Reciclaje automático de mejores posts.
Parámetros:
platform(str, opcional): Plataforma específicacount(int, default=1, max=5): Cantidad a reciclarmin_engagement_rate(float, default=2.0)
Respuesta:
{
"success": true,
"recycled": 2,
"posts": [
{
"original_id": 123,
"new_post_id": 456,
"engagement_rate": 4.5
}
]
}
GET /api/recycling/history
Obtiene historial de reciclaje.
Parámetros:
original_post_id(int, opcional): Filtrar por post originallimit(int, default=50)
POST /api/recycling/{post_id}/disable
Marca un post como no reciclable.
Sistema de Puntuación
Los candidatos se puntúan con la fórmula:
score = engagement_rate * recency_factor * recycled_penalty
donde:
recency_factor = min(days_since_publish / 90, 1.0)
recycled_penalty = 1 - (recycle_count * 0.2)
Ejemplo
| Post | Engagement | Días | Reciclajes | Score |
|---|---|---|---|---|
| A | 4.0% | 60 | 0 | 4.0 × 0.67 × 1.0 = 2.68 |
| B | 5.0% | 90 | 1 | 5.0 × 1.0 × 0.8 = 4.00 |
| C | 3.0% | 45 | 0 | 3.0 × 0.5 × 1.0 = 1.50 |
Post B tiene el score más alto.
Tareas Programadas
auto_recycle_content
- Frecuencia: Diario a las 2:00 AM
- Función:
- Busca 1 post por plataforma con engagement > 3%
- Programa reciclaje automático
- Plataformas: x, threads
Flujo de Reciclaje
1. Identificar Candidatos
- Posts con > 30 días de antigüedad
- Engagement rate > 2%
- recycle_count < 3
- is_recyclable = true
↓
2. Seleccionar por Score
- Ordenar por score descendente
↓
3. Crear Post Reciclado
- Clonar contenido (o modificar)
- Establecer recycled_from_id
- Programar publicación
↓
4. Registrar en RecycledPost
- Guardar relación
- Incrementar recycle_count del original
↓
5. Publicar y Trackear
- Comparar new_engagement_rate vs original
Razones de Reciclaje
| Razón | Descripción |
|---|---|
high_performer |
Post con engagement alto |
evergreen |
Contenido atemporal relevante |
seasonal |
Contenido de temporada que regresa |
manual |
Reciclado manualmente |
Ejemplo de Uso
from app.services.recycling_service import recycling_service
# Buscar candidatos
candidates = await recycling_service.find_recyclable_posts(
platform="x",
min_engagement_rate=3.0,
limit=10
)
for candidate in candidates:
print(f"Post {candidate['id']}: {candidate['engagement_rate']}% - Score {candidate['score']}")
# Reciclar manualmente
result = await recycling_service.recycle_post(
post_id=123,
modifications={"content": "Versión actualizada..."},
reason="evergreen"
)
# Reciclaje automático
result = await recycling_service.auto_recycle(
platform="x",
count=2
)
Mejores Prácticas
- Esperar suficiente tiempo: Mínimo 30 días entre reciclajes
- Modificar ligeramente: Actualiza hashtags o intro
- No abusar: Máximo 3 reciclajes por post
- Monitorear: Compara rendimiento nuevo vs original
- Contenido evergreen: Prioriza contenido atemporal
Tipos de Contenido Ideales para Reciclar
| Tipo | Ideal | Razón |
|---|---|---|
| Tips técnicos | ✅ | Siempre relevantes |
| Tutoriales | ✅ | Valor educativo permanente |
| Productos | ⚠️ | Si stock disponible |
| Promociones | ❌ | Fechas específicas |
| Efemérides | ❌ | Fechas específicas |
| Noticias | ❌ | Se vuelven obsoletas |