You are viewing the Spanish (Mexico) site, but your language preference is set to English. Switch to English site →

Menu

Expand
Calificar esta página:

Migración al SDK 2.0 de Voice para JavaScript

Se ha lanzado la versión 2.1.0 del SDK de Voice para JavaScript. Después de usar esta guía de migración para actualizar a la versión 2.0.1, dirígete a la página de registro de cambios para ver las novedades de la versión 2.1.0.

Puedes ver los detalles de las actualizaciones del SDK en el registro de cambios del repositorio de GitHub. Encontrarás la documentación completa de la API generada automáticamente en el sitio de páginas de GitHub.

En esta guía, verás referencias a una clase Call. Se trata de la clase Connection con otro nombre. Encontrarás más información en la guía que aparece a continuación.

Utiliza el nuevo módulo NPM en lugar de la CDN

El SDK de Voice para JavaScript está publicado en @twilio/voice-sdk. Los SDK 1.x seguirán estando disponibles como twilio-client.

Con el interés de promover las prácticas recomendadas, las versiones 2.0 y más recientes no se cargarán a la CDN de Twilio. Las versiones existentes (anteriores a la 2.0) y las versiones 1.x posteriores seguirán utilizándose a través de la CDN. Sin embargo, recomendamos encarecidamente no vincular de forma directa estos archivos en producción, ya que existe la posibilidad de interrupciones debido a cortes en la CDN.

Para los clientes que utilizan actualmente la CDN, hay un par de opciones para realizar el cambio:

  1. Si tu proyecto utiliza NPM, instala la última versión de @twilio/voice-sdk. Desde este momento, los archivos de distribución creados estarán disponibles en node_modules/@twilio/voice-sdk/dist.
  2. Si tu proyecto no utiliza NPM, puedes descargar el último artefacto creado y utilizarlo desde tus propios servidores. Cada versión tendrá su propia etiqueta en GitHub. Descarga la última versión (la etiqueta más reciente sin -rc), descomprímela y navega hasta /dist para encontrar los archivos twilio.js y twilio.min.js.

Deja de utilizar la instancia única Device y, en su lugar, crea una nueva instancia de Device

Se ha eliminado el comportamiento de instancia única de Device para favorecer el uso de las prácticas recomendadas. device.setup() ya no funcionará; en su lugar, se debe crear una instancia nueva de Device a través de new Device(token, options?).

const device = new Device(token, deviceOptions);

Deja de utilizar device.setup() y, en su lugar, utiliza device.updateOptions()

device.setup() ya no servirá para crear una instancia de Device.

Además, device.setup() ya no servirá para actualizar la instancia de Device después de su creación. En su lugar, utiliza device.updateOptions(deviceOptions) para actualizar cualquiera de las opciones de una instancia de Device después de crear una nueva instancia de Device.

Deja de escuchar device.on('ready')

Las instancias de Device ahora son de tipo lazy cuando se abre la conexión de señalización. Esto significa que el constructor Device es sincrónico y no hará que se abra un canal de señalización.

El WebSocket de señalización se abrirá en uno de los siguientes casos:

Si la aplicación debe supervisar el estado de registro de una instancia de Device, la instancia emite los siguientes eventos:

Para supervisar el estado de la conexión de señalización durante una llamada saliente cuando no está registrada (no se invocó device.register() para permitir que la instancia de Device recibiera llamadas entrantes), debes supervisar el estado de Call.

La lista completa de eventos de Device ahora es esta:

enum Device.EventName {
  Error = 'error',
  Incoming = 'incoming',
  Unregistered = 'unregistered',
  Registering = 'registering',
  Registered = 'registered',
  Destroyed = 'destroyed',
}

Asegúrate de que AccessToken esté actualizado

Ahora que la señalización es de tipo lazy, AccessToken se debe mantener actualizado con device.updateToken(accessToken) antes de registrarse (con device.register()) o iniciar una Call (Llamada) saliente (con device.connect()).

