https://d226lax1qjow5r.cloudfront.net/blog/blogposts/building-voice-alerts-broadcast-system-using-ruby-nexmo-text-speech-api-dr/flood-voice-alerts.jpg

Creación de un sistema de difusión de alertas de voz con Ruby

Publicado el May 13, 2021

Tiempo de lectura: 8 minutos

A veces no basta con un mensaje de texto. Cuando realmente quieres que te avisen de algo importante, probablemente quieras recibir una llamada telefónica real; ya sea porque un servidor no funciona o porque se ha producido una catástrofe natural en tu zona.

Del mismo modo, un proveedor de servicios o una autoridad (local) que se ocupe de una emergencia querrá llegar al mayor número de personas posible, lo antes posible, independientemente de que posean o no un teléfono móvil.

La aplicación de alertas por voz de las inundaciones

En este tutorial añadiremos un Sistema de Difusión de Alertas de Voz a una aplicación existente utilizando la Nexmo API de texto a voz (TTS). Para ello hemos construido la aplicación Nexmo Alertas de Inundación que permite a los usuarios suscribirse a alertas de voz para su código postal.

Nexmo Flood Alerts

Esta aplicación nos sirve de punto de partida para este tutorial. Es una aplicación básica de Sinatra básica, escrita en Ruby con algunas gemas adicionales para facilitar las cosas. Hemos añadido SQLite3 y ActiveRecord para la persistencia de nuestros suscriptores. También hemos añadido Bootstrap para hacer que nuestra interfaz de usuario se vea un poco más atractiva. Por último, para este tutorial hemos dejado la obtención de los datos de inundación como un detalle de implementación y en su lugar vamos a enviar manualmente las notificaciones a través del panel de administración.

Puedes descargar el punto de partida de esta aplicación desde Github:

# ensure you have Ruby and Bundler installed git clone https://github.com/nexmo-community/nexmo-sinatra-voice-alerts-demo.git cd nexmo-sinatra-voice-alerts-demo bundle install bundle exec rake db:migrate ruby app.rb

A continuación, visite localhost:4567 en su navegador y suscríbase a una alerta de inundación con su código postal y su número. Después puede visitar el (muy rudimentario) panel de administración donde podrás ver tu suscripción.

Todo el código de este punto de partida se encuentra en la página suscripciones en Github. Todo el código que añadiremos a continuación se encuentra en la rama alertas de alertas. Para tu comodidad puedes ver todos los cambios entre nuestro punto inicial y final en Github también.

API de conversión de texto a voz Nexmo

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.

Nexmo Voice es la forma más sencilla de crear aplicaciones de voz de alta calidad en la nube. Tiene un montón de características y la que vamos a ver hoy es la API de texto a voz (TTS). Utilizaremos esta API para enviar a la gente llamadas de voz que les hablen en voz alta de las alertas de inundación. Para ello vamos a añadir los siguientes cambios a nuestra aplicación:

  1. Añadir el Gema Nexmo Rubí a nuestra aplicación

  2. Crear un formulario para que el administrador pueda seleccionar quién recibe las alertas

  3. Enviar una solicitud a la API Nexmo para un mensaje de texto a voz

Añadir la gema Nexmo Ruby a nuestra aplicación

Para enviar un mensaje de texto a voz a través de Nexmo vamos a tener que añadir la gema nexmo al proyecto.

# Gemfile
gem 'nexmo'
gem 'dotenv'

Como puede ver, también hemos añadido la gema dotenv gema. Esto es sólo para que la aplicación puede cargar las credenciales de la API de un .env archivo. La gema Nexmo automáticamente recoge esas variables de entorno y las utiliza para inicializar el cliente. Puedes encontrar tus credenciales en la página de configuración de tu Account Nexmo.

# .env NEXMO_API_KEY='your_key' NEXMO_API_SECRET='your_secret'

A continuación también tenemos que decirle a la aplicación que utilice estas dos gemas cuando se inicie.

# app.rb
require 'nexmo'
require 'dotenv'
Dotenv.load

Ahora que hemos cargado estas 2 gemas podemos simplemente llamar a Nexmo::Client.new en cualquier lugar sin ningún parámetro para empezar a hacer llamadas a la API.

Seleccione un Numbers o un código postal

Alert Form

Antes de empezar a enviar alertas a todo el mundo, probablemente deberíamos dar al administrador una forma de seleccionar a quién enviar un mensaje. Empecemos por añadir un formulario al panel de administración.

<!-- views/admin.erb -->
  ...
</table>

<h2 class='header'>Send an alert</h2>

<form class="form form-vertical" action="/alert" method="post">
  <div class="form-group form-inline">
    <select class="form-control" name="number">
      <option disabled selected value> -- select a number -- </option>
      <% Subscriber.pluck(:number).sort.each do |number| %>
        <option><%= number %></option>
      <% end %>
    </select>
  </div>
  <input type='submit' value='Send' class='btn btn-primary'>
