https://a.storyblok.com/f/270183/1368x665/ce3c4db0b0/25may_dev-blog_ruby-rcs-suggestions.jpg

How to Receive an RCS Suggested Reply in Ruby on Rails

Published on July 8, 2025

Rich Communications Services (RCS) suggested replies help improve your user experience with interactive, friendly reply buttons. Previously, we learned how to send RCS Reply messages and track their status using Ruby on Rails. But we also need to accept replies somehow, to read in which option our users select. In this article, we’ll show you exactly how to set that up.

In this tutorial, you will learn how to receive an inbound RCS Suggested Reply message by implementing a webhook endpoint in Ruby on Rails.

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

Screenshot of an RCS message conversation where the Vonage RoR chatbot asks the user to choose an ice cream flavor, and responds positively to the user selecting 'Vanilla.RCS chat interaction with Vonage RoR bot demonstrating conversational capabilities by asking about ice cream flavor preferences

Prerequisites

How Does Inbound RCS Work?

You might be wondering how an RCS reply gets from a user’s phone to your Rails application. Similar to SMS, Vonage handles the interaction with the mobile network. Then, it will forward that information in an inbound webhook that you define in your Vonage application. In this tutorial, we’ll use ngrok to handle the incoming webhook to our Rails application.

Infographic titled Inbound RCS Reply' showing how an RCS reply message is sent from a user, processed through the Vonage platform, and delivered to an application via an API and webhook callback.Diagram illustrating the inbound RCS process, where a user sends a message through the Vonage platform, which then forwards the message to an application via a webhook.

How to Expose a Ruby on Rails App with ngrok

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 dynamic environment variable VONAGE_SERVER_HOSTNAME, so you don’t have to continuously update with each run.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']

If you haven't created an .env file from before, make sure to do so in the root of your application and add your Vonage credentials and ngrok URL:

VONAGE_APPLICATION_ID='XXXX'
VONAGE_PRIVATE_KEY='./private.key'
VONAGE_SERVER_HOSTNAME='XXXXXX.ngrok.app

>> Keep Your Credentials Secure

>> Never commit .env files to your repository! Make sure .env is in your .gitignore.

For more help, see working with environment variables in Ruby.

How to Connect Your RCS Agent to Your Vonage Application

Once ngrok is running, we’ll edit our Vonage application (from the previous article) in the dashboard to add the ngrok URL in our webhooks and link it to our RCS Agent.

First, link your RCS Agent by clicking the “Link external accounts” tab:

Screenshot of the Vonage dashboard where the Vonage-Rails-Quickstart application is linked to an RCS external account named 'Vonage RoR,' displaying application ID, API key, and status controls.Dashboard view showing the Vonage-Rails-Quickstart application linked to the Vonage RoR RCS external account, with voice and message capabilities enabled.

Now, update the Inbound URL under the Messages capabilities. Add your ngrok URL followed by /inbound_rcs.

Messages settings section in the Vonage dashboard with fields for Inbound URL configured for HTTP POST, version set to v1, and Enhanced Inbound Media Security toggle set to off.Screenshot of the Messages settings in the Vonage dashboard showing configuration for inbound and status webhook URLs used for RCS communication.

Once you hit save ngrok will now tunnel requests made to the /inbound_rcs endpoint to your Rails application! But there’s one small problem: our Rails application doesn’t have that endpoint yet.

How to Handle an Inbound RCS WebHooks in Rails

Now that Vonage is forwarding an RCS payload to /inbound_rcs, let’s update our application by creating a route to handle it.

Rails.application.routes.draw do
 post '/inbound_rcs', to: 'inbound_rcs#create', as: :inbound_rcs
  ....remaining routes...

When an RCS reply has been sent to your virtual Vonage number, Vonage will notify your application by sending a webhook. A typical payload for an inbound RCS reply message JSON will look something like this:

{
   "channel": "rcs",
   "message_uuid": "aaaaaaaa-bbbb-4ccc-8ddd-0123456789ab",
   "to": "Vonage",
   "from": "447700900001",
   "timestamp": "2025-02-03T12:14:25Z",
   "context_status": "none",
   "message_type": "reply",
   "reply": {
      "id": "reply_option_1",
      "title": "9am"
   }
}

How to Store an RCS Reply Messages from Rails

Now that we have all the required information based on our RCS model as previously defined, we can create some logic to store our inbound RCS replies. We’ll also send a reply to our user to let them know we’ve received their reply.  Let’s generate a new controller to handle this.

rails g controller InboundRcs create

Inside our controller, we’ll have a simple create method that parses the webhook and enters an RCS into our database. You’ll notice that we grab the timestamp, message_type (which will be reply), and the reply JSON object.

# app/controllers/inbound_rcs_controller.rb

class InboundRcsController < ApplicationController
  skip_before_action :verify_authenticity_token

  def create
    rcs = RcsMessage.create(
      message_uuid: params[:message_uuid],
      from: params[:from],
      to: params[:to],
      timestamp: params[:timestamp],
      message_type: params[:message_type],
      reply: params[:reply]
    )

  # send reply to user
    reply(rcs)
    head :ok
   end

To prove that we’ve received the RCS reply, we’ll send a confirmation text back to the sender.

def reply(rcs)
    selection = rcs.reply["title"]
    message = vonage.messaging.rcs(
      type: "text",
      message: "#{selection} is a great choice!"
    )

    vonage.messaging.send(
      from: ENV["RCS_SENDER_ID"],
      to: rcs.from,
      **message
    )

end

The reply method relies on the Vonage client, so we’ll need to initialize it like we did in the previous article.

def vonage
  Vonage::Client.new(
    application_id: ENV["VONAGE_APPLICATION_ID"],
    private_key: ENV["VONAGE_PRIVATE_KEY"]
    )
end

You can see how all the code fits together in the full inbound_rcs_controller.rb file.

Conclusion

Congratulations! You’ve successfully built a Ruby on Rails RCS application that can receive inbound RCS reply messages using a Vonage webhook. And thus, you’ve completed the RCS suggest replies portion of the Ruby on Rails Quickstart. We’ll continue to add more RCS features and then WhatsApp capabilities in future tutorials.

If you have any questions or want to request a functionality for the Quickstart application, join the conversation on the Vonage Community Slack or reach out on X (formerly Twitter). We’d love to hear what you build next!

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.