Un agente de soporte al cliente autónomo que monitorea Gmail, consulta Shopify en tiempo real y redacta respuestas inteligentes.
Características •f Instalación • Configuración • Uso • API • Personalización
Este repositorio contiene un Agente de Soporte al Cliente Autónomo construido con Python, FastAPI y OpenAI.
El sistema:
- 📧 Monitorea una bandeja de entrada de Gmail
- 🏷️ Clasifica correos entrantes por categoría
- 🔍 Consulta datos en tiempo real de Shopify (pedidos, stock, políticas)
- ✍️ Redacta borradores de respuesta inteligentes y personalizados
⚠️ Human-in-the-loop: Este agente NO envía correos automáticamente. Crea borradores en Gmail para revisión humana antes del envío.
- Lee correos no leídos automáticamente
- Gestiona hilos de conversación para mantener contexto
- Crea borradores de respuesta (no envía directamente)
- Marca correos procesados como leídos
- Router inteligente que clasifica intenciones del usuario
- 9 categorías especializadas de soporte
- Function Calling para consultas a APIs externas
- Detección automática de idioma y respuesta en el mismo idioma
| Funcionalidad | Descripción |
|---|---|
| 📦 Pedidos | Rastreo en tiempo real, estado de envío, tracking |
| 📊 Inventario | Stock por variante, alertas de agotado |
| 🏷️ Metafields | Instrucciones de lavado, materiales, compresión |
| 👤 Clientes | Perfil VIP, LTV, historial de compras |
| 💰 Descuentos | Códigos activos, reglas de precio |
| 📜 Políticas | Devoluciones, envíos, términos |
- Filtrado de dominios maliciosos y phishing
- Detección de correos B2B/Marketing
- Bloqueo de emails automatizados del sistema
- Validación de email para consultas de pedidos
graph TB
subgraph "📧 Email Input"
Gmail["Gmail API<br/>(Email Worker)"]
end
subgraph "🖥️ Frontend (Opcional)"
User("👤 End User") <-->|HTTP/JSON| Chat["Chat Endpoint<br/>(/chat)"]
end
subgraph "⚙️ Backend Infrastructure"
Gmail -->|Polling cada 60s| Security["🛡️ Gatekeeper<br/>(Spam Filter)"]
Security -->|PROCESS| Router["🧠 Main Router<br/>(Classifier)"]
Security -->|IGNORE| Trash["🗑️ Mark as Read"]
Chat --> Router
Router --> Agents["👥 Specialized Agents<br/>(9 Categories)"]
Agents <-->|Function Calling| Tools["🔧 Tools Engine"]
end
subgraph "🤖 AI Layer"
Router <-->|Classification| OpenAI["OpenAI API<br/>(GPT-5.1 / GPT-5-mini)"]
Agents <-->|Generation| OpenAI
end
subgraph "🛍️ Data Sources"
Tools <-->|REST + GraphQL| Shopify["Shopify Admin API"]
Shopify --- Orders["📦 Orders"]
Shopify --- Products["🏷️ Products"]
Shopify --- Inventory["📊 Inventory"]
Shopify --- Customers["👤 Customers"]
end
subgraph "📤 Output"
Agents -->|Create Draft| Drafts["📝 Gmail Drafts"]
Drafts -->|Human Review| Send["✉️ Send Email"]
end
style Security fill:#ff6b6b,stroke:#333,stroke-width:2px
style Router fill:#4ecdc4,stroke:#333,stroke-width:2px
style OpenAI fill:#9b59b6,stroke:#333,stroke-width:2px
style Shopify fill:#96ceb4,stroke:#333,stroke-width:2px
sequenceDiagram
autonumber
participant G as 📧 Gmail
participant W as ⚙️ Email Worker
participant S as 🛡️ Gatekeeper
participant R as 🧠 Router
participant A as 👤 Agent
participant T as 🔧 Tools
participant AI as 🤖 OpenAI
participant SH as 🛍️ Shopify
loop Cada 60 segundos
W->>G: Buscar emails no leídos
G-->>W: Lista de mensajes
end
W->>G: Obtener contenido + historial del hilo
G-->>W: Email data
W->>S: Analizar seguridad
alt Email es Spam/Phishing
S-->>W: IGNORE
W->>G: Marcar como leído
else Email es de Partner
S-->>W: INTERNAL_ALERT
W->>G: Marcar como leído
else Email válido
S-->>W: PROCESS
W->>R: Clasificar mensaje
R->>AI: Determinar categoría
AI-->>R: Categoría (ej: ShippingDelivery)
R->>A: Activar agente especializado
A->>AI: Generar respuesta con tools
opt Si necesita datos
AI-->>A: Tool call request
A->>T: Ejecutar tool
T->>SH: Consultar API
SH-->>T: Datos (orden, stock, etc.)
T-->>A: Resultado JSON
A->>AI: Continuar con datos
end
AI-->>A: Respuesta final
A->>G: Crear borrador
W->>G: Marcar como leído
end
graph LR
subgraph "🧠 OpenAI Decision"
AI["gpt-5-mini"] -->|"tool_calls"| Decision{¿Necesita datos?}
end
Decision -->|No| Response["Respuesta directa"]
Decision -->|Sí| Tools
subgraph "🔧 Tools Disponibles"
Tools["Tools Engine"]
Tools --> T1["lookup_order_crm<br/>📦 Pedido + Cliente VIP"]
Tools --> T2["lookup_order_admin<br/>🚚 Estado + Tracking"]
Tools --> T3["lookup_product_intelligence<br/>🏷️ Stock + Metafields"]
Tools --> T4["lookup_product_stock<br/>📊 Inventario GraphQL"]
Tools --> T5["escalate_ticket_to_support<br/>🎫 Crear Ticket"]
end
subgraph "🛍️ Shopify API"
T1 & T2 -->|REST| Orders["/orders.json"]
T1 -->|REST| Customers["/customers.json"]
T3 -->|REST| Products["/products.json"]
T3 -->|REST| Metafields["/metafields.json"]
T3 & T4 -->|REST| Inventory["/inventory_levels.json"]
T4 -->|GraphQL| GQL["graphql.json"]
end
T1 & T2 & T3 & T4 & T5 -->|JSON Result| AI
AI --> FinalResponse["✉️ Respuesta Final"]
style AI fill:#9b59b6,stroke:#333
style Tools fill:#3498db,stroke:#333
style FinalResponse fill:#2ecc71,stroke:#333
graph TD
Input["📨 Mensaje Entrante"] --> Router["🧠 Router GPT"]
Router --> C1["📦 OrderPlacementStatus"]
Router --> C2["🚚 ShippingDelivery"]
Router --> C3["↩️ ReturnsCancellations"]
Router --> C4["💳 PaymentBilling"]
Router --> C5["🏷️ ProductInfo"]
Router --> C6["🔧 TechnicalIssues"]
Router --> C7["🎁 Promotions"]
Router --> C8["😤 Complaints"]
Router --> C9["👤 AccountOther"]
C1 --> Agent1["Agent: Order Detective<br/>Tools: lookup_order_crm"]
C2 --> Agent2["Agent: Shipping Specialist<br/>Tools: lookup_order_admin"]
C3 --> Agent3["Agent: Returns Solutionist<br/>Tools: lookup_order_crm"]
C4 --> Agent4["Agent: Billing Support<br/>Tools: lookup_order_crm"]
C5 --> Agent5["Agent: Product Expert<br/>Tools: lookup_product_intelligence"]
C6 --> Agent6["Agent: Tech Support<br/>Tools: escalate_ticket"]
C7 --> Agent7["Agent: Promotions Manager<br/>Tools: store_context"]
C8 --> Agent8["Agent: Escalation Manager<br/>Tools: escalate_ticket"]
C9 --> Agent9["Agent: General Assistant<br/>Tools: varies"]
style Router fill:#4ecdc4,stroke:#333,stroke-width:2px
style C1 fill:#74b9ff,stroke:#333
style C2 fill:#74b9ff,stroke:#333
style C3 fill:#74b9ff,stroke:#333
style C4 fill:#74b9ff,stroke:#333
style C5 fill:#74b9ff,stroke:#333
style C6 fill:#74b9ff,stroke:#333
style C7 fill:#74b9ff,stroke:#333
style C8 fill:#74b9ff,stroke:#333
style C9 fill:#74b9ff,stroke:#333
flowchart TD
Email["📧 Email Entrante"] --> Extract["Extraer: sender, subject, body"]
Extract --> Check1{"🚫 Dominio<br/>bloqueado?"}
Check1 -->|Sí| IGNORE1["🗑️ IGNORE"]
Check1 -->|No| Check2{"⚙️ Dominio<br/>de sistema?"}
Check2 -->|Sí| IGNORE2["🗑️ IGNORE"]
Check2 -->|No| Check3{"🤖 Prefijo<br/>automatizado?"}
Check3 -->|Sí| IGNORE3["🗑️ IGNORE"]
Check3 -->|No| Check4{"📧 Email gratuito<br/>+ keywords spam?"}
Check4 -->|Sí| IGNORE4["🗑️ IGNORE"]
Check4 -->|No| Check5{"🤝 Dominio<br/>de partner?"}
Check5 -->|Sí| ALERT["⚠️ INTERNAL_ALERT"]
Check5 -->|No| Check6{"🎣 Subject<br/>phishing?"}
Check6 -->|Sí| IGNORE5["🗑️ IGNORE"]
Check6 -->|No| Check7{"📝 Body<br/>spam B2B?"}
Check7 -->|Sí| IGNORE6["🗑️ IGNORE"]
Check7 -->|No| PROCESS["✅ PROCESS"]
IGNORE1 & IGNORE2 & IGNORE3 & IGNORE4 & IGNORE5 & IGNORE6 --> MarkRead["Marcar como leído"]
ALERT --> MarkRead
PROCESS --> AI["🧠 Procesar con IA"]
style PROCESS fill:#2ecc71,stroke:#333,stroke-width:2px
style ALERT fill:#f39c12,stroke:#333,stroke-width:2px
style IGNORE1 fill:#e74c3c,stroke:#333
style IGNORE2 fill:#e74c3c,stroke:#333
style IGNORE3 fill:#e74c3c,stroke:#333
style IGNORE4 fill:#e74c3c,stroke:#333
style IGNORE5 fill:#e74c3c,stroke:#333
style IGNORE6 fill:#e74c3c,stroke:#333
Email Worker detecta correo no leído
↓
Gatekeeper filtra spam/phishing
↓
Router clasifica categoría (9 tipos)
↓
Agente especializado procesa con contexto de tienda
↓
Tools ejecutan consultas a Shopify (si necesario)
↓
Se genera respuesta en idioma del cliente
↓
Borrador creado en Gmail → Humano revisa y envía
AI-Customer-Support-Agent/
├── main.py # Aplicación principal (FastAPI + Workers)
├── requirements.txt # Dependencias Python
├── .env.example # Plantilla de variables de entorno
├── .gitignore # Archivos ignorados por Git
├── README.md # Esta documentación
└── docs/ # Documentación adicional
├── SETUP_GMAIL.md
└── SETUP_SHOPIFY.md
- Python 3.10 o superior
- Cuenta de Shopify con acceso a Admin API
- API Key de OpenAI (recomendado: GPT‑5.1 o GPT‑5‑mini)
- Proyecto en Google Cloud con Gmail API habilitada (opcional, para Email Worker)
git clone https://github.com/hitthecodelabs/AI-Customer-Support-Agent.git
cd AI-Customer-Support-Agent# Crear entorno virtual
python -m venv venv
# Activar entorno
# Linux/macOS:
source venv/bin/activate
# Windows:
venv\Scripts\activatepip install -r requirements.txt# Copiar plantilla
cp .env.example .env
# Editar con tus credenciales
nano .env # o tu editor preferidoCrea un archivo .env basándote en .env.example:
# ═══════════════════════════════════════════════════════════
# SHOPIFY - Configuración de la tienda
# ═══════════════════════════════════════════════════════════
SHOPIFY_URL=tu-tienda.myshopify.com
SHOPIFY_TOKEN=shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SHOPIFY_API_VERSION=2025-10
# ═══════════════════════════════════════════════════════════
# OPENAI - Modelo de IA
# ═══════════════════════════════════════════════════════════
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
OPENAI_MODEL=gpt-5-mini # Opciones: gpt-5, gpt-5.1, gpt-5-mini
# ═══════════════════════════════════════════════════════════
# SEGURIDAD - Autenticación del endpoint /chat
# ═══════════════════════════════════════════════════════════
AGENT_SECRET=tu-secret-seguro-aqui
# ═══════════════════════════════════════════════════════════
# GMAIL - Credenciales OAuth (opcional, para Email Worker)
# ═══════════════════════════════════════════════════════════
# JSON en una sola línea con las credenciales OAuth
GOOGLE_TOKEN_JSON={"token":"...","refresh_token":"...","client_id":"...","client_secret":"...","token_uri":"https://oauth2.googleapis.com/token"}
# ═══════════════════════════════════════════════════════════
# WORKER - Configuración del procesamiento de emails
# ═══════════════════════════════════════════════════════════
EMAIL_CHECK_INTERVAL=60 # Segundos entre verificaciones- Accede a tu Admin de Shopify → Settings → Apps and sales channels
- Crear App personalizada:
- Click en Develop apps
- Create an app → nombra tu app
- En API credentials, configura los scopes:
read_orders, read_products, read_inventory,
read_customers, read_price_rules, read_policies
- Instalar y obtener token:
- Click en Install app
- Copia el Admin API access token (empieza con
shpat_)
- Configura en
.env:
SHOPIFY_URL=tu-tienda.myshopify.com
SHOPIFY_TOKEN=shpat_xxxxxxxxxxxxxxxxxxxxxSolo necesario si quieres habilitar el worker de emails automático.
- Ve a Google Cloud Console
- Crea un nuevo proyecto
- Habilita la Gmail API
- Ve a APIs & Services → Credentials
- Create Credentials → OAuth client ID
- Tipo: Desktop application
- Descarga el archivo
credentials.json
Ejecuta este script localmente para autenticarte:
# generate_token.py
from google_auth_oauthlib.flow import InstalledAppFlow
import json
SCOPES = [
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/gmail.modify",
"https://www.googleapis.com/auth/gmail.compose",
]
flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
creds = flow.run_local_server(port=0)
print(
json.dumps(
{
"token": creds.token,
"refresh_token": creds.refresh_token,
"token_uri": creds.token_uri,
"client_id": creds.client_id,
"client_secret": creds.client_secret,
}
)
)python generate_token.pyCopia el JSON generado (en una sola línea) a tu .env:
GOOGLE_TOKEN_JSON={"token":"ya29.xxx","refresh_token":"1//xxx","client_id":"xxx.apps.googleusercontent.com","client_secret":"xxx","token_uri":"https://oauth2.googleapis.com/token"}# Con hot-reload
uvicorn main:app --reload --port 8000uvicorn main:app --host 0.0.0.0 --port 8000Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]Build + Run:
docker build -t ai-support-agent .
docker run -p 8000:8000 --env-file .env ai-support-agentGET /Respuesta:
{
"status": "online",
"email_worker": "active"
}GET /healthRespuesta:
{
"status": "healthy",
"shopify_configured": true,
"openai_configured": true,
"gmail_configured": true,
"version": "1.0.0"
}POST /chat
Content-Type: application/json
X-Secret: tu-agent-secretBody:
{
"message": "¿Dónde está mi pedido #1234?",
"history": []
}Respuesta:
{
"response": "¡Hola! 💛 He encontrado tu pedido #1234...",
"category": "ShippingDelivery",
"history": [
{ "role": "user", "content": "¿Dónde está mi pedido #1234?" },
{ "role": "assistant", "content": "¡Hola! 💛 He encontrado tu pedido #1234..." }
]
}El agente clasifica automáticamente cada mensaje en una de estas categorías:
| Categoría | Descripción | Ejemplo de trigger |
|---|---|---|
| OrderPlacementStatus | Estado de pedidos | “¿Recibieron mi orden?” |
| ShippingDelivery | Envíos y tracking | “¿Dónde está mi paquete?” |
| ReturnsCancellationsExchanges | Devoluciones | “Quiero cancelar” |
| PaymentBilling | Pagos y facturación | “Me cobraron dos veces” |
| ProductInfoAvailability | Info de productos | “¿Tienen talla M?” |
| TechnicalIssues | Problemas técnicos | “No puedo pagar” |
| PromotionsDiscountsPricing | Descuentos | “Mi código no funciona” |
| CustomerComplaintsSatisfaction | Quejas | “Servicio terrible” |
| AccountProfileOther | Otros | “Cambiar contraseña” |
El agente puede ejecutar estas herramientas automáticamente:
| Tool | Descripción |
|---|---|
| lookup_order_crm | Busca pedido + perfil del cliente |
| lookup_order_admin | Estado de pedido en tiempo real |
| lookup_product_intelligence | Stock + metafields del producto |
| lookup_product_stock | Inventario con GraphQL |
| escalate_ticket_to_support | Crea ticket de escalación |
Edita COMMON_TONE en main.py:
COMMON_TONE = r'''
TONE & PERSONA:
- You are "Princess Carolyne", the Customer Success Manager at TuMarca.
- Tone: Friendly, professional, solution-oriented.
- Use emojis: 💛, 🙏, 😊
...
'''- Añade la categoría a
AGENT_CATEGORIES - Crea el prompt en
AGENT_PROMPTS - El router la detectará automáticamente
Edita EmailSecurityConfig:
class EmailSecurityConfig:
BLOCKED_DOMAIN_PATTERNS = [
"spam-domain.com",
"phishing-site.net",
]
INTERNAL_PARTNERS = [
"tu-proveedor.com",
"tu-agencia.com",
]Implementa _create_ticket_internal:
async def _create_ticket_internal(category, email, summary, priority):
# Integración con Zendesk, Freshdesk, etc.
async with httpx.AsyncClient() as client:
response = await client.post(
"https://tu-sistema.zendesk.com/api/v2/tickets",
json={"ticket": {"subject": summary, "...": "..."}},
headers={"Authorization": "Bearer xxx"},
)
return {"ticket_id": response.json()["id"]}- Conecta tu repositorio de GitHub
- Configura las variables de entorno en el dashboard
- Railway detecta automáticamente el
Procfileo usa:
uvicorn main:app --host 0.0.0.0 --port $PORT- Build Command:
pip install -r requirements.txt - Start Command:
uvicorn main:app --host 0.0.0.0 --port $PORT
fly launch
fly secrets set OPENAI_API_KEY=sk-xxx SHOPIFY_TOKEN=shpat_xxx ...
fly deployℹ️ [Email Worker] Deshabilitado (GOOGLE_TOKEN_JSON no configurado)
Solución: Verifica que GOOGLE_TOKEN_JSON esté correctamente configurado en .env.
❌ [Gmail] Error refrescando token
Solución: Regenera el token ejecutando generate_token.py localmente.
Solución:
- Verifica que el token empiece con
shpat_ - Confirma que la app tiene los scopes necesarios
Solución: Reduce el modelo a gpt-5-mini o implementa retry con backoff.
- Tiempo de respuesta promedio por categoría
- Tasa de escalación a humanos
- Distribución de categorías de emails
- Errores de tools (Shopify timeouts, etc.)
- Fork el repositorio
- Crea una rama:
git checkout -b feature/nueva-funcionalidad - Commit:
git commit -m "Agrega nueva funcionalidad" - Push:
git push origin feature/nueva-funcionalidad - Abre un Pull Request
Este proyecto está bajo la licencia MIT. Ver LICENSE para más detalles.
- OpenAI por la API de GPT
- FastAPI por el framework
- Shopify por la documentación de su API
¿Preguntas o sugerencias? Abre un issue.
⭐ Si este proyecto te fue útil, considera darle una estrella.