The Vonage Number Insight API provides you with the ability to quickly check in real time the validity, reachability, roaming status, and more about any phone number globally.
There are three types of requests you can make to the Number Insight API:
Basic: Returns the local and international formatting for the number, country code, country name, and country prefix.
Standard: Returns all of the same as Basic, along with current and original cell carrier, whether the number was ported, and whether it is roaming.
Advanced: Returns all the same as Standard, along with whether the number is reachable and if it is a valid number or not.
In addition, you can also make the Advanced request asynchronously. In order to make an asynchronous Advanced request, you need to supply a callback URL.
We are going to walk through creating a Rails application that facilitates looking up basic, standard and advanced number insights on any phone number utilizing the Number Insight API. In addition to following along in this blog post, you can also clone a working copy from GitHub. We will explore using the Advanced Asynchronous Number Insight API in a separate blog post.
Prerequisites
Before we begin we need to make sure we have the following set up and ready:
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.
Set Up Rails
Once you have created your Nexmo account and have Ruby on Rails installed on your system we are ready to begin. The first thing we need to do is initialize a new Rails project. You can execute the following command in your terminal:
With the above command, we have created a new Rails application called number-insights-app
and designated PostgreSQL as our database of choice. You can change the name of the application to whatever you choose and, also replace the database parameter with your preferred database if you would like to use something other than PostgreSQL.
Once you have completed the above command, change into your new application's directory and open up the project in your preferred code editor. Add the following to the Gemfile
:
# Gemfile
gem 'nexmo'
gem 'dotenv-rails'
Once you have saved the Gemfile
, go ahead and run bundle install
from your command line. This will install the Vonage Ruby gem and the dotenv gem into your application. The Nexmo gem provides easy access to the suite of Vonage APIs and the dotenv gem allows you to securely store environment variables without revealing them in your version control.
At this point, you can also run rake db:migrate
. This will set up the database schema for your application. For the purpose of this walkthrough, we are not going to persist the data we receive, but you are welcome to do so.
Our next step is to create our Controller methods and our Routes.
Define Our Controller Actions
The application we are creating is going to present to the user a form with two fields:
A text input for a phone number
Radio buttons to select which kind of Number Insight to run the number against
Therefore, we are going to need the following Controller actions: index
, show
, and create
. The index
action will be the top-level page for our application that will have the HTML form. The show
action will present the data after the API request has been made. The create
action will submit the data to the Vonage Number Insight API. Additionally, we are going to create two private methods: nexmo
and insight_type
. The former will instantiate an instance of the Vonage client, and the latter will be where we process the HTML form and decide what kind of Number Insight request to make.
The index
and show
Actions
The index
and show
actions will be our simplest to define. All we need is to define them. First, create a file in app/controllers/
called number_insights_controller.rb
and add the following:
# number_insights_controller.rb
class NumberInsightsController < ApplicationController
def index
end
def show
end
end
The create
Action
The create
action will receive the form data from the user and send it to our insight_type
method for processing. Thus, we define the action as follows, making sure we call the #insight_type
method, passing the form parameters to the method, and the rendering the show
view:
# number_insights_controller.rb
def create
insight_type(params)
render :show
end
At this point, we need to create the previously mentioned private methods to instantiate our Nexmo client and to process the form data and make the correct API request. After designating these as private
methods, let's first create our Nexmo instantiation method:
# number_insights_controller.rb
private
def nexmo
client = Nexmo::Client.new(api_key: ENV['NEXMO_API_KEY'], api_secret: ENV['NEXMO_API_SECRET'])
end
Next, let's create the method that will process the HTML form data and send it with the appropriate Nexmo API request:
# number_insights_controller.rb
def insight_type(params)
if params[:type] == 'basic'
@data = nexmo.number_insight.basic(number: params[:number])
elsif params[:type] == 'standard'
@data = nexmo.number_insight.standard(number: params[:number])
elsif params[:type] == 'advanced'
@data = nexmo.number_insight.advanced(number: params[:number])
else
flash[:failure] = "Please try to submit the form again, something went wrong."
redirect_to '/number_insights'
end
@data = @data.to_h
end
The #insight_type
method, as shown above, takes one argument, which is the HTML form params
and then runs through an if/else statement checking for the type
of request selected. If the type
does not match one of the defined types (e.g. basic
, standard
, or advanced
) then a message is shared with the user that something went wrong and they are redirected to the index
view. Lastly. the data returned from the API request is converted into a key:value
hash form for easier handling in the view.
At this point, we need to define the routes for our application.
Create Our Routes
Our application needs three routes:
A
GET
route to theindex
actionA
GET
route to theshow
actionA
POST
route to thecreate
action
Let's add them to the config/routes.rb
file:
# routes.rb
get '/number_insights', to: 'number_insights#index'
get '/number_insights/show', to: 'number_insights#show'
post '/number_insights/new', to: 'number_insights#create'
In order for our application to communicate with the Vonage Number Insight API, we need to provide it with the proper credentials. We will do that next.
Your Vonage API Credentials
To obtain your Vonage API key and API secret, navigate to the Vonage Dashboard and once you log in you will see your credentials near the top of the page. All you need to do is click on the eye icon to reveal the API secret. You can also click on the copy icon of each item to automatically copy them to the clipboard.
You are going to want to take advantage of the functionality of the dotenv
gem you installed earlier, so create a file called .env
in the root folder of your project. This is where we will store our Vonage API credentials. Also, it is a good idea to add .env
to a .gitignore
file, if you have not done so already, to ensure that it is not committed to your version control history.
In your code editor, open up the .env
file and add the API key and secret in the following format, making sure to put your credentials after the =
sign on each line:
# .env
NEXMO_API_KEY=
NEXMO_API_SECRET=
At this point, the only thing left to do is to create our views and then our application is ready to use.
Set Up Our Views
We need two views and we also need to add a space in the application layout for the flash
error message that we defined earlier in case the user provided an invalid type
input in the HTML form. Let's add the space for the error message first.
Open up the app/views/layouts/application.html.erb
file and right after the opening <body>
tag and before the <%= yield %>
tag on a new line add the following:
# application.html.erb
<% if flash %>
<% flash.each do |key, msg| %>
<%= msg %>
<% end %>
<% end %>
Now, if there is an error message during the processing of the form data, the user will see it at the top of the page.
The index
View
The index
view contains the HTML form where the user submits the phone number they are looking for number insights on and the type of insight they are requesting.
Create a new folder inside /views/
called number_insights
and add an index.html.erb
file inside of it. Within the index.html.erb
file let's create our form:
# index.html.erb
<h2>Nexmo Number Insights with Rails</h2>
<%= form_tag('/number_insights/new') do %>
<%= label_tag(:number, "Phone Number:") %>
<%= text_field_tag(:number) %>
<br><br>
<%= radio_button_tag(:type, "basic") %>
<%= label_tag(:type_basic, "Basic") %>
<br>
<%= radio_button_tag(:type, "standard") %>
<%= label_tag(:type_standard, "Standard") %>
<br>
<%= radio_button_tag(:type, "advanced") %>
<%= label_tag(:type_advanced, "Advanced") %>
<br><br>
<%= submit_tag("Search") %>
<% end %>
We take advantage of Rails view helpers to create an HTML form that submits a POST
request to /number_insights/new
and contains one text field, three radio buttons, and a submit button.
The show
View
Within the show
view we are creating an HTML table that will dynamically populate its header row and data rows with the data returned from our API request. In this way, we do not need to hardcode a table for each type of API request, but rather we will let the application do that work for us. If you recall, we converted the data returned from our API request to a key:value
hash format and saved it to the @data
instance variable. We will use the keys
for the header row and the values
for the data rows.
An important item to call attention to is that some of the data items returned in the standard
and advanced
API requests contain a hash of hashes, and thus we need to make a second level of iteration over those nested hashes to retrieve the data inside of them. That is what is happening beginning with the <% if value.class == Nexmo::Entity %>
condition check below.
# show.html.erb
<h2>Number Insight Details</h2>
<h3>Number: <%= params[:number] %></h3>
<% @data.each do |key, value| %>
<% end %>
<% @data.each do |key, value| %>
<% if value.class == Nexmo::Entity %>
<% else %>
<% end %>
<% end %>
<table>
<tbody><tr><th><%= key %></th></tr>
<tr><td>
<% value.to_h.each do |subkey, subvalue| %>
<%= subvalue %>
<% end %>
</td><td><%= value %></td></tr>
</tbody></table>
We have now finished creating our application. Go ahead and try it with different phone numbers and with different Vonage Number Insight API request types. You can start your application from the command line with rails -s
and navigate in your web browser to http://localhost:3000/number_insights
. Congratulations!
Further Reading
If you are interested in finding out more about the Nexmo Number Insight API check out the following:
Ben is a second career developer who previously spent a decade in the fields of adult education, community organizing and non-profit management. He worked as a developer advocate for Vonage. He writes regularly on the intersection of community development and tech. Originally from Southern California and a long time resident of New York City, Ben now resides near Tel Aviv, Israel.