https://d226lax1qjow5r.cloudfront.net/blog/blogposts/play-streaming-audio-to-a-call-with-ruby-dr/Stream-Audio-into-a-Phone-Call-with-Ruby.png

Reproducir audio en streaming en una llamada telefónica con Ruby

Publicado el May 12, 2021

Tiempo de lectura: 9 minutos

En esta publicación, veremos cómo transmitir un archivo de audio en una llamada telefónica en curso. Existen muchos casos de uso para la transmisión de archivos de audio en llamadas, y con la Voice API de Vonage y la gema Ruby de Vonage, es un proceso relativamente sencillo. Ya sea que quieras compartir música con alguien por teléfono o un fragmento de una reunión de trabajo, puedes hacerlo con unas pocas líneas de Ruby y Vonage.

El código fuente de esta entrada del blog está disponible en GitHub.

Requisitos previos

Para trabajar a través de este puesto, usted necesitará:

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.

Configura tu cuenta y aplicación de Vonage

Comencemos por comprar un número de teléfono que podamos usar para las pruebas. Usaremos la CLI de Vonage para comprar el número.

vonage numbers:buy NUMBER COUNTRYCODE

Aquí NUMBER representa el número que desea comprar, y COUNTRYCODE el prefijo del país para ese número.

Si aún no conoce el número que desea comprar, puede buscar primero un número en un país determinado de la siguiente manera (aquí estamos buscando números en EE.UU. utilizando el código de país US código de país):

vonage numbers:search US

Anote el número de teléfono que acaba de comprar. Lo utilizaremos dentro de un momento en nuestro código.

También usaremos la CLI de Vonage para crear una nueva aplicación. Necesitamos crear una aplicación para usar Voice API.

vonage apps:create "Test Application 1" --voice_answer_urlhttp://example.com/answer --voice_event_url=http://example.com/event

Ejecutando ese comando, hemos creado una nueva aplicación llamada "Aplicación de prueba 1" y definido tres parámetros:

  • answer_url: Donde nuestra aplicación entrega el Objeto de Control de Llamada de Vonage (NCCO) que gobierna la llamada.

  • event_url: Donde Vonage envía la información del evento de forma asíncrona cuando los call_status cambios

Redefiniremos tanto el answer_url como el event_url en nuestro código. Es importante tener en cuenta que deben ser accesibles externamente para que la plataforma de Vonage pueda acceder. Para nuestra instalación local, podemos utilizar ngrok para que nuestro servidor local esté disponible externamente. Puedes encontrar más información sobre el uso de Vonage con ngrok en esta publicación del blog.

Al ejecutar el comando vonage apps:create también genera un ID de aplicación para la aplicación creada. Utilizaremos este identificador dentro de un momento en nuestro código, junto con el nuevo número de teléfono que hemos adquirido.

Configurar nuestras credenciales

En este punto, ya tenemos la información que necesitamos para crear nuestra aplicación. Vamos a crear un servidor web Sinatra que sirve cuatro rutas, tres GET peticiones y una POST petición. Las GET solicitudes inician la llamada telefónica, proporcionan las instrucciones de NCCO a la plataforma de Vonage y transmiten un archivo silencioso para mantener la llamada abierta. La solicitud POST envía el audio a la llamada una vez que ha sido respondida.

Para acceder a nuestra Account de Vonage y autenticarnos necesitamos proporcionar las credenciales correctas. Debes tener cuidado de almacenarlas de forma segura y evitar registrarlas en el control de código fuente. En este ejemplo, utilizaremos la gema dotenv para almacenar nuestras credenciales como variables de entorno y acceder a ellas en nuestro código. Lo haremos creando primero un archivo llamado .env y poniendo lo siguiente dentro:

VONAGE_API_KEY=
VONAGE_API_SECRET=
VONAGE_APPLICATION_ID=
VONAGE_APPLICATION_PRIVATE_KEY_PATH=private.key
VONAGE_TO_NUMBER=
VONAGE_NUMBER=

Su VONAGE_API_KEY y VONAGE_API_SECRET se te proporcionaron cuando te inscribiste para obtener una cuenta de Vonage al comienzo de este tutorial. Puedes volver a acceder a ellos en tu configuración de cuenta. Tu VONAGE_APPLICATION_ID es lo que se te devolvió cuando creaste una nueva aplicación con la CLI de Nexmo. Del mismo modo, tu VONAGE_APPLICATION_PRIVATE_KEY_PATH es la ruta del archivo private.key creado automáticamente al inicializar una nueva aplicación con la CLI. En nuestro ejemplo, es ./private.key. Su VONAGE_NUMBER es el número de teléfono que ha comprado, y el VONAGE_TO_NUMBER es el número de teléfono al que desea llamar.

Si vas a enviar esto a GitHub, asegúrate también de crear un archivo .gitignore y añadir .env para asegurarte de que tus credenciales no se publican en línea por accidente.

Envío de audio en streaming a una llamada con Ruby

Vamos a crear un nuevo archivo llamado server.rb y asegurémonos de que estamos requiriendo nuestras dependencias necesarias y cargando nuestras variables de entorno dotenv variables de entorno:

require 'sinatra'
require 'vonage'
require 'dotenv'
require 'json'

Dotenv.load

A continuación, vamos a inicializar una nueva instancia de cliente de Vonage utilizando esas credenciales y la gema de Vonage.

client = Vonage::Client.new(
  api_key: ENV['VONAGE_API_KEY'],
  api_secret: ENV['VONAGE_API_SECRET'],
  application_id: ENV['VONAGE_APPLICATION_ID'],
  private_key: File.read(ENV['VONAGE_APPLICATION_PRIVATE_KEY_PATH'])
)

