https://d226lax1qjow5r.cloudfront.net/blog/blogposts/build-a-voicemail-with-ruby-on-rails-dr/ruby-voicemail.png

Crear un buzón de voz con Ruby on Rails

Publicado el May 13, 2021

Tiempo de lectura: 16 minutos

¿Alguna vez ha querido poder proporcionar a los clientes un número de teléfono al que puedan llamar y simplemente dejarle un mensaje? Puedes crear tu propia aplicación de buzón de voz con Nexmo Voice API y Ruby on Rails. En este tutorial vamos a caminar a través de los pasos para poner en marcha y funcionando. Su aplicación será capaz de recibir llamadas telefónicas, grabar mensajes de voz y tener una interfaz web para mostrar todos los mensajes y reproducirlos.

Si lo prefiere, también puede clonar una copia de trabajo completa de esta aplicación en GutHub

Empecemos.

Requisitos previos

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.

Para realizar este tutorial necesitarás lo siguiente:

  • Rails 5.2+

  • ngrok

Crear una aplicación de buzón de voz

Vamos a seguir los siguientes pasos:

  1. Crear una nueva aplicación Rails

  2. Crear una Account Nexmo

  3. Configurar ngrok

  4. Configurar nuestra aplicación Rails

Una vez que hayamos terminado todos los pasos anteriores estaremos listos para llamar a nuestra nueva aplicación, dejar un mensaje y luego reproducirlo desde nuestra interfaz web.

Creación de una nueva aplicación Rails

Desde su línea de comandos ejecute lo siguiente:

rails new nexmo-rails-voicemail-demo --database=postgresql

Una vez terminado, tendremos una nueva aplicación Rails llamada nexmo-rails-voicemail-demo con PostgreSQL definido como su base de datos. En este punto también querrás crear la base de datos de desarrollo en PostgreSQL. Puedes hacerlo ejecutando lo siguiente:

createdb nexmo-rails-voicemail-demo_development

Ahora que la base de datos está creada podemos crear nuestra tabla que almacenará la información de cada grabación de buzón de voz. Queremos una tabla que contenga los identificadores únicos para el buzón de voz, la grabación y el número de teléfono del remitente. Conversationla grabación y el número de teléfono del remitente. Definiremos qué es un Conversation y cómo utilizarlo cuando hablemos de la creación del controlador. El siguiente comando creará nuestra tabla:

rails generate migration CreateRecordings conversation_uuid:string recording_uuid:string from:numeric

Puede inspeccionar el archivo de migración creado por el generador abriendo la aplicación en su editor de código preferido y visualizando el archivo en la carpeta /db/migrate carpeta. Se llamará create_recordings.rb precedido por una marca de tiempo de cuando ejecutó el comando anterior. El archivo debería tener este aspecto:

class CreateRecordings < ActiveRecord::Migration[5.2]
  def change
    create_table :recordings do |t|
      t.string :conversation_uuid
      t.string :recording_uuid
      t.numeric :from

      t.timestamps
    end
  end
end

Si el archivo de migración se ve bien, entonces usted puede seguir adelante y ejecutar la migración mediante la ejecución de rake db:migrate desde la línea de comandos.

El último paso para configurar nuestra aplicación Rails es instalar nuestras dependencias. Abre el directorio Gemfile en la carpeta raíz de la aplicación y añade lo siguiente:

# Gemfile

gem 'nexmo_rails'
gem 'dotenv-rails'

Una vez guardado el archivo, ejecute bundle install desde tu terminal. Habrás instalado la gema nexmo_rails inicializador en su aplicación, lo que nos permite instanciar un cliente Nexmo con credenciales. Vamos a aplazar la ejecución del inicializador Nexmo por ahora, ya que primero tenemos que crear nuestra cuenta Nexmo y recibir nuestras credenciales de la API. También has instalado la gema dotenv-rails que nos ayudará cuando añadamos nuestras credenciales de la API de Nexmo como variables de entorno.

Ya estamos listos para pasar al siguiente paso y configurar nuestra Account de Nexmo.

Configurar ngrok

