feat: Add follower tracking to interactions

- Add get_followers() method to X publisher
- Track new followers as "follow" interaction type
- Update daily reports to show followers separately
- Store follower name, username, bio, and profile image

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-29 23:07:28 +00:00
parent f5c6554fc3
commit b6823651e0
3 changed files with 113 additions and 9 deletions

View File

@@ -67,14 +67,30 @@ def morning_report():
else:
message += " _No hay posts programados para hoy_\n\n"
# Sección de interacciones
# Separar follows de otras interacciones
follows = [i for i in new_interactions if i.interaction_type == "follow"]
other_interactions = [i for i in new_interactions if i.interaction_type != "follow"]
# Sección de nuevos followers
if follows:
message += "━━━━━━━━━━━━━━━━━━━━━\n"
message += f"👥 *Nuevos followers ({len(follows)}):*\n\n"
for f in follows[:5]:
name = f.author_name or f.author_username
name = name.replace("_", "\\_").replace("*", "\\*") if name else "Usuario"
message += f" • @{f.author_username} ({name})\n"
if len(follows) > 5:
message += f" _...y {len(follows) - 5} más_\n"
message += "\n"
# Sección de otras interacciones
message += "━━━━━━━━━━━━━━━━━━━━━\n"
message += "💬 *Nuevas interacciones (24h):*\n\n"
if new_interactions:
if other_interactions:
# Agrupar por plataforma
by_platform = {}
for interaction in new_interactions:
for interaction in other_interactions:
platform = interaction.platform
if platform not in by_platform:
by_platform[platform] = []
@@ -85,7 +101,8 @@ def morning_report():
for i in interactions[:3]: # Mostrar máximo 3 por plataforma
content_preview = i.content[:50] + "..." if i.content and len(i.content) > 50 else (i.content or "N/A")
content_preview = content_preview.replace("_", "\\_").replace("*", "\\*")
message += f" • @{i.author_username}: {content_preview}\n"
type_emoji = "💬" if i.interaction_type == "comment" else "📢"
message += f" {type_emoji} @{i.author_username}: {content_preview}\n"
if len(interactions) > 3:
message += f" _...y {len(interactions) - 3} más_\n"
message += "\n"
@@ -154,13 +171,29 @@ def afternoon_report():
message += f" ✅ Publicados hoy: {published_today}\n"
message += f" 📅 Programados mañana: {scheduled_tomorrow}\n\n"
# Separar follows de otras interacciones
follows = [i for i in new_interactions if i.interaction_type == "follow"]
other_interactions = [i for i in new_interactions if i.interaction_type != "follow"]
# Nuevos followers del día
if follows:
message += "━━━━━━━━━━━━━━━━━━━━━\n"
message += f"👥 *Nuevos followers hoy ({len(follows)}):*\n\n"
for f in follows[:5]:
name = f.author_name or f.author_username
name = name.replace("_", "\\_").replace("*", "\\*") if name else "Usuario"
message += f" • @{f.author_username} ({name})\n"
if len(follows) > 5:
message += f" _...y {len(follows) - 5} más_\n"
message += "\n"
# Interacciones pendientes
message += "━━━━━━━━━━━━━━━━━━━━━\n"
message += "💬 *Interacciones pendientes:*\n\n"
if new_interactions:
if other_interactions:
by_platform = {}
for interaction in new_interactions:
for interaction in other_interactions:
platform = interaction.platform
if platform not in by_platform:
by_platform[platform] = []
@@ -171,13 +204,14 @@ def afternoon_report():
for i in interactions[:5]: # Mostrar más en el reporte de la tarde
content_preview = i.content[:50] + "..." if i.content and len(i.content) > 50 else (i.content or "N/A")
content_preview = content_preview.replace("_", "\\_").replace("*", "\\*")
message += f" • @{i.author_username}: {content_preview}\n"
type_emoji = "💬" if i.interaction_type == "comment" else "📢"
message += f" {type_emoji} @{i.author_username}: {content_preview}\n"
if len(interactions) > 5:
message += f" _...y {len(interactions) - 5} más_\n"
message += "\n"
message += "━━━━━━━━━━━━━━━━━━━━━\n"
message += f"⚠️ *{len(new_interactions)} interacciones sin responder*"
message += f"⚠️ *{len(other_interactions)} interacciones sin responder*"
else:
message += " ✅ _Todas las interacciones han sido atendidas_\n\n"
message += "━━━━━━━━━━━━━━━━━━━━━\n"