Un AccessToken caducado impedirá que se publiquen las estadísticas de Voice Insights. Este es un comportamiento existente desde la versión 1.x. En el futuro, a medida que exploremos la admisión de la reconexión de señalización, mantener actualizado este token será aún más importante para restaurar automáticamente la conexión con una Call (Llamada) o volver a registrar automáticamente el punto final.

A continuación, se muestra un ejemplo de cómo mantener el AccessToken actualizado:

const ttl = 600000; // 10 minutos
const refreshBuffer = 30000; // 30 segundos

const token = await getTokenViaAjax({ ttl });
const device = new Device(token);

setInterval(async () => {
  const newToken = await getTokenViaAjax({ ttl });
  device.updateToken(token);
}, ttl - refreshBuffer); // Nos brinda unos generosos 30 segundos de buffer

Actualiza las referencias al estado de Device

Los estados de Device han cambiado:

namespace Device {
  isBusy: boolean;
  enum State {
    Unregistered = 'unregistered';
    Registering = 'registering';
    Registered = 'registered';
    Destroyed = 'destroyed';
  }
}

Ya no incluimos el estado busy (ocupado) como parte del estado de Device; lo hemos movido al booleano device.isBusy.

El estado ready (preparado) ahora está representado por el estado Registered de Device.

El estado offline (preparado) ahora está representado por el estado Unregistered de Device.

Es importante mencionar que ready (preparado) y offline siempre han indicado el estado de registro, en lugar de indicar el estado de conexión. Este cambio en la versión 2 pretende aclarar esta confusión.

Actualiza los argumentos de device.connect() y call.accept()

El objeto AcceptOptions pasado a call.accept() ahora tiene las siguientes propiedades:

interface Call.AcceptOptions {
  /** 
    * Un RTCConfiguration para pasar al constructor RTCPeerConnection. 
    */
  rtcConfiguration?: RTCConfiguration;

  /**
   * MediaStreamConstraints para pasar a getUserMedia cuando se realiza o acepta una llamada. 
   */
  rtcConstraints?: MediaStreamConstraints;
}

El objeto ConnectOptions pasado a device.connect() extiende la interfaz AcceptOptions y agrega una propiedad opcional params:

interface Device.ConnectOptions extends Call.AcceptOptions {
 /**
  * Un objeto plano que contiene pares clave-valor que se enviarán a la app TwiML. 
  */
  params?: Record<string, string>;
}

Ten en cuenta que los objetos ahora pueden tomar MediaStreamConstraints. Por ejemplo:

device.connect({ To: 'client:alice' }, { deviceId: 'default' });

se puede reescribir como

device.connect({
  params: { To: 'client:alice' },
  rtcConstraints: { audio: { deviceId: 'default' } },
});

Actualización de los controladores de error

Para mantener la compatibilidad con versiones anteriores, el nuevo formato de error se adjuntó al formato antiguo en error.twilioError:

class oldError extends Error {
  //...
  code: number;
  message: string;
  twilioError: TwilioError;
}

El nuevo formato de error es un objeto TwilioError:

class TwilioError extends Error {
  /**
   * Una lista de las posibles causas del error.
   */
  causes: string[];
  /**
   * El código numérico asociado con el error.
   */
  code: number;
  /**
   * Una descripción de lo que significa el error.
   */
  description: string;
  /**
   * Una explicación de cuándo podría surgir el error.
   */
  explanation: string;
  /**
   * Cualquier información adicional obtenida y entregada en tiempo de ejecución.
   */
  message: string;
  /**
   * El nombre de este error.
   */
  name: string;
  /**
   * El error original recibido del sistema externo, si corresponde.
   */
  originalError?: Error;
  /**
   * Una lista de las posibles soluciones del error.
   */
  solutions: string[];
}

Si ya estás utilizando el nuevo formato, la migración debería ser sencilla:

// cambiar...
device.on('error', e => {
  handleError(e.twilioError);
});

// a...
device.on('error', e => {
  handleError(e);
});

De lo contrario, algunos de los códigos de error y mensajes pueden haber cambiado de los códigos antiguos específicos de la plataforma a los nuevos códigos que son más coherentes con Twilio, nuestra API REST y otros SDK.