Hay varias formas de hacer que nuestro servidor de desarrollo local sea accesible externamente, pero una de las formas más sencillas es con ngrok. Puedes leer este artículo para una explicación más detallada de cómo funciona ngrok. Sin embargo, para nuestros propósitos, sólo necesitamos ponerlo en marcha y copiar la URL que nos proporciona.

Para iniciar ngrok, abra una nueva ventana de terminal y ejecute lo siguiente desde la línea de comandos:

ngrok http 3000

Ahora verá una interfaz de registro ngrok en su ventana de terminal. Cerca de la parte superior de la interfaz hay una línea que comienza con Forwarding y contiene dos URLs. La primera es la URL ngrok accesible externamente, que termina con ngrok.io seguido de http://localhost:3000que es tu servidor de desarrollo local. Ahora, cuando tú o Nexmo contacte con la URL ngrok.io URL, lo reenviará a tu servidor local.

Asegúrese de copiar la ngrok.io URL en un lugar seguro. La utilizaremos en el siguiente paso de configuración de nuestra cuenta Nexmo, número de teléfono y aplicación Voice.

Crear una Nexmo Account

Para que nuestra aplicación de voz funcione, necesitamos una cuenta Nexmo, un número de teléfono provisto por Nexmo, una aplicación Nexmo y, por último, necesitamos vincular nuestra aplicación a nuestro número de teléfono.

Puede crear una cuenta Nexmo de forma gratuita y, como ventaja añadida, se le abonarán 2 euros en su cuenta para empezar a utilizar su nueva aplicación. Visita el Panel para desarrolladores de API de Vonage y sigue los pasos de inscripción si aún no tienes una cuenta de desarrollador de API de Vonage. Una vez que completes la inscripción, verás tu panel de desarrollador de API de Vonage.

En el menú de la izquierda, haga clic en el Voice menu . Verá las cuatro opciones siguientes bajo APPLICATIONS:

Create voice app

Haga clic en la opción Create an application y accederá a una página en la que podrá configurar una nueva aplicación Nexmo.

Rellene el formulario con lo siguiente:

  • Application name introducir campo de texto nexmo-rails-voicemail-demo

  • Event URL introduzca su URL ngrok: https://[ngrok url here]/event

  • Answer URL introduzca de nuevo su URL ngrok: https://[ngrok url here]/webhooks/answer

Cuando haya terminado, haga clic en el botón azul Create Application azul.

Una vez creada la aplicación, puede generar un par de claves pública/privada. Necesitará estas claves cuando acceda a las grabaciones del buzón de voz desde la API. Haga clic en generate public/private key pair y mueva el archivo private.key a la carpeta raíz de nuestra aplicación.

Si aún no lo ha hecho, ahora sería un buen momento para crear un archivo .gitignore archivo en el nivel superior de su aplicación y añadir ./private.key para no enviar tu clave privada al control de versiones.

Ya ha creado una aplicación Nexmo Voice. Nuestro siguiente paso es comprar un número de teléfono Nexmo y vincularlo a esta aplicación.

En el Panel de control de Nexmo, haga clic en el elemento de menú Numbers en el menú de la izquierda. Verá que aparecen tres opciones:

buy numers

Haga clic en la opción Buy numbers y accederá a una página en la que podrá elegir el país, las características, el tipo y los cuatro dígitos que desea que tenga el número.

numbers

Para nuestros propósitos: elija el país en el que se encuentra actualmente, para que la llamada sea una llamada local para usted; elija Voice para las características y móvil o fijo para el tipo. No necesita introducir nada en el campo Number campo de texto. Cuando pulse Searchverás una lista de números de teléfono disponibles.

Elija uno haciendo clic en el botón naranja Buy y volviendo a pulsar el botón naranja Buy una vez más en el mensaje de confirmación.

Una vez que posea el número, podrá vincularlo a su aplicación de nexmo-rails-voicemail-demo aplicación Voice. Para ello, haz clic en el icono de engranaje situado junto al número de teléfono y verás el siguiente menú:

webhook dashboard

Seleccione la nexmo-rails-voicemail-demo Applications de la lista desplegable y haga clic en el botón azul Ok azul. Su número de teléfono Nexmo está ahora vinculado a su aplicación Voice y listo para aceptar y reenviar llamadas telefónicas entrantes a través de proxy de voz.

