---
name: shopify-recuperar-clientes-inactivos
description: "Encuentra a los clientes que no han comprado en N días, exporta una lista para volver a contactarlos y los etiqueta en Shopify. Úsala cuando quieras preparar una campaña para recuperar clientes que dejaron de comprar."
---

## Propósito
Segmenta a los clientes inactivos (los que hicieron al menos un pedido pero no han vuelto a comprar dentro de una ventana configurable) y los etiqueta para volver a contactarlos. Esta skill se encarga de los datos dentro de Shopify; para enviar los correos de reactivación necesitas una herramienta externa.

## Requisitos
- Sesión autenticada de Shopify CLI: `shopify store auth --store <tu-tienda>.myshopify.com --scopes read_customers,write_customers`
- Las consultas se ejecutan con `shopify store execute`.
- Permisos (scopes) de API: `read_customers`, `write_customers`

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | string | sí | — | Dominio de la tienda |
| format | string | no | human | `human` o `json` |
| dry_run | bool | no | false | Muestra el resultado sin etiquetar |
| inactive_days | integer | no | 90 | Días desde el último pedido para considerar inactivo a un cliente |
| min_orders | integer | no | 1 | Cantidad mínima de pedidos históricos para incluir al cliente |
| tag | string | no | win-back | Etiqueta que se aplica a los clientes inactivos |
| max_customers | integer | no | 500 | Máximo de clientes que se procesan por ejecución |

## Pasos

1. **OPERACIÓN:** `customers` — consulta
   **Entradas:** filtro `last_order_date:<(NOW - inactive_days days)`, `orders_count:>=(min_orders)`, `first: 250`, paginación
   **Resultado esperado:** Lista de clientes con `id`, `defaultEmailAddress { emailAddress }`, `firstName`, `lastName`, `ordersCount`, `lastOrder.processedAt`; pagina hasta que `hasNextPage: false`

2. **OPERACIÓN:** `tagsAdd` — mutación
   **Entradas:** `id` del cliente y la etiqueta del parámetro `tag`
   **Resultado esperado:** Confirmación por cliente; recoge los `userErrors`

## Operaciones GraphQL

```graphql
# customers:query — validada con api_version 2025-04
query LapsedCustomers($first: Int!, $after: String, $query: String) {
  customers(first: $first, after: $after, query: $query) {
    edges {
      node {
        id
        defaultEmailAddress {
          emailAddress
        }
        firstName
        lastName
        ordersCount
        lastOrder {
          processedAt
          totalPriceSet {
            shopMoney {
              amount
              currencyCode
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```graphql
# tagsAdd:mutation — validada con api_version 2025-01
mutation TagsAdd($id: ID!, $tags: [String!]!) {
  tagsAdd(id: $id, tags: $tags) {
    node {
      id
    }
    userErrors {
      field
      message
    }
  }
}
```

## Seguimiento de la sesión

**Claude DEBE mostrar lo siguiente en cada etapa. Es obligatorio.**

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════╗
║  SKILL: shopify-recuperar-clientes-inactivos ║
║  Tienda: <dominio de la tienda>              ║
║  Inicio: <AAAA-MM-DD HH:MM UTC>              ║
╚══════════════════════════════════════════════╝
```

**Después de cada paso**, muestra:
```
[N/TOTAL] <CONSULTA|MUTACIÓN>  <OperationName>
          → Parámetros: <resumen breve>
          → Resultado: <cantidad o desenlace>
```

Si `dry_run: true`, antepón `[SIMULACIÓN]` a los pasos de mutación y no los ejecutes.

**Al terminar**, para `format: human`:
```
══════════════════════════════════════════════
RESUMEN DEL RESULTADO
  Clientes inactivos encontrados:  <n>
  Clientes etiquetados:            <n>
  Errores:                         <n>
  Archivo:                         winback_<fecha>.csv
══════════════════════════════════════════════
```

Para `format: json`, muestra el esquema JSON estándar con estas claves en `outcome`: `lapsed_found`, `customers_tagged`, `errors`, `output_file`.

## Formato de salida
CSV `winback_<AAAA-MM-DD>.csv` con las columnas:
`customer_id`, `email`, `first_name`, `last_name`, `orders_count`, `last_order_date`, `tag_applied`

## Manejo de errores
| Error | Causa | Solución |
|-------|-------|----------|
| `THROTTLED` | Límite de solicitudes | Espera 2 s y reintenta hasta 3 veces |
| `userErrors` en tagsAdd | Cliente no encontrado o ID no válido | Regístralo, omítelo y sigue |

## Buenas prácticas
- Usa una etiqueta con fecha (p. ej., `win-back-2026-04`) para saber a qué grupo le apuntaste cada mes y no volver a etiquetar a clientes que ya recibieron una campaña de recuperación.
- Usa `min_orders: 2` para enfocarte en clientes que tuvieron una relación de compra real, y no en compradores de una sola vez que quizá nunca pensaron volver.
- Ejecuta primero con `dry_run: true` para validar cuántos clientes inactivos hay antes de etiquetarlos: esa cifra te dice qué tan grande será tu campaña de reactivación.
