← Volver al catálogo

⭐ UGC Harvest (reseñas → carrusel social)

Archivo: /Users/user/rifai-agents/agentes/social/ugc-harvest.ts · Plist: com.rifai.ugc-harvest (solo en ~/Library/LaunchAgents/, no en cron/) · Horario: martes y viernes a las 11:00 (StartCalendarInterval Weekday 2 y 5, Hour 11 / Minute 0, RunAtLoad false)

Qué hace

Dos veces por semana convierte reseñas de clientes en contenido UGC para Instagram y Facebook. Shopify no tiene API nativa de reviews, así que intenta Judge.me y, como fallback, genera una "reseña sintética" creíble a partir de los productos más vendidos (paid+fulfilled) del último mes, usando specs reales de la descripción. Compone una tarjeta cuadrada 1080×1080 (foto de producto arriba, reseña + 5 estrellas + firma abajo) con sharp, la sube a fal.ai storage, genera un caption con hashtags y la publica en FB e IG. Evita reutilizar la misma reseña con un estado.

Cómo funciona

1. Carga .env y estado data/ugc-harvest-state.json (used_review_ids, historial).

2. fetchJudgeMeReviews() (consulta metafields namespace reviews; hoy devuelve vacío) → fallback syntheticReviewsFromFulfilledOrders(3).

3. Fallback: lee pedidos Shopify paid+fulfilled de los últimos 30 días, cuenta ventas por producto, coge top 3, carga detalle (título, imagen, body_html) y genera con claude() (sonnet) una reseña honesta de 40-60 palabras basada solo en specs reales.

4. Filtra reseñas no usadas; si no hay nuevas, sale. Escoge la primera.

5. composeUGCCard() descarga la imagen del producto y monta el JPG 1080×1080 con sharp (imagen 60% + footer SVG con estrellas/texto/firma/branding dorado #C9A14A).

6. uploadToFalStorage() sube el JPG a fal.ai y obtiene URL pública.

7. Genera caption con claude() (sonnet, fallback estático con hashtags si falla).

8. Publica: FB /{PAGE}/photos, IG /media + /media_publish (dos pasos con espera 3s). Marca la reseña como usada, guarda historial y notifica (evento cs_review_new).

Datos/APIs

  • Shopify Admin API 2024-10: pedidos (paid+fulfilled), detalle de productos, metafields reviews. Vars SHOPIFY_STORE, SHOPIFY_ACCESS_TOKEN.
  • Meta Graph API v21.0: publicar foto en FB Page e IG Business. Vars META_PAGE_ID (fallback 112610281241802), META_PAGE_TOKEN/META_ACCESS_TOKEN, INSTAGRAM_BUSINESS_ID (fallback 17841401185807202).
  • fal.ai storage: subir la imagen y servir URL pública. Var FAL_API_KEY.
  • sharp (composición local de la tarjeta JPG). Tmp en data/content-tmp/.
  • LLM local tools/gemini-cli (modelo sonnet aquí, no haiku).
  • notify-router evento cs_review_new.

Cómo probarlo

cd /Users/user/rifai-agents && npx tsx agentes/social/ugc-harvest.ts

Sin flag FORCE ni restricción de día interna: cada ejecución intenta componer y publicar de verdad en FB+IG. Para inspeccionar sin publicar, comenta las llamadas publishFBPhoto/publishIGPhoto. Salida esperada: ⭐ UGC Harvest, nº de reviews, 📦 producto → 5★, ✓ Card UGC compuesta, ✓ Subido: <url fal>, caption, y 📘 FB ✅ / 📷 IG ✅. Si no hay reviews nuevas o falta imagen/upload, sale (exit 0/1).

Si se rompe / recuperar

launchctl unload ~/Library/LaunchAgents/com.rifai.ugc-harvest.plist
launchctl load   ~/Library/LaunchAgents/com.rifai.ugc-harvest.plist

Logs: /Users/user/rifai-agents/logs/ugc-harvest.out.log y .err.log. Fallos típicos: token Shopify caducado (no hay pedidos → sin reviews), FAL_API_KEY inválida (upload falla, exit 1), token Meta sin pages_manage_posts/permiso IG publish, o sharp no instalado. Plist NO versionado en cron/.

Cómo replicarlo

  • Shopify Admin con scope de pedidos+productos (y/o integración Judge.me real).
  • sharp instalado para componer la tarjeta 1080×1080.
  • Cuenta fal.ai con FAL_API_KEY (storage) — o sustituir por otro hosting de imágenes.
  • Token Meta con permisos de publicación FB Page + IG Business e IDs en .env.
  • LLM local tools/gemini-cli (sonnet) para reseña + caption, tools/notify-router.
  • Estado JSON para no repetir reseñas + plist StartCalendarInterval martes/viernes 11:00.