🛒 Cart Recovery (recuperación de carritos)
Archivo: agentes/marketing/cart-recovery.ts · Plist: _(ninguno — sin plist propio; cron previsto cada 2h, hoy se ejecuta manual)_ · Horario: Manual / pendiente de programar (el plist com.rifai.cart-abandoned apunta a OTRO script agentes/cart-abandoned.ts, no a este)
Qué hace
Detecta carritos de Shopify abandonados en las últimas 72h y lanza emails de recuperación escalonados. Estrategia en 3 etapas según la antigüedad del carrito: a 1h un recordatorio suave, a 24h recordatorio con descuento 5%, a 72h "última oportunidad" con descuento 10%. Genera los códigos de descuento reales en Shopify y redacta cada email con IA. Manda los emails por Gmail (preferido, gratis) o Resend, y avisa al CEO con un resumen.
Cómo funciona
1. Carga .env y abre/crea data/cart-recovery-state.json (registro de qué carrito+etapa ya se notificó, evita duplicados).
2. GET /checkouts.json?status=open de las últimas 72h; filtra los que tienen email y line_items y no están completados.
3. Para cada carrito calcula su edad y lo asigna a una ventana: 1h (1–4h), 24h (22–28h) o 72h (60–76h). Si no cae en ninguna o ya se envió esa etapa, lo salta.
4. En etapas 24h/72h crea un price_rule + discount_code en Shopify (VUELVE5-xxxxxx / ULTIMA10-xxxxxx).
5. Genera el HTML del email y el subject con el binario local gemini-cli (modelo haiku).
6. Envía con tools/gmail-sender.ts o, si no hay Gmail, con Resend.
7. Persiste estado e historial (recorta historial a 500), notifica vía router (sales_cart_abandoned).
Datos/APIs
- Shopify Admin API (
2024-10): checkouts, price_rules, discount_codes. - gemini-cli local (
tools/gemini-cli, modelo haiku) para copy + subject. - Gmail SMTP (
tools/gmail-sender.ts) o Resend como fallback. - notify-router → evento
sales_cart_abandoned. - Vars .env:
SHOPIFY_STORE,SHOPIFY_ACCESS_TOKEN,GMAIL_USER,GMAIL_APP_PASSWORD(preferido) oRESEND_API_KEY+RESEND_FROM.
Cómo probarlo
cd /Users/user/rifai-agents && npx tsx agentes/marketing/cart-recovery.ts
Espera: lista de carritos abandonados, generación/envío de emails sólo para los que caen en una ventana horaria (1h/24h/72h) y aún no fueron notificados, y resumen Enviados / Errores. Si no hay sender configurado avisa con no email sender configured.
Si se rompe / recuperar
- No tiene plist propio. Si se le crea uno (p.ej.
com.rifai.cart-recovery) recargar con:
launchctl load ~/Library/LaunchAgents/com.rifai.cart-recovery.plist
- Logs (al ejecutar a mano apuntar salida):
/Users/user/rifai-agents/logs/cart-recovery.log - Estado:
data/cart-recovery-state.json(borrarlo re-permite reenvíos).
Cómo replicarlo
- Parser
.envestándar de la flota. - Lectura de checkouts abandonados Shopify + cálculo de edad y mapeo a etapas.
- Creación de price_rule + discount_code por API.
- Generación de email HTML con un LLM local (system prompt copywriter España).
- Envío Gmail/Resend con fallback.
- Estado JSON anti-duplicados (clave
id-etapa) + notify-router.