https://a.storyblok.com/f/270183/1368x665/e3a515fda7/25apr_dev-blog_ruby-sms-status.jpg

Receive an SMS Message Status with Ruby on Rails

最后更新 May 1, 2025

Previously, we learned how to send SMS messages using Ruby on Rails SMS integration. However, sending an SMS shouldn't feel like sending a message in a bottle. With SMS Ruby on Rails applications, we can track message delivery and ensure reliability. Thankfully, we get that plus a lot more with the Messages API and SMS Message Status.

This tutorial will show you how to integrate SMS delivery statuses in a Ruby on Rails application using Vonage webhooks.

TL;DR Skip ahead and find all the Quickstart code on GitHub.

Prerequisites

  • An ngrok account

  • Vonage Virtual Number 

  • Ruby on Rails application, as described previously

To buy a virtual phone number, go to your API dashboard and follow the steps shown below.

Steps on how to purchase a phone number from the dashboard, from selecting the number and confirming the selection.Purchase a phone number

  1. Go to your API dashboard

  2. Navigate to BUILD & MANAGE > Numbers > Buy Numbers.

  3. Choose the attributes needed and then click Search

  4. Click the Buy button next to the number you want and validate your purchase

  5. To confirm you have purchased the virtual number, go to the left-hand navigation menu, under BUILD & MANAGE, click Numbers, then Your Numbers

What is An SMS Message Status?

When you fire off a request to send an SMS, this is just the first step in its journey. If you make a successful SMS request, Vonage will queue the SMS while finding the best network provider to deliver the SMS. From there, the network provider will fulfill the request and send the SMS to its target recipient.

Infographic titled 'What is an SMS Message Status?' showing an SMS flow from an application via Vonage's API to a carrier and user. It illustrates message requests, delivery, and callback notifications using icons for API, webhook, carrier, and user devices.Diagram explaining SMS Message Status, showing how messages travel from an application through Vonage and carriers to the user, with delivery status callbacks.

Then, a Message Status (MS) is sent in the opposite order (Network Provider -> Vonage -> Your App) regarding whether or not the SMS was delivered successfully.

To receive this MS in your application, you will need to set up a webhook endpoint telling Vonage where to send it.

How to Publicly Expose Our Ruby on Rails App with ngrok

Vonage will need to send our message statuses to an endpoint. Our Ruby on Rails application is running in development on port 3000, so we can access it locally at localhost:3000. However that only works on our computer!

You can use ngrok to safely expose your local server publicly over HTTP. So now, in a separate tab from your rails server, open an ngrok tunnel on port 3000.

ngrok http 3000

Be sure to add your ngrok URL as a config.host in your development.rb file. We’ll use the environment variable VONAGE_SERVER_HOSTNAME, to make our app more dynamic.

For more help, see how to get started and use ngrok in Rails.

# config/environments/development.rb

Rails.application.configure do
   config.hosts << ENV['VONAGE_SERVER_HOSTNAME']

Now in our .env file, set your 'VONAGE_SERVER_HOSTNAME' to your ngrok URL.

# .env

# ngrok URL, don't include the protocol (https://)
VONAGE_SERVER_HOSTNAME=''

We’ll also need to edit our Vonage application (from previous article) in the dashboard to add the ngrok URL in our webhooks. In the Status URL field, add your ngrok URL followed by /sms_message_status.

Screenshot of Vonage Messages API settings with fields for Inbound URL and Status URL. The Inbound URL field has an error message indicating an invalid URL.Vonage Messages API webhook settings showing an invalid Inbound URL error.Once you hit save ngrok will now forward requests made to the /sms_message_status endpoint to your Rails application! But there’s one small problem: our Rails application doesn’t have that end point.

How to Handle Delivery Receipt Webhooks in Rails

Now that Vonage is forwarding statuses to the /sms_delivery_receipts endpoint, let’s update our application and create a route to handle it.

# config/routes.rb
Rails.application.routes.draw do

 # For SmsMessageStatus controller, create
  post '/sms_message_status', to: 'sms_message_status#create', as: :sms_message_status

	...previous routes...

But what’s going to happen there? Our application is going to accept the Message Status and parse it for the relevant information. You can see what a typical Message Status looks like:

{
"to"=>"13215678899",
"from"=>"John",
"channel"=>"sms",
"message_uuid"=>"93cc5afe-2824-4d40-97b1-e6f6ec00249e", 
"timestamp"=>"2025-02-23T14:52:53Z",
"status"=>"delivered", 
"destination"=> {"network_code"=>"42507"}
}

The most important field is the status because it tells you whether your message was delivered and, if not, what went wrong. See more information about Message Status webhooks.

We’re going to create some logic to update our SMS status based on the received message statuses. Let’s generate a new controller in the command line to handle this.


rails g controller SmsMessageStatus create

Our controller has a single, simple create method. First, the method parses our message status and extracts the message_uuid; it uses this foreign ID to find the SMS in our local database.  It then updates the status for this SMS to the current status we received in the message status.

class SmsMessageStatusController < ApplicationController
  skip_before_action :verify_authenticity_token

  def create
   SmsMessage.where(message_uuid: params[:sms_message_status][:message_uuid])
       .update_all(status: params[:sms_message_status][:status]) if params[:sms_message_status][:message_uuid]

    # Return an empty HTTP 200 status
    head :ok
  end
end

You can now send an SMS and watch your rails server to see that the webhook is called, forwarded, and ActiveRecord updates the database!

Screenshot of a console log displaying an inbound SMS delivery receipt request, JSON parameters, and an SQL update query marking an SMS message as 'submitted' in a Vonage Rails application.Console log showing the processing of an SMS delivery receipt in a Vonage Rails application, including a database update query.

Conclusion

You did it! You learned how to expose your Ruby on Rails application to listen for a webhook via ngrok, updating your database in the process! We’ll continue to build on this application by accepting incoming SMS in the next post.

If you have any questions or suggestions for more Ruby content, send us a message over on the Community Slack. You can also stay in the loop on our developer content and events on X, formerly known as Twitter.

Share:

https://a.storyblok.com/f/270183/384x384/e4e7d1452e/benjamin-aronov.png
Benjamin AronovDeveloper Advocate

Benjamin Aronov is a developer advocate at Vonage. He is a proven community builder with a background in Ruby on Rails. Benjamin enjoys the beaches of Tel Aviv which he calls home. His Tel Aviv base allows him to meet and learn from some of the world's best startup founders. Outside of tech, Benjamin loves traveling the world in search of the perfect pain au chocolat.