Ir al contenido
Guía

Recepcionista con IA para Twilio en Node.js con Wixzel Voice

Al final, las llamadas a tu número actual de Twilio las atiende un recepcionista de IA que tú creaste: saluda a quien llama, responde según tus instrucciones y agenda citas que puedes consultar desde la API. Lleva unos 30 minutos en Node.js, con el SDK wixzel-voice para TypeScript y JavaScript y una troncal Elastic SIP de Twilio. El tiempo de motor con el motor classic cuesta $0.0867 por minuto conectado, unos $0.26 por una llamada de tres minutos, facturado por segundo desde un saldo prepago. Twilio te factura directamente los minutos de la troncal, sin margen.

Por · Publicado el · Actualizado el

Duración
Unos 30 minutos
Motor
classic
Tiempo de motor
$0.0867 por minuto conectado

¿Qué necesitas antes de empezar?

  • Una cuenta de Twilio con Elastic SIP Trunking y un número de teléfono de Twilio.
  • Una clave de API de Wixzel Voice (wv_live_…) y crédito en la cuenta. La recarga mínima es de $5.
  • Node.js 20 o posterior.

¿Cómo construyes esto en Wixzel Voice, paso a paso?

  1. 01Crea la troncal Elastic SIP en Twilio

    En la consola de Twilio, abre Elastic SIP Trunking y crea una troncal. En Termination, elige un Termination SIP URI, como your-clinic.pstn.twilio.com. Ese nombre de host es el host de la troncal que conectas en el siguiente paso.

    Deja abierta la consola de Twilio. Volverás a ella cuando la API te haya dado las dos direcciones que tienes que introducir.

  2. 02Instala el SDK y conecta la troncal

    Instala el SDK y pon tu clave de API en el entorno:

    shell
    npm install wixzel-voice
    export WIXZEL_API_KEY="wv_live_..."
    trunk.mjs
    import { WixzelVoice } from 'wixzel-voice';
    
    const client = new WixzelVoice({ apiKey: process.env.WIXZEL_API_KEY });
    
    const trunk = await client.sipTrunks.create({
      name: 'Twilio',
      host: 'your-clinic.pstn.twilio.com', // your Termination SIP URI
      port: 5060,
      transport: 'udp',
    });
    
    console.log('TRUNK_ID', trunk.id);
    console.log('Allowlist at Twilio:', trunk.platform_ip);
    console.log('Origination URI:', trunk.origination_uri);

    Aquí no hay usuario ni contraseña porque Twilio autoriza por IP de origen, que es el siguiente paso. Para usar una Credential List de Twilio, pasa su username y su password. La contraseña se guarda cifrada y la API no la vuelve a devolver nunca.

  3. 03Apunta Twilio a Wixzel Voice, en ambas direcciones

    Twilio configura las llamadas salientes y las entrantes por separado, y cada dirección falla sin avisar cuando falta su configuración.

    En Termination, y luego en Authentication, añade la platform_ip que se imprimió arriba a una IP Access Control List. Sin ella, Twilio rechaza las llamadas en un segundo aproximadamente con la causa de colgado 21.

    En Origination, añade un Origination SIP URI con el valor del origination_uri que se imprimió arriba. Sin él, tu número nunca llega al agente y no aparece nada en ninguno de los dos logs, porque la llamada nunca sale de Twilio.

    Por último, asocia tu número de Twilio a esta troncal en Numbers.

  4. 04Crea el recepcionista

    Un agente se compone de unas instrucciones (prompt), una frase de apertura y un motor de voz. appointment_booking_enabled le permite listar, agendar y cancelar citas durante la llamada; las instrucciones le dicen qué días, qué horario y qué duración de cita puede ofrecer.

    agent.mjs
    import { WixzelVoice } from 'wixzel-voice';
    
    const client = new WixzelVoice({ apiKey: process.env.WIXZEL_API_KEY });
    
    const agent = await client.agents.create({
      name: 'Reception',
      system_prompt: [
        'You are the receptionist for Riverside Dental, answering the phone.',
        'Keep every reply to one or two short sentences, and never read out lists.',
        'You can book, move and cancel check-ups and cleanings.',
        'Offer appointments Monday to Friday, 09:00 to 17:00, 30 minutes each.',
        'Before booking, ask for the full name of the caller and repeat the day and time back.',
        'For a dental emergency, tell the caller to hang up and ring the emergency number.',
        'If you cannot help, take a message and promise a callback.',
      ].join('\n'),
      opening_message: 'Riverside Dental, this is the automated assistant. How can I help?',
      appointment_booking_enabled: true,
      voice: {
        stt: { model: 'deepgram/nova-3', language: 'en-US' },
        llm: { model: 'openrouter/gpt-4o-mini' },
        tts: { model: 'elevenlabs/eleven_flash_v2_5' },
      },
    });
    
    console.log('AGENT_ID', agent.id);

    Este es el motor classic: Deepgram Nova-3, GPT-4o-mini y ElevenLabs Flash v2.5, la combinación fiable más barata para inglés, a $0.0867 por minuto. Añade una voice al bloque tts para elegir la voz; client.engines.voices('classic') lista las que puede usar.

    La frase de apertura dice que quien llama está hablando con un asistente automático. Donde la ley lo exige, o exige avisar de que la llamada se graba, ese aviso va en la frase de apertura.

  5. 05Enruta tu número al recepcionista

    Registra el número en la troncal, con el agente como el que lo atiende:

    number.mjs
    import { WixzelVoice } from 'wixzel-voice';
    
    const client = new WixzelVoice({ apiKey: process.env.WIXZEL_API_KEY });
    
    const number = await client.phoneNumbers.create({
      phone_number: '+14155550100', // your Twilio number, in E.164
      sip_trunk_id: process.env.TRUNK_ID,
      inbound_agent_id: process.env.AGENT_ID,
    });
    
    console.log('NUMBER_ID', number.id);

    Sin un inbound_agent_id, las llamadas entrantes a un número se rechazan. Para que el mismo agente también haga llamadas, para recordatorios o una llamada de prueba, haz que el número sea su identificador de llamada con client.agents.update(agentId, { outbound_phone_number_id: number.id }).

  6. 06Llama y luego consulta la llamada y la cita

    Llama a tu número de Twilio desde un teléfono móvil y reserva un horario. Al colgar, la llamada y la cita ya están en la API:

    results.mjs
    import { WixzelVoice } from 'wixzel-voice';
    
    const client = new WixzelVoice({ apiKey: process.env.WIXZEL_API_KEY });
    
    // Lists are newest first.
    const calls = await client.calls.list({ direction: 'inbound', limit: 1 });
    const latest = calls.data[0];
    if (latest) {
      const call = await client.calls.retrieve(latest.id);
      console.log(call.status, call.duration_seconds + 's', (call.cost_micros ?? 0) / 1e6, 'USD');
      for (const line of call.transcript) console.log(line.role + ': ' + line.content);
    }
    
    const appointments = await client.appointments.list({ limit: 5 });
    for (const a of appointments.data) {
      console.log(a.date_time, a.client_name, a.phone_number, a.status);
    }

    date_time siempre está en UTC. Cada reserva también dispara el webhook appointmentBooked, que es la forma de copiarla a tu propio calendario en el momento.