</form>

Ignorando el Bootstrap boilerplate, todo lo que hemos hecho aquí es crear un formulario con un campo que nos da la opción de apuntar a un número de teléfono. Vamos a añadir un segundo campo después del <select> que acabamos de añadir que nos permite elegir entre todos los códigos postales también.

<!-- views/admin.erb -->
</select>
...
or
<select class="form-control" name="postcode">
  <option disabled selected value> -- select a postcode -- </option>
  <% Subscriber.pluck(:postcode).sort.each do |postcode| %>
    <option><%= postcode %></option>
  <% end %>
</select>
...

Enviar un mensaje de texto a voz de difusión de alertas de voz

Cuando el administrador envía este formulario POST una solicitud a /alert donde podemos analizar el número o código postal seleccionado y hacer una llamada a la API de Nexmo.

# app.rb
...
post '/alert' do
  if params[:number]
    send_alert(:number, params[:number])
  elsif params[:postcode]
    send_alert(:postcode, params[:postcode])
  end
  redirect '/alert'
end

En send_alertque envía el mensaje, pasaremos 4 parámetros al método initiate_tts_call del método Nexmo::Client.

  • to - El número al que enviar un mensaje de voz. (obligatorio)

  • text - El mensaje que hay que transmitir al destinatario (obligatorio)

  • from - El número de Nexmo Voice desde el que enviar un mensaje de voz (opcional)

  • lg - El idioma de voz a utilizar. En este caso utilizaremos una voz británica. (opcional)

Para obtener un Nexmo Voice Numbers, dirígete al Panel Nexmo y compra un Numbers, o bien utiliza la CLI de Vonage y compra un número directamente en la línea de comandos. Una vez comprado, añade el número al archivo .env archivo:

# .env ... NEXMO_PHONE_NUMBER='your_number' ...

Ahora podemos enviar nuestro mensaje.

# app.rb
def send_alert key, value
  Subscriber.where(key => value).each do |subscriber|
    Nexmo::Client.new.initiate_tts_call(
        to: subscriber.number,
      from: ENV['NEXMO_PHONE_NUMBER'],
      text: %{
        <break time="1s"/> Hello #{subscriber.name}.
        This is a flood alert for
        <prosody rate="-50%">#{subscriber.postcode}</prosody>.
        Thank you for using Nexmo.
      },
        lg: 'en-gb'
    )
  end
end

Aquí encontramos todos los Subscribers que coinciden con el código postal o el número dado y, a continuación, hacemos una llamada a la API Nexmo para cada uno de ellos.

El parámetro text tiene algunas cosas interesantes incrustadas en el texto. En primer lugar, utilizamos la etiqueta <break/>-para hacer una pausa de un segundo al inicio de la llamada. Esto es útil para esperar a que el destinatario se lleve el teléfono a la oreja. También utilizamos la etiqueta <prosody>-para ralentizar la pronunciación del código postal. Para más información sobre estas etiquetas en nuestra documentación.

Por último, todo lo que tenemos que hacer es asegurarnos de que cuando el administrador sea redirigido vea una página que confirme que ha enviado la alerta.

# app.rb
get '/alert' do
  erb :alert
end
<!-- views/alert.erb  -->
<% content_for :title do %>
  Alert sent
<% end %>

<p>
  Your Nexmo Flood Alert has been sent.
</p>

Eso es todo, ¡pruébalo! Asegúrate de reiniciar Sinatra si es necesario. Seleccione su propio número en el menú desplegable y envíe el formulario. Recibirás una llamada de voz en cuestión de segundos.

Próximos pasos

El sitio API de texto a voz de Nexmo tiene muchas más opciones de las que hemos mostrado aquí, y de hecho nos hemos saltado algunas muy potentes:

  • Nexmo puede reintentar automáticamente una llamada por ti hasta 10 veces

  • Nexmo puede detectar automáticamente los contestadores automáticos y dejar un mensaje o colgar.

  • Puede especificar un punto final de webhook para que Nexmo realice una llamada HTTP después de que se haya recibido correctamente una alerta

  • Puedes especificar el género preferido de la voz utilizada para convertir tu texto en voz

Personalmente, me gusta mucho que pueda enviar un mensaje de texto a voz como éste sin necesitar directamente webhooks, lo que me permite añadir webhooks sólo si es necesario o más adelante.

Me encantaría saber qué añadirías a continuación. Envíame un tuit (soy @cbetta) con tus pensamientos e ideas.

Compartir:

https://a.storyblok.com/f/270183/400x400/73e68604be/phil-leggetter.jpg
Phil Leggetter

Phil is Head of Developer Relations at Hookdeck, an asynchronous messaging platform, and a proud Vonage alumni.