Nuestro último paso antes de estar listos para ejecutar nuestra aplicación es definir nuestro Controlador, Vista, Modelo y Rutas Rails.

Configurar nuestra aplicación Rails

Antes de empezar a escribir el código para nuestro modelo, vista y controlador vamos a tomarnos un momento para repasar lo que queremos que haga la aplicación. Hay dos aspectos diferentes a nuestra aplicación:

  • Recibir una llamada telefónica y grabar un mensaje

  • Mostrar y hacer accesibles las grabaciones en una página web

Con el fin de lograr la primera tarea de recibir una llamada y grabar un mensaje que necesitamos tener una ruta webhook que puede aceptar la solicitud de la Nexmo Voice API al contestar una llamada y enviar de vuelta las instrucciones a la API. Luego necesitamos una ruta separada que pueda aceptar las actualizaciones de estado de la llamada.

La segunda tarea de nuestra aplicación requiere una ruta que pueda aceptar una petición GET para listar todas las grabaciones. Además, como necesitamos listar todas las grabaciones, tendremos que guardar cada grabación en la base de datos que creamos antes. También querremos guardar cada grabación para poder reproducirla fácilmente al oyente.

Ahora que conceptualmente tenemos un camino a seguir, empecemos a construirlo.

Definir nuestras rutas

Abra el archivo /config/routes.rb en su editor de código y añada las siguientes rutas:

# routes.rb

get '/', to: 'voicemail#index'
get '/answer', to: 'voicemail#answer'
post '/event', to: 'voicemail#event'
post '/recording', to: 'voicemail#new'

Hemos creado cuatro rutas separadas que dirigirán todo el tráfico a nuestra aplicación a los métodos apropiados en nuestro controlador de buzón de voz que pronto será creado. Hemos creado dos GET una para manejar la solicitud de nivel superior para listar todas las grabaciones y otra para recibir la solicitud inicial de la API de Nexmo cuando se contesta una llamada telefónica. También creamos dos POST una para recibir actualizaciones de estado de Nexmo sobre la llamada, y otra para guardar la grabación cuando la llamada ha terminado.

Definir las acciones del controlador

Las rutas que creamos hacían referencia a un controlador que aún no hemos creado, así que vamos a hacerlo ahora. Desde la línea de comandos ejecuta lo siguiente:

rails generate controller Voicemail

Esto creará un archivo en /app/controllers llamado voicemail_controller.rb. Necesitamos crear una acción para cada una de las rutas. Estas acciones contendrán la lógica detrás de la ruta y dirigirán el tráfico a la vista apropiada, cuando sea apropiado. Las acciones son las siguientes:

  • #index: Contiene una variable de instancia llamada @recordings que contiene todos los registros del buzón de voz.

  • #answer: Envía un Objeto de Control de Llamada Nexmo (NCCO) [objeto JSON que contiene las instrucciones para la API Nexmo] a la API Nexmo.

  • #event: Recibe actualizaciones de la API Nexmo. Cuando la aplicación recibe un estado de answeredel método crea una nueva entrada en la tabla Recordings tabla.

  • #new: Accedido por la API cuando se ha realizado una grabación y actualiza una entrada de grabación con el recording_uuidID único de la grabación de audio.

Por último, antes de definir ningún método, creamos dos variables constantes NEXMO_NUMBER y EXTERNAL_URLpara contener nuestro número de teléfono Nexmo y la URL de nuestra URL ngrok accesible externamente, respectivamente. Asegúrate de definirlas en tu controlador con tu información.

Este es el aspecto que tendrá nuestro controlador cuando esté terminado:

# voicemail_controller.rb

class VoicemailController < ApplicationController
    skip_before_action :verify_authenticity_token

    NEXMO_NUMBER = YOUR PHONE NUMBER GOES HERE
    EXTERNAL_URL = 'YOUR NGROK URL GOES HERE'
    
    def index
        @recordings = Recording.all
    end

    def answer
        render json:
        [
            {
                :action => 'talk',
                :text => 'Leave your message after the beep.'
            },
            {
                :action => 'record',
                :beepStart => true,
                :eventUrl => [ "#{EXTERNAL_URL}/recording" ],
                :endOnSilence => 3
            }
        ]
    end

    def event
        if params['status'] == 'answered'
            Recording.create(conversation_uuid: params['conversation_uuid'], from: params['from'])
        end
    end

    def new
        if params['recording_url']
            recording = Recording.find_by(uuid: params['conversation_uuid'])
            recording.recording_uuid = params['recording_uuid']
            recording.save
            Nexmo.files.save(params['recording_url'], "public/voicemail/#{params['recording_uuid']}.wav")
        end
    end
