⭐ 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 endata/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).
sharpinstalado 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
StartCalendarIntervalmartes/viernes 11:00.