Actualización de los códigos de error

Con la transición al formato TwilioError, han cambiado los siguientes códigos de error:

Código antiguo Código nuevo Descripción
31003 53405 Cuando la conexión ICE falla
31201 31402 Cuando no se puede acceder a los medios del usuario
31208 31401 Cuando el usuario deniega el acceso a sus medios
31901 53000 Cuando el WebSocket agota el tiempo de espera en modo de comprobación preliminar o preflight

Actualización de la lógica de llamada para incluir los estados de llamada si es necesario

En un parche anterior, incluimos estados de llamada en Call que estaban activados en la propiedad enableRingingState de DeviceOptions. Hemos eliminado este indicador en la versión 2.0, ya que ahora está activado por defecto.

Para obtener una funcionalidad completa, todavía es necesario configurar answerOnBridge en TwiML. Sin embargo, incluso sin answerOnBridge, Call pasará por el nuevo estado ringing (llamando) (brevemente, durante unos pocos ms) antes de llegar a open (establecida). Cuando answerOnBridge está activado, el estado ringing (llamando) comenzará cuando el teléfono del destinatario comience a sonar y pasará a open (establecida) cuando haya respondido y se haya establecido el medio de comunicación.

Esto no debería afectar a la mayoría de las aplicaciones; sin embargo, puede ser necesario que la aplicación conozca el estado Call.Ringing y el evento ringing, lo que dependerá de la implementación.

Actualización de los métodos de eliminación y sus opciones

  • call.mediaStream
  • call.message
  • call.options
    • Se pretendía que fuera una propiedad privada
  • call.pstream
    • Se pretendía que fuera una propiedad privada
  • call.sendHangup()
    • Se pretendía que fuera un método privado
  • deviceOptions.enableIceRestart
    • Ahora el valor predeterminado es true
  • deviceOptions.enableRingingState
    • Ahora el valor predeterminado es true
  • deviceOptions.fakeLocalDtmf
    • Ahora el valor predeterminado es true
  • device.activeCall
    • La aplicación debe mantener referencias a las instancias de Call devueltas en los controladores de evento device.on('incoming') o a través de device.connect()

El evento 'cancel' ya no se emite mediante una instancia de Call en respuesta a una ejecución local de call.ignore().

La instancia de Call ya no emite el evento 'cancel' como respuesta a la ejecución local de call.ignore(). En su lugar, solo se activará cuando el extremo remoto se haya cancelado.

Actualización de tus DeviceOptions

La nueva interfaz de DeviceOptions es esta:

interface Device.Options {
  allowIncomingWhileBusy?: boolean;
  appName?: string;
  appVersion?: string;
  closeProtection?: boolean | string;
  codecPreferences?: Connection.Codec[];
  disableAudioContextSounds?: boolean;
  dscp?: boolean;
  edge?: string[] | string;
  forceAggressiveIceNomination?: boolean;
  logLevel: number;
	maxAverageBitrate?: number;
  sounds?: Partial<Record<Device.SoundName, string>>;
}

(Opcional) Cambio de nombre de Connection a Call

Hemos cambiado el nombre de la clase Connection a Call. Esto no debería afectar a ninguna API pública, pero se han actualizado algunos nombres de métodos internos. Por lo tanto, cualquier código que interactúe con los elementos internos funcionará incorrectamente si no se actualiza.

Calificar esta página:

¿Necesitas ayuda?

Todos la necesitamos a veces; la programación es difícil. Obtén ayuda ahora de nuestro equipo de soporte, o recurre a la sabiduría de la multitud visitando Stack Overflow Collective de Twilio o navegando por la etiqueta de Twilio en Stack Overflow.

        
        
        

        Gracias por tus comentarios.

        Selecciona los motivos de tus comentarios. La información adicional que nos brindas nos ayuda a mejorar nuestra documentación:

        Enviando tus comentarios…
        🎉 Gracias por tus comentarios.
        Se produjo un error. Inténtalo de nuevo.

        Gracias por tus comentarios.

        thanks-feedback-gif