Guía Frontend: Comprar número Twilio y vincularlo a un Agente de Voz (n8n vs Backend)
Esta guía es para el equipo frontend: implementa en UI el flujo completo de:
- Comprar un número de teléfono (Twilio) para el usuario
- Elegir el Agente de Voz que atenderá llamadas entrantes en ese número:
- CLIA Voice Agent (n8n)
- CLIA Voice Agent (Backend Streaming)
Nota de arquitectura: la “vinculación con agente” se aplica configurando el VoiceUrl del número en Twilio, pero a nivel de producto se presenta como elegir entre dos agentes de voz.
0) Prerrequisitos (Frontend)
- Tener JWT del usuario ().text
Authorization: Bearer ... - Conocer .text
userId - El usuario debe tener (incluye Free si está activado) para poder buscar/comprar números.text
subscriptionStatus: "active" - Para compra: el usuario debe tener balance suficiente para el cargo único (default $5).
1) UI recomendada (pantalla “Voice / Phone Number”)
Sección A — Estado actual
Mostrar:
- Número actual: (si existe)text
user.twilioNumber - Estado de número: (active/suspended)text
user.twilioNumberStatus - Saldo: +text
voiceBalance(para explicar por qué no puede comprar)textcreditLimit - Agente de voz seleccionado:
- si el usuario ya tiene número, el backend persiste (source of truth).text
user.voiceAgentId
- si el usuario ya tiene número, el backend persiste
Sección B — Seleccionar agente de voz
Mostrar un selector con 2 agentes (card o radio):
- text
CLIA Voice Agent (n8n) - text
CLIA Voice Agent (Backend Streaming)
Cómo obtenerlos:
- (o filtrar portext
GET /agents/catalog?interactionMode=voiceytextagentType=voice-assistant)textinteractionMode=voice
Recomendación: filtra por
para no mezclar chat.textinteractionMode === "voice"
Sección C — Comprar número
Wizard:
- Seleccionar país / area code (opcional)
- Buscar números disponibles
- Elegir número y confirmar compra
- Si falta “Emergency Address”, redirigir al paso de configurarlo
- Comprar (y configurar webhooks según el agente seleccionado)
2) Buscar números disponibles
Endpoint:
- text
GET /users/:userId/twilio/numbers/available?country=US&areaCode=415&limit=10
Headers:
- text
Authorization: Bearer <jwt>
UI:
- Lista con ,text
phoneNumber,textlocality,textregion.textcapabilities - Botón “Seleccionar”.
Errores:
- 403: no estext
subscriptionStatus.textactive
3) Emergency Address (E911)
La compra puede fallar si el usuario no tiene Emergency Address configurada.
Endpoints:
- text
POST /users/:userId/twilio/emergency-address - text
GET /users/:userId/twilio/emergency-address
UI mínima:
- Form con ,text
customerName,textstreet,textcity,textregion,textpostalCodetextisoCountry - Mostrar estado text
pending|validated|invalid
Comportamiento recomendado:
- Antes de comprar, llama text
GET /users/:userId/twilio/emergency-address- Si no existe, obliga a completar el form
4) Comprar el número y vincularlo al agente de voz
Endpoint:
- text
POST /users/:userId/twilio/purchase
Headers:
- text
Authorization: Bearer <jwt> - text
Content-Type: application/json
Body (ejemplo - recomendado usando
agentIdjson{ "country": "US", "areaCode": "415", "phoneNumber": "+14155550123", "agentId": "AGENT_ID_DEL_CATALOGO_DE_VOZ" }
Alternativa legacy (compatibilidad):
useStreamingAgentjson{ "country": "US", "areaCode": "415", "phoneNumber": "+14155550123", "useStreamingAgent": true }
Mapping: agente seleccionado → request (recomendado)
- Si el usuario eligió CLIA Voice Agent (n8n) → enviar de ese agentetext
agentId - Si el usuario eligió CLIA Voice Agent (Backend Streaming) → enviar de ese agentetext
agentId
Respuesta:
- ,text
phoneNumber,textsid,textpurchaseCost,textmonthlyCost, etc.textremainingBalance
Errores comunes:
- 400 : mostrar CTA “Configurar Emergency Address”.text
Emergency address required - 400 : bloquear compra y mostrar “Liberar número” (si aplica).text
User already has a Twilio number assigned - 402 : llevar a recarga/billing.text
Insufficient balance
5) Cambiar el Agente de Voz después de comprar
Si el usuario ya tiene número comprado, puede cambiar de agente (reconfigura el VoiceUrl en Twilio):
- text
PUT /users/:userId/twilio/agent
Body:
json{ "agentId": "AGENT_ID_DEL_CATALOGO_DE_VOZ" }
Alternativa legacy:
json{ "useStreamingAgent": true }
Respuesta incluye:
- :text
agentTypeotext"streaming"text"n8n" - : la URL configurada en Twiliotext
voiceWebhookUrl - : eltext
agentIdpersistido/seleccionado (si está disponible)textAgent._id
UI:
- Mostrar confirmación “Agente actualizado”.
- Mostrar como información diagnóstica.text
voiceWebhookUrl
6) Prueba rápida (manual)
- Comprar número
- Seleccionar agente
- Llamar al número y verificar:
- Agente n8n: flujo controlado por workflow
- Agente backend: flujo (barge-in disponible)text
media-stream-*
7) Nota sobre “2 agentes” en catálogo
Para que el frontend pueda mostrar ambos como seleccionables:
- Ambos deben existir como de tipo voz en BD (system agents).text
Agent - Si el ambiente no los tiene, correr el seed:
- text
npx ts-node src/scripts/seed-system-agents.ts