En este punto, ahora tenemos una instancia de cliente de Vonage con credenciales y nuestro streaming de audio definido. ¿Qué nos falta? La llamada telefónica, por supuesto.

Primero, obtengamos nuestra ngrok URL de acceso externo que utilizaremos para poner nuestro servidor a disposición de Vonage para que reciba nuestras instrucciones de llamadas y envíe actualizaciones del estado de las llamadas. Una vez que hayas instalado ngrokabre una nueva ventana de consola y ejecuta ngrok http 4567 desde la línea de comandos. Esto iniciará un nuevo ngrok en el puerto 4567 paralelo a nuestro servidor Sinatra, que también se ejecuta en el puerto 4567. Verá que se le muestra un estado que contiene la ngrok URL bajo el parámetro Forwarding parámetro. Siga adelante y copiar y pegar esa URL en el BASE_URL variable constante en server.rb.

BASE_URL = 'PASTE URL HERE'

Mientras estamos definiendo nuestras variables, vamos a seguir adelante y establecer la ruta a nuestro archivo de streaming de audio, y vamos a definir como una CONSTANT variable.

AUDIO_URL = "#{BASE_URL}/voice_api_audio_streaming.mp3"

Ahora podemos crear una ruta URL a /new que, cuando se acceda a ella, iniciará la llamada telefónica.

get '/new' do
  response = client.calls.create(
    to: [{ type: 'phone', number: ENV['VONAGE_NUMBER'] }],
    from: { type: 'phone', number: ENV['VONAGE_TO_NUMBER'] },
    answer_url: ["#{BASE_URL}/answer"],
    event_url: ["#{BASE_URL}/event"]
  )
  puts response.inspect
end

La acción get /new anterior crea una nueva llamada telefónica con el carácter to:, from:, answer_url: y event_url: proporcionados.

En to: y from: requieren tanto un type y a number. En nuestro caso, el parámetro type para ambos es phone. En answer_url y event_url deben ser URL accesibles desde el exterior de las que la plataforma de Vonage pueda recibir instrucciones y a las que pueda enviar actualizaciones del estado de las llamadas, respectivamente.

Una vez que iniciamos la llamada telefónica, Vonage accede a la answer_url ruta buscando instrucciones de llamada. Necesitamos crear esa acción también. La acción renderizará y entregará las instrucciones como JSON. Las instrucciones proporcionan actionla ruta URL a un archivo de audio silencioso que se reproducirá en segundo plano manteniendo la conexión abierta y un parámetro loop que definimos como 0.

get '/answer' do
    # Provide the Vonage Call Control Object (NCCO) as JSON to the Vonage Platform
    content_type :json
    [{ :action => 'stream', :streamUrl => ["#{BASE_URL}/stream/silent"], :loop => 0 }].to_json
end

En este punto, necesitamos crear una ruta más GET para entregar el archivo de audio silencioso que especificamos en las instrucciones de NCCO:

get '/stream/silent' do
    # Stream a silent file in the background to keep the call open
    send_file File.join(settings.public_folder, 'silence.mp3')
end

Por último, también creamos una POST ruta a /event que recibe el estado de la llamada desde la plataforma de Vonage y envía el streaming de audio una vez que ha sido contestada. La acción analiza los datos recibidos y utiliza el parámetro status para determinar cuándo se ha contestado la llamada. El estado de una llamada cambia de started a ringing y luego a answered y finalmente, cuando se desconecta, a completed. Nuestro código reproduce el archivo de audio una vez que status ha alcanzado answered. También recibimos el identificador único de esta llamada, el uuidde los datos recibidos, que es necesario para que podamos inyectar nuestro streaming de audio en esta llamada específica.

post '/event' do
  data = JSON.parse(request.body.read)
  response = client.calls.stream.start(data['uuid'], stream_url: [AUDIO_URL]) if data['status'] == 'answered'
  puts response.inspect
end

Así que con esa POST hemos terminado de crear nuestra aplicación. Ahora, sólo tenemos que ejecutar ruby server.rb desde la línea de comandos para arrancar nuestro servidor y asegurarnos de que hemos inicializado ngrok para que nuestro servidor local sea accesible externamente. Una vez hecho esto, sigue adelante y navega a http://localhost:4567 desde tu navegador web y recibirás la llamada. Cuando conteste la llamada, el audio comenzará a transmitirse.

Conclusión

En aproximadamente 40 líneas de código, hemos creado un servidor web completamente funcional que puede llamar a cualquier número de teléfono y reproducir audio en streaming en esa llamada. Hay mucho más que se puede hacer con Voice API de Vonage y puedes explorarlo por completo en la Plataforma para desarrolladores de Vonage.

Si tienes alguna pregunta sobre esta publicación, envía un correo electrónico a devrel@nexmo.com o únete al canal Slack de la comunidad de Vonagedonde estamos esperando y listos para ayudarte.

Compartir:

https://a.storyblok.com/f/270183/384x384/e5480d2945/ben-greenberg.png
Ben GreenbergAntiguos alumnos de Vonage

Ben es un desarrollador de segunda carrera que anteriormente pasó una década en los campos de la educación de adultos, la organización comunitaria y la gestión de organizaciones sin ánimo de lucro. Trabajó como defensor de los desarrolladores para Vonage. Escribe regularmente sobre la intersección entre el desarrollo comunitario y la tecnología. Originario del sur de California y residente durante mucho tiempo en Nueva York, Ben reside ahora cerca de Tel Aviv (Israel).