---
name: shopify-auditoria-correos-clientes
description: "Solo lectura: revisa tu base de clientes en busca de correos mal escritos, cuentas genéricas, dominios desechables y patrones de rebote para proteger tu reputación como remitente. Úsala antes de cada envío grande de email marketing."
---

## Propósito
Revisa toda la lista de clientes y señala las direcciones que afectarán la entregabilidad de tus correos si las incluyes en envíos de marketing: direcciones con sintaxis inválida, cuentas genéricas o de rol (info@, admin@, sales@), dominios desechables o temporales conocidos y patrones que sugieren rebote duro. El resultado es una lista de supresión que puedes importar directamente en tu plataforma de email. Solo lectura, sin mutaciones.

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

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | string | sí | — | Dominio de la tienda (p. ej., mitienda.myshopify.com) |
| marketing_consent_only | bool | no | true | Revisa solo los clientes que hoy aceptan marketing: son los que corren el riesgo de recibir envíos |
| disposable_domains | array | no | lista incluida | Reemplaza la lista incluida de dominios desechables |
| role_localparts | array | no | `["info","admin","sales","support","contact","noreply","help","webmaster","postmaster"]` | Prefijos de la parte local (antes de la @) que se marcan como cuentas de rol |
| format | string | no | human | Formato de salida: `human` o `json` |

## Seguridad

> ℹ️ Skill de solo lectura: no ejecuta mutaciones. Puedes usarla en cualquier momento sin riesgo. No se envía ningún correo ni se cambia el consentimiento de marketing de nadie.

## Reglas de detección

Para cada correo de cliente, aplica estas revisiones en orden y asigna una o más marcas:

1. **`invalid_syntax`**: no pasa la validación de parte local o dominio según RFC 5322, le falta la `@`, tiene espacios, puntos dobles o un punto al inicio o al final
2. **`role_account`**: la parte local coincide exactamente con una entrada de `role_localparts` (sin distinguir mayúsculas)
3. **`disposable_domain`**: el dominio está en la lista de dominios desechables (mailinator, guerrillamail, dominios tipo tempmail, etc.)
4. **`plus_alias`**: tiene un `+` en la parte local (informativo; por sí solo no afecta la entregabilidad, pero sirve para eliminar duplicados)
5. **`bounce_suspect`**: heurísticas: parte local solo con números, más de 64 caracteres, TODO EN MAYÚSCULAS, caracteres repetidos (`aaaaa`), secuencias de teclado (`asdfghjk`)
6. **`duplicate`**: el mismo correo normalizado ya apareció en el grupo de clientes

Un cliente puede tener varias marcas; la más grave (`invalid_syntax` > `bounce_suspect` > `disposable_domain` > `role_account` > `plus_alias`) define la acción recomendada.

## Pasos

1. **OPERACIÓN:** `customers` — consulta
   **Entradas:** `first: 250`, campos `id`, `defaultEmailAddress { emailAddress, marketingState }`, `numberOfOrders`, `tags`, cursor de paginación. Si `marketing_consent_only: true`, filtra con `query: "email_marketing_state:subscribed"`
   **Resultado esperado:** Todos los clientes objetivo que tienen correo; pagina hasta `hasNextPage: false`

2. Aplica las reglas de detección a cada correo y reúne las marcas

3. Suma los conteos por marca y arma la lista de supresión

## Operaciones GraphQL

```graphql
# customers:query — validada con api_version 2025-01
query DeliverabilityAudit($query: String, $after: String) {
  customers(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        displayName
        defaultEmailAddress {
          emailAddress
          marketingState
        }
        numberOfOrders
        amountSpent {
          amount
          currencyCode
        }
        tags
        createdAt
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

## Seguimiento de la sesión

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

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════════╗
║  SKILL: Correos de clientes que no van a llegar  ║
║  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 de las entradas clave>
          → Resultado: <cantidad o desenlace>
```

**Al terminar**, muestra:

Para `format: human` (predeterminado):
```
══════════════════════════════════════════════
AUDITORÍA DE ENTREGABILIDAD DE CORREOS
  Clientes revisados:      <n>
  Clientes suscritos:      <n>
  ─────────────────────────────
  Sintaxis inválida:       <n> (<pct>%)   🔴 suprimir
  Cuentas de rol:          <n> (<pct>%)   ⚠️ suprimir
  Dominios desechables:    <n> (<pct>%)   ⚠️ suprimir
  Patrones de rebote:      <n> (<pct>%)   ⚠️ revisar
  Alias con +:             <n> (<pct>%)   ℹ️ informativo
  Duplicados:              <n> (<pct>%)   ℹ️ informativo

  Supresión recomendada:   <n>  (<pct>% de los suscritos)
  Archivo: deliverability_audit_<fecha>.csv
══════════════════════════════════════════════
```

Para `format: json`, muestra:
```json
{
  "skill": "shopify-auditoria-correos-clientes",
  "store": "<dominio>",
  "customers_scanned": 0,
  "flags": {
    "invalid_syntax": 0,
    "role_account": 0,
    "disposable_domain": 0,
    "bounce_suspect": 0,
    "plus_alias": 0,
    "duplicate": 0
  },
  "recommended_suppressions": 0,
  "output_file": "deliverability_audit_<fecha>.csv"
}
```

## Formato de salida
Archivo CSV `deliverability_audit_<AAAA-MM-DD>.csv` con las columnas:
`customer_id`, `email`, `flags`, `recommended_action`, `marketing_state`, `order_count`, `total_spent`, `created_at`

`recommended_action` toma uno de estos valores: `suppress` (suprimir), `review` (revisar), `keep` (conservar).

## Manejo de errores
| Error | Causa | Solución |
|-------|-------|----------|
| `THROTTLED` | Se superó el límite de solicitudes de la API | Espera 2 segundos y reintenta hasta 3 veces |
| Cliente sin correo | Cuenta que solo tiene teléfono o que se creó en el punto de venta | Omítelo; no lo incluyas en la lista de supresión |
| Lista de desechables desactualizada | Un dominio temporal nuevo no está en la lista incluida | Puedes reemplazarla con el parámetro `disposable_domains` |
| Partes locales con Unicode | Direcciones de correo internacionalizadas | Normaliza con NFC; no marques dominios IDN válidos |

## Buenas prácticas
- Ejecútala antes de cada envío promocional grande: tasas de correos inválidos o de rebote por encima del 2 % ponen en riesgo la reputación de tu dominio de envío.
- Trata las marcas `role_account` como supresión suave: esas direcciones casi nunca dan un consentimiento real para marketing y con frecuencia marcan los correos como spam.
- Vuelve a auditar cada trimestre aunque la lista de clientes no cambie: las listas de reputación de dominios cambian y los proveedores de correo desechable suman dominios nuevos.
- Combínala con `shopify-consentimiento-marketing` para confirmar que el estado de consentimiento coincide con lo que tiene registrado tu proveedor de email marketing.
- Entrega el CSV de supresión a la función de importar lista de supresión de tu proveedor de email; no borres clientes de Shopify solo por lo que diga esta auditoría.
