Files
social-media-automation/docs/CONTENT_RECYCLING.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

268 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```python
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
```python
# 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
```python
# 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 plataforma
- `content_type` (str): Filtrar por tipo de contenido
- `min_engagement_rate` (float, default=2.0): Engagement mínimo
- `min_days` (int, default=30): Días desde publicación
- `limit` (int, default=20): Máximo candidatos
**Respuesta:**
```json
{
"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):**
```json
{
"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:**
```json
{
"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ífica
- `count` (int, default=1, max=5): Cantidad a reciclar
- `min_engagement_rate` (float, default=2.0)
**Respuesta:**
```json
{
"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 original
- `limit` (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:
```python
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
```python
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
1. **Esperar suficiente tiempo:** Mínimo 30 días entre reciclajes
2. **Modificar ligeramente:** Actualiza hashtags o intro
3. **No abusar:** Máximo 3 reciclajes por post
4. **Monitorear:** Compara rendimiento nuevo vs original
5. **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 |