¿Cuánto cuesta esto en Wixzel Voice?

Tiempo de motor para llamadas de 3 minutos con el motor classic a $0.0867 por minuto conectado: unos $0.26 por llamada. La telefonía es tu propia troncal con la tarifa de tu operador y no está incluida.

Costo mensual de motor de lo que construye esta guía
Llamadas al mesMinutos conectadosCosto de motor al mes
200600$52.02
10003000$260
30009000$780

Wixzel Voice factura solo el tiempo de motor, por segundo de llamada, desde un saldo prepago. Twilio factura los minutos de Elastic SIP Trunking a tu cuenta de Twilio con tus tarifas de Twilio; Wixzel Voice nunca ve ese cargo ni le añade margen.

Prepago, sin suscripción y sin plan gratuito: agrega crédito desde $5 y el uso lo va consumiendo. Calcula tu propia combinación.

¿Qué límites de Wixzel Voice se aplican a esto?

  • El recepcionista conoce tu horario por sus instrucciones. La API v1 no tiene un endpoint de disponibilidad, así que no puede ver tu calendario real: rechaza un horario ya reservado desde la API, pero no ve las citas que gestionas en otro sitio.
  • Las reservas se interpretan en la zona horaria de la cuenta, que es UTC salvo que se haya cambiado, y la API v1 todavía no permite cambiarla. Revisa el date_time de tus primeras reservas antes de confiar en ellas, y escribe a aqeel@wixzel.com si tu negocio no está en UTC.
  • Por defecto, cada cuenta puede tener cinco llamadas en curso a la vez. Las demás se rechazan hasta que termine una, y el límite se amplía a petición.
  • Tu número sigue en Twilio. Wixzel Voice no vende, porta ni aloja números.
  • Los cambios de comportamiento de Wixzel Voice se publican detrás de un encabezado Wixzel-Version con fecha.