end

Definir nuestro modelo

En nuestra aplicación sólo necesitamos crear un modelo que utilizaremos para interactuar con nuestra tabla Recordings en la base de datos. Sigue adelante y crea un archivo llamado recording.rb en /app/models/ y todo lo que necesitas hacer dentro de él es simplemente definir que es un modelo que hereda de ActiveRecord::Base:

# recording.rb

class Recording < ActiveRecord::Base
end

Ahora que tenemos nuestras Rutas, nuestro Controlador y nuestro Modelo definidos, el siguiente elemento que necesitamos crear es una #index vista. Vamos a seguir adelante y hacer eso ahora.

Crear nuestra vista

Necesitamos crear una vista para nuestra aplicación, que será donde se mostrarán todas las grabaciones del buzón de voz. El usuario puede hacer clic en cualquiera de ellas para reproducir la grabación. Necesitamos crear un archivo index.html.erb en el directorio /app/views/voicemail. Dentro de ese archivo queremos aprovechar la variable de instancia @recordings que creamos en la acción Controlador del buzón de voz #index que contiene todas las entradas de la tabla Recordings . Iteraremos sobre esos datos y crearemos una tabla HTML para listar todas las grabaciones. Nuestra vista final tendrá el siguiente código:

# index.html.erb

<h1>Your Voicemail</h1>

<strong>You have <%= Dir["public/voicemail/*"].length %> messages</strong>

<br /><br />

<table>
    <tr>
        <th>From</th>
        <th>Timestamp</th>
        <th>Conversation UUID</th>
        <th>Recording</th>
    </tr>
    <% @recordings.each do |r| %>
        <tr>
            <td><%= r.from %></td>
            <td><%= r.created_at %></td>
            <td><%= r.conversation_uuid %></td>
            <td><a href="/voicemail/<%= r.recording_uuid %>.wav">Click here to listen</a></td>
        </tr>
    <% end %>
</table>

El único elemento adicional que hemos añadido a la vista, además de la tabla HTML, es un recuento del número de grabaciones del buzón de voz. Utilizamos el método #length en Ruby para contar el número de archivos en la carpeta local de grabaciones de correo de voz y mostrar ese número.

Con la creación de la vista, nuestra aplicación ya está casi lista. Lo último que tenemos que hacer es añadir nuestras credenciales de la API de Nexmo como variables de entorno e inicializar nuestro cliente Nexmo usando el inicializador de Nexmo Rails.

Añadir credenciales Nexmo e inicializar un cliente Nexmo

Anteriormente en este tutorial, instalamos los módulos dotenv-rails y nexmo_rails como dependencias. La primera nos ayuda a gestionar el uso de variables de entorno en nuestra aplicación, mientras que la segunda contiene un generador Rails para inicializar un cliente con credenciales Nexmo.

Lo primero que queremos hacer para añadir nuestras credenciales Nexmo es abrir, o crear el archivo si aún no existe, .env en la carpeta raíz de nuestro proyecto. Dentro de la .env vamos a añadir nuestras credenciales para nuestra clave API Nexmo, secreto, ruta del archivo de clave privada y el ID de la aplicación. Tendrá el siguiente aspecto, sustituyendo los valores por tus credenciales únicas que has obtenido desde el panel de Nexmo:

# .env

NEXMO_API_KEY=your api key
NEXMO_API_SECRET=your api secret
NEXMO_APPLICATION_ID=your application id
NEXMO_PRIVATE_KEY=./private.key

Ahora que nuestras credenciales están añadidas como variables de entorno, estamos listos para ejecutar el generador. Desde la línea de comandos ejecute lo siguiente:

rails generate nexmo_initializer

Ya está. Ya tiene una aplicación totalmente operativa.

Arranca tu servidor Rails, y asegurándote de que ngrok se está ejecutando, ¡llama y déjate un mensaje!

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).