https://a.storyblok.com/f/270183/200055/b3a9d27ecd/ruby-voicemail.png

Crie um correio de voz com Ruby on Rails

Publicado em May 13, 2021

Tempo de leitura: 16 minutos

Você já pensou em oferecer aos clientes um número de telefone para o qual eles possam ligar e simplesmente deixar uma mensagem? Você pode criar seu próprio aplicativo de correio de voz utilizando a Voice API e o Ruby on Rails. Neste tutorial, vamos explicar passo a passo como colocar tudo em funcionamento. Seu aplicativo poderá receber chamadas, gravar mensagens de correio de voz e terá uma interface web para exibir todas as mensagens e reproduzi-las.

Se preferir, você também pode clonar uma cópia de trabalho completa deste aplicativo no GitHub

Vamos começar!

Pré-requisitos

Para seguir este tutorial, você precisará do seguinte:

  • Rails 5.2 ou superior

  • ngrok

Criar um aplicativo de correio de voz

Vamos percorrer as seguintes etapas:

  1. Criar uma nova aplicação Rails

  2. Criar um account no Nexmo

  3. Configurar o ngrok

  4. Configurar nosso aplicativo Rails

Assim que tivermos concluído todas as etapas acima, estaremos prontos para acessar nosso novo aplicativo, gravar uma mensagem e, em seguida, reproduzi-la pela nossa interface web.

Criar uma nova aplicação Rails

Na linha de comando, execute o seguinte:

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

Assim que terminar, você terá uma aplicação Rails totalmente nova chamada nexmo-rails-voicemail-demo com o PostgreSQL definido como seu banco de dados. Nesse momento, você também vai querer criar o banco de dados de desenvolvimento no PostgreSQL. Para isso, execute o seguinte:

createdb nexmo-rails-voicemail-demo_development

Agora que o banco de dados está criado, podemos criar nossa tabela, que armazenará as informações de cada gravação de mensagem de voz. Queremos uma tabela que contenha os identificadores exclusivos para a Conversation, da gravação e do número de telefone do remetente. Definiremos o que é um Conversation é e como usá-lo quando discutirmos a criação do Controlador. O comando a seguir criará nossa tabela:

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

Você pode verificar o arquivo de migração criado pelo gerador abrindo o aplicativo no seu editor de código preferido e visualizando o arquivo na /db/migrate pasta. Ele terá o nome create_recordings.rb precedido por um carimbo de data e hora correspondente ao momento em que você executou o comando acima. O arquivo deve ter uma aparência semelhante a esta:

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

Se o arquivo de migração estiver correto, você pode prosseguir e executar a migração digitando rake db:migrate na linha de comando.

O último passo, por enquanto, na configuração da nossa aplicação Rails é instalar nossas dependências. Abra o arquivo Gemfile na pasta raiz da aplicação e adicione o seguinte:

# Gemfile

gem 'nexmo_rails'
gem 'dotenv-rails'

Depois que o arquivo estiver salvo, execute bundle install no seu terminal. Você já deve ter instalado a nexmo_rails gem inicializadora em seu aplicativo, o que nos permite instanciar um cliente Nexmo com credenciais. Vamos adiar a execução do inicializador do Nexmo por enquanto, já que primeiro precisamos criar nosso Account no Nexmo e receber nossas credenciais de API. Você também instalou o dotenv-rails gem que nos ajudará quando adicionarmos nossas credenciais da API do Nexmo como variáveis de ambiente.

Agora estamos prontos para avançar para a próxima etapa e configurar nosso Account no Nexmo.

Configurar o ngrok

Existem várias maneiras de tornar nosso servidor de desenvolvimento local acessível externamente, mas uma das mais simples é usando o ngrok. Você pode ler este artigo para obter uma explicação mais detalhada sobre como o ngrok funciona. No entanto, para nossos propósitos, basta colocá-lo em funcionamento e copiar a URL que ele nos fornece.

Para iniciar o ngrok, abra uma nova janela do terminal e execute o seguinte na linha de comando:

ngrok http 3000

Agora você verá uma interface de registro do ngrok na janela do seu terminal. Na parte superior da interface, há uma linha que começa com Forwarding e contém duas URLs. A primeira é a URL do ngrok acessível externamente, que termina com ngrok.io seguida por http://localhost:3000, que é o seu servidor de desenvolvimento local. Agora, quando você ou a Nexmo acessarem a ngrok.io URL, ela será redirecionada para o seu servidor local.

Certifique-se de copiar o ngrok.io URL em algum lugar seguro. Vamos usá-lo na próxima etapa da configuração da nossa conta Nexmo, do número de telefone e do aplicativo Voice.

Criar um Account no Nexmo

Para que nosso aplicativo de voz funcione, precisamos de um Account Nexmo, um número de telefone provisionado pela Nexmo, um aplicativo Nexmo e, por fim, precisamos vincular nosso aplicativo ao nosso número de telefone.

