| --- |
| title: FlexiGo Support Bot |
| emoji: 💬 |
| colorFrom: red |
| colorTo: yellow |
| sdk: docker |
| app_port: 7860 |
| pinned: false |
| --- |
| |
| # Shopify Support Chatbot |
|
|
| Chatbot de soporte embebible para tiendas **Shopify**. Responde dudas de |
| **información** (catálogo en vivo + base de conocimiento de PDFs/URLs) y de |
| **pedidos** (estado y nº de seguimiento, con verificación de identidad), en el |
| **idioma del cliente**. Cerebro LLM **gratis** (Groq con failover a Cloudflare |
| Workers AI), embeddings **locales**. Pensado para una tienda y reutilizable. |
|
|
| > Diseño: [`docs/superpowers/specs/2026-06-09-shopify-support-chatbot-design.md`](docs/superpowers/specs/2026-06-09-shopify-support-chatbot-design.md) |
| > Plan: [`docs/superpowers/plans/2026-06-09-shopify-support-chatbot.md`](docs/superpowers/plans/2026-06-09-shopify-support-chatbot.md) |
|
|
| ## Arquitectura |
|
|
| ``` |
| Widget (Theme App Extension) ──/apps/chat (App Proxy, sin CORS, HMAC)──► FastAPI |
| │ |
| ┌────────────────────────────────────────────────────────────────────┐ │ |
| │ Orquestador (tool-calling) │ │ |
| │ • search_knowledge → RAG (pgvector + embeddings locales) │ │ |
| │ • search_products → Shopify GraphQL Admin API │ │ |
| │ • lookup_order → Shopify GraphQL + verificación de identidad │ │ |
| │ • escalate_to_human → email al equipo │ │ |
| │ LLM: Groq (primario) → Cloudflare Workers AI (failover) │ │ |
| └────────────────────────────────────────────────────────────────────┘ │ |
| Postgres + pgvector ◄──────────────────────┘ |
| ``` |
|
|
| ## Stack |
| Python 3.12 · FastAPI · SQLAlchemy 2 (async) · Postgres + pgvector · Alembic · |
| fastembed (ONNX, multilingüe) · httpx · pytest. Gestor: **uv**. |
|
|
| ## Desarrollo local |
|
|
| ```bash |
| uv sync # crea el venv (Python 3.12) e instala dependencias |
| cp .env.example .env # rellena las claves (ver abajo) |
| uv run uvicorn app.main:app --reload |
| # Tests: |
| uv run pytest # suite completa (incluye el test lento del embedder) |
| uv run pytest -m "not slow" # rápido (sin cargar el modelo de embeddings) |
| uv run ruff check . # lint |
| ``` |
| Sin Postgres local puedes usar sqlite para una prueba rápida: |
| `DATABASE_URL=sqlite+aiosqlite:///./dev.db` (pgvector solo en Postgres; en sqlite |
| la búsqueda RAG usa coseno en Python). |
|
|
| ## Claves LLM (gratis) |
|
|
| - **Groq** (primario): crea una API key en <https://console.groq.com> (gratis, sin |
| tarjeta). Uso comercial permitido y **no entrena con tus datos**. → `GROQ_API_KEY`. |
| - **Cloudflare Workers AI** (failover): Account ID + API token de Workers AI. |
| Gratis (10.000 neuronas/día), **no entrena con tus datos**. → |
| `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_API_TOKEN`. |
|
|
| Mismos modelos Llama 3.3 70B / 3.1 8B en ambos, así que el failover es transparente. |
| **Camino de upgrade** si la tienda crece: Groq de pago, o Cloudflare con facturación, |
| o Gemini de pago — basta cambiar variables de entorno (`LLM_PROVIDER_ORDER` + claves). |
|
|
| Embeddings: modelo multilingüe local (`fastembed`), 0 €, sin enviar datos a terceros. |
|
|
| ## 🚀 Despliegue (multi-tenant: el cliente no toca nada) |
|
|
| **Modelo:** NOSOTROS alojamos **un solo backend** que sirve a **todos los clientes** |
| (cada uno es un *tenant*). El cliente solo recibe **una línea** para pegar (o se la |
| pegamos). Cero infraestructura, cero claves, cero Railway para el cliente. |
|
|
| ### Una vez (nosotros) — desplegar el backend |
| 1. Desplegar este repo en Railway (usa [`railway.json`](railway.json): migraciones + |
| uvicorn + healthcheck `/healthz`, automático). |
| 2. Volumen en `/app/data` (SQLite + caché del modelo). |
| 3. Variables: `GROQ_API_KEY` (nuestra), `ADMIN_TOKEN` (nuestra), `SECRET_KEY` (cifra |
| los secretos de los tenants), `DATABASE_URL=sqlite+aiosqlite:////app/data/bot.db`. |
| (Opcional `CLOUDFLARE_*` para el failover.) |
|
|
| ### Por cada cliente (alta de 5 min, en `/admin/`) |
| 1. Entrar en `https://NUESTRO_BACKEND/admin/` con el `ADMIN_TOKEN`. |
| 2. **Crear la tienda** (slug, p.ej. `toorx`), poner nombre/color/bienvenida. |
| 3. Subir sus **PDFs/URLs** (base de conocimiento, aislada por tenant). |
| 4. (Opcional, para pedidos) pegar las credenciales de su **custom app de Shopify** |
| (`shop`, `client_id`, `client_secret` — se guarda **cifrado**). Sin esto = bot solo-info. |
| 5. Copiar la **línea de incrustación** que muestra el panel: |
|
|
| ```html |
| <script src="https://NUESTRO_BACKEND/widget.js?t=toorx" defer></script> |
| ``` |
|
|
| ### El cliente — pega 1 línea |
| En su tema de Shopify (**Online Store → Themes → Edit code → `theme.liquid`**, antes |
| de `</body>`), pega esa línea. **Fin.** El widget se sirve solo, detecta su backend y |
| su tienda por el `?t=`, lee su marca de `/widget-config` y habla con `/chat` (CORS). |
|
|
| > Aislamiento: la base de conocimiento, sesiones y pedidos de cada tenant están |
| > separados por `tenant_id`; una tienda nunca ve los datos de otra. |
| |
| ### (Opcional) Modo seguro con App Proxy |
| Si un cliente quiere firmas HMAC + `logged_in_customer_id` en vez del `<script>`: |
| desplegar `extension/` con `shopify app deploy`, configurar el App Proxy |
| (`subpath=chat`, `prefix=apps`, URL → `/apps/chat`) y activar el bloque en *App embeds*. |
| `/apps/chat` resuelve el tenant por el `shop` firmado. |
|
|
| ### (Opcional) Postgres + pgvector a escala |
| Cambia `DATABASE_URL` a Postgres; la migración crea la extensión `vector` y usa |
| búsqueda vectorial nativa. (En SQLite la búsqueda RAG usa coseno en Python.) |
|
|
| ## Privacidad / GDPR |
| - LLMs sin entrenamiento con datos (Groq + Cloudflare) → seguro para datos de pedidos. |
| - Verificación por niveles: email + nº de pedido; solo se revela estado de envío + |
| seguimiento (nunca dirección completa ni pago). Errores genéricos + bloqueo por |
| intentos. |
| - Retención: las sesiones/mensajes se purgan automáticamente a los |
| `SESSION_RETENTION_DAYS` días. |
|
|