Preguntas frecuentes

¿Puedo crear un recepcionista de IA en Twilio?

Sí. Conecta tu troncal Elastic SIP de Twilio a Wixzel Voice, añade la IP de la plataforma a la lista de permitidas en Termination, configura el Origination SIP URI y registra tu número de Twilio con un inbound_agent_id. A partir de ahí, las llamadas al número las atiende tu agente, y Twilio sigue facturándote la troncal directamente.

¿Tengo que sacar mi número de Twilio?

No. El número sigue en tu cuenta de Twilio, asociado a tu troncal Elastic SIP. Wixzel Voice no vende, porta ni aloja números.

¿Por qué mi número de Twilio no llega al agente?

Normalmente falta el Origination SIP URI, o el número no está asociado a la troncal. La entrega de llamadas entrantes se configura aparte de las salientes y, sin ella, Twilio no tiene adónde enviar la llamada, así que no aparece nada en ninguno de los dos logs. El URI debe coincidir con el origination_uri de la troncal, y el número necesita un inbound_agent_id.

¿Cuánto cuesta una llamada de un recepcionista de IA?

Con el motor classic, $0.0867 por minuto conectado, unos $0.26 por una llamada de tres minutos, facturados por segundo desde crédito prepago. Los minutos de la troncal los factura Twilio con tus tarifas.

¿Hay SDK para lenguajes distintos de JavaScript?

Hay dos SDK oficiales: wixzel-voice en npm para TypeScript y JavaScript, y wixzel_voice en pub.dev para Dart y Flutter. Otros lenguajes llaman directamente a la misma API HTTP, descrita por el documento OpenAPI en https://docs.voice.wixzel.com/api-reference.

Dónde leer más

  • Troncales SIPdocumentación

    La sección de Twilio: IP ACL, Termination URI, identificador de llamada y Origination URI.

  • Agentesdocumentación

    Instrucciones, frases de apertura, de dónde sale el valor de cada campo y llamadas de prueba.

  • Webhooksdocumentación

    appointmentBooked, callCompleted, firmas y reintentos.

  • SDKdocumentación

    Los SDK de TypeScript y Dart.

API para telefonía con agentes

Acerca de Wixzel Voice

Wixzel Voice es una API de IA de voz para crear agentes de IA que hacen y contestan llamadas telefónicas reales a través de tu propia troncal SIP, o que hablan con personas en tus apps web y móviles. Una clave de API y un saldo prepagado cubren todos los motores de voz, con cobro por segundo de uso real.

Dale a Claude una línea telefónica con el MCP de Wixzel Voice

Claude, en Claude Code o claude.ai, haciendo una llamada real por tu troncal SIP y leyéndote la transcripción, con una confirmación antes de marcar.

Agente telefónico en hindi y malayalam con sarvam en Wixzel Voice

Dos agentes telefónicos, uno en hindi y otro en malayalam, con los modelos de Sarvam para idiomas de la India, que atienden o hacen llamadas por tu troncal SIP.

Añade un agente de voz a Flutter por WebSocket con Wixzel Voice

Una app Flutter en la que los usuarios hablan con tu agente de voz por WebSocket, con la clave de API guardada en tu servidor y sin ningún número de teléfono.

Gemini Live en una llamada real con la API de Wixzel Voice

Un agente Gemini Live llamando a un teléfono real por tu troncal SIP a partir de cuatro peticiones cURL, y el registro de la llamada con su transcripción y su costo.

Haz una campaña de calificación de leads con IA con Wixzel Voice

Una lista de leads llamados por tu agente a través de tu troncal SIP, en lotes ajustados a tu límite de llamadas simultáneas, con el estado y la transcripción de cada llamada.

Añade una mascota de IA que habla a tu web con Wixzel Voice

Una mascota que habla en la esquina de tu sitio web, a la que los visitantes llaman desde el navegador, limitada a tus dominios y a tus límites diarios, con cada persona que llama registrada.

Muestra la mascota de tu agente en Flutter con Wixzel Voice

Una pantalla de Flutter con la mascota de tu agente, que mueve la boca con la voz del agente durante una llamada en tiempo real, con tu clave de API guardada en tu servidor.