Você pode criar um account na Nexmo gratuitamente e, como bônus adicional, receberá 2 euros em seu account para começar a usar seu novo aplicativo. Acesse o Painel do Desenvolvedor da API da Vonage e siga as etapas de cadastro, caso ainda não tenha um Account de desenvolvedor da API da Vonage. Após concluir o cadastro, você verá o Painel do Desenvolvedor da API da Vonage.

No menu à esquerda, clique no Voice menu item. Você verá as quatro opções a seguir em APPLICATIONS:

Create voice app

Clique na Create an application opção e você será direcionado para uma página onde poderá configurar um novo aplicativo Nexmo.

Preencha o formulário com as seguintes informações:

  • Application name campo de texto: Enter nexmo-rails-voicemail-demo

  • Event URL No campo de texto, insira sua URL do ngrok: https://[ngrok url here]/event

  • Answer URL No campo de texto, digite novamente a URL do ngrok: https://[ngrok url here]/webhooks/answer

Quando terminar, clique no botão azul Create Application .

Depois que o aplicativo for criado, você poderá gerar um par de chaves pública/privada. Você precisará dessas chaves para acessar as gravações do correio de voz por meio da API. Clique em generate public/private key pair e mova o arquivo baixado automaticamente private.key para a pasta raiz do nosso aplicativo.

Se você ainda não fez isso, agora seria um bom momento para criar um .gitignore arquivo no nível superior do seu aplicativo e adicionar ./private.key conteúdo a ele, para não enviar sua chave privada para o controle de versão.

Você acabou de criar um aplicativo do Nexmo Voice. O próximo passo é adquirir um número de telefone do Nexmo e vinculá-lo a esse aplicativo.

No Painel do Nexmo, clique no Numbers item de menu no menu à esquerda. Você verá três opções aparecerem:

buy numers

Clique na Buy numbers opção e você será direcionado para uma página onde poderá escolher o país, os recursos, o tipo e os quatro dígitos que deseja que o número tenha.

numbers

Para os nossos fins: escolha o país em que você está no momento, para que a ligação seja considerada local para você; escolha Voice “Recursos” e “Celular” ou “Fixo” como tipo. Você não precisa preencher nada no Number campo de texto. Ao clicar em Search, você verá uma lista de números de telefone disponíveis.

Escolha uma clicando no botão laranja Buy e clicando no botão laranja Buy mais uma vez na janela de confirmação.

Depois de adquirir o número, você já pode vinculá-lo ao seu nexmo-rails-voicemail-demo aplicativo Voice. Para isso, clique no ícone de engrenagem ao lado do número de telefone e você verá o seguinte menu:

webhook dashboard

Selecione a nexmo-rails-voicemail-demo Applications na lista suspensa e clique no botão azul Ok . Seu número de telefone da Nexmo agora está vinculado ao seu aplicativo Voice e pronto para receber e encaminhar chamadas recebidas por meio do proxy de voz.

Nosso último passo antes de estarmos prontos para executar nosso aplicativo é definir nosso controlador, nossa visualização, nosso modelo e nossas rotas no Rails.

Configurar nosso aplicativo Rails

Antes de começarmos a escrever o código para nosso modelo, nossa vista e nosso controlador, vamos dedicar um momento para analisar o que queremos que o aplicativo faça. Há dois aspectos diferentes em nosso aplicativo:

  • Receber uma ligação e gravar uma mensagem

  • Exibir e disponibilizar as gravações em uma página da web

Para realizar a primeira tarefa, que consiste em receber uma chamada e gravar uma mensagem, precisamos ter uma rota de webhook capaz de aceitar a solicitação da Voice API ao atender uma chamada e enviar instruções de volta para a Voice API. Em seguida, precisamos de uma rota separada que possa receber as atualizações de status da chamada.

A segunda tarefa do nosso aplicativo requer uma rota capaz de aceitar uma GET solicitação para listar todas as gravações. Além disso, como precisamos listar todas as gravações, teremos que salvar cada uma delas no banco de dados que criamos anteriormente. Também vamos querer salvar cada gravação em si para facilitar a reprodução para o ouvinte.

Agora que já temos uma ideia conceitual do caminho a seguir e do que estamos buscando, vamos começar a colocá-lo em prática.

Definir nossas rotas

Abra o /config/routes.rb arquivo no seu editor de código e adicione as seguintes rotas:

# routes.rb

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

Criamos quatro rotas distintas que direcionarão todo o tráfego para o nosso aplicativo aos métodos apropriados em nosso controlador de correio de voz, que será criado em breve. Criamos duas GET rotas de solicitação: uma para lidar com a solicitação de nível superior para listar todas as gravações e outra para receber a solicitação inicial da API da Nexmo quando uma chamada for atendida. Também criamos duas POST solicitações: uma para receber atualizações de status da Nexmo sobre a chamada e outra para salvar a gravação quando a chamada terminar.

Definir as ações do nosso controlador

As rotas que criamos fazem referência a um controlador que ainda não criamos; portanto, vamos criar esse controlador agora. Na linha de comando, execute o seguinte:

rails generate controller Voicemail

Isso criará um arquivo em /app/controllers chamado voicemail_controller.rb. Precisamos criar uma ação para cada uma das rotas. Essas ações conterão a lógica por trás da rota e direcionarão o tráfego para a visualização apropriada, quando for o caso. As ações são as seguintes:

  • #index: Contém uma variável de instância chamada @recordings que contém todos os registros de mensagens de voz.

  • #answer: Envia um Objeto de Controle de Chamadas da Nexmo (NCCO) [objeto JSON contendo as instruções para a API da Nexmo] à API da Nexmo.

  • #event: Recebe atualizações da API da Nexmo. Quando o aplicativo recebe um status de answered, o método cria uma nova entrada na Recordings tabela.

  • #new: Acessado pela API quando uma gravação é feita e atualiza um registro de gravação com o recording_uuid, o ID exclusivo da gravação de áudio.

Por fim, antes de definir qualquer método, criamos duas variáveis constantes: NEXMO_NUMBER e EXTERNAL_URL, para armazenar, respectivamente, nosso número de telefone da Nexmo que provisionamos e a URL do nosso ngrok acessível externamente. Certifique-se de defini-las em seu controlador com suas informações.

É assim que nosso controlador ficará quando estiver pronto:

# 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

Defina nosso modelo

Em nosso aplicativo, precisamos criar apenas um modelo que usaremos para interagir com nossa Recordings tabela no banco de dados. Vá em frente e crie um arquivo chamado recording.rb em /app/models/ e tudo o que você precisa fazer nele é simplesmente definir que se trata de um modelo que herda de ActiveRecord::Base:

# recording.rb

class Recording < ActiveRecord::Base
end

Agora que já definimos nossas Rotas, nosso Controlador e nosso Modelo, o próximo item que precisamos criar é uma #index visualização. Vamos em frente e fazer isso agora.

Crie a nossa visão

Precisamos criar uma visualização para nosso aplicativo, na qual serão exibidas todas as gravações de mensagens de voz. O usuário pode clicar em qualquer uma delas para reproduzir a gravação. Precisamos criar um index.html.erb arquivo em /app/views/voicemail. Nesse arquivo, queremos aproveitar a @recordings variável de instância que criamos no controlador de mensagens de voz #index , que contém todas as entradas da Recordings tabela. Iremos percorrer esses dados e criar uma tabela HTML para listar todas as gravações. Nossa visualização final terá o seguinte 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>

O único elemento adicional que incluímos na visualização, além da tabela HTML, é a contagem do número de gravações de mensagens de voz. Utilizamos o #length método em Ruby para contar o número de arquivos na pasta local das gravações de mensagens de voz e exibir esse número.

Com a criação da visualização, nosso aplicativo já está quase pronto. A última coisa que precisamos fazer é adicionar nossas credenciais da API do Nexmo como variáveis de ambiente e inicializar nosso cliente Nexmo usando o inicializador do Nexmo para Rails.

Adicionando credenciais do Nexmo e inicializando um cliente Nexmo

No início deste tutorial, instalamos o dotenv-rails e nexmo_rails gems como dependências. A primeira nos ajuda a gerenciar o uso de variáveis de ambiente em nossa aplicação, enquanto a segunda contém um gerador do Rails para inicializar um cliente com credenciais do Nexmo.

A primeira coisa que queremos fazer para adicionar nossas credenciais do Nexmo é abrir — ou criar o arquivo, caso ele ainda não exista — .env na pasta raiz do nosso projeto. Dentro do .env arquivo, vamos adicionar nossas credenciais: a chave da API do Nexmo, o segredo, o caminho do arquivo da chave privada e o ID do aplicativo. Ficará mais ou menos assim, substituindo os valores pelas suas credenciais exclusivas obtidas no painel do 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

Agora que nossas credenciais foram adicionadas como variáveis de ambiente, estamos prontos para executar o gerador. Na linha de comando, execute o seguinte:

rails generate nexmo_initializer

É isso aí! Agora você tem um aplicativo totalmente funcional.

Inicie seu servidor Rails e, depois de verificar se o ngrok está em execução, vá em frente, acesse o servidor e deixe uma mensagem para você mesmo!

Compartilhar:

https://a.storyblok.com/f/270183/384x384/e5480d2945/ben-greenberg.png
Ben GreenbergEx-funcionários da Vonage

Ben é um desenvolvedor que mudou de carreira, tendo atuado anteriormente por uma década nas áreas de educação de adultos, organização comunitária e gestão de organizações sem fins lucrativos. Ele trabalhou como representante de desenvolvedores na Vonage. Escreve regularmente sobre a interseção entre desenvolvimento comunitário e tecnologia. Natural do sul da Califórnia e morador de longa data da cidade de Nova York, Ben reside atualmente perto de Tel Aviv, em Israel.