
How to Send RCS Suggested Replies With Ruby on Rails
Rich Communication Services (RCS) is transforming the way businesses engage with customers. As the next evolution of SMS, RCS offers a richer, more interactive experience with features like images, videos, file sharing, and suggested replies, natively inside a user's default messaging app. Check out all the cool RCS capabilities.
With RCS support rolling out around the world, for both Android and iOS, now is the perfect time to start exploring this technology. In this tutorial, you'll learn how to send RCS suggested replies using the Vonage Messages API in a Ruby on Rails application, helping you create more dynamic and engaging conversations with your users.
>> TL;DR Skip ahead and find all the Quickstart code on GitHub.
A Vonage RCS chatbot asks the user to choose their preferred ice cream flavor using quick reply buttons.
Prerequisites
Ruby on Rails installed on your machine
A registered RBM Agent
A phone number with RCS capabilities for testing
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.
How to Register an RBM Agent
In order to send and receive RCS capabilities in your Vonage application, you will need to have a registered Rich Business Messaging (RBM) agent and a phone with RCS capabilities.
Currently, RCS Messaging through Vonage is only available for managed accounts. You will need to contact your account manager to request Developer Mode activation for your RBM agent. Developer Mode allows you to test RCS messaging to allow-listed numbers before completing the Agent Verification process and launching in production.
Please contact our sales team if you do not have a managed account.
>> Understand the difference between RCS and RBM.
How to Create a Ruby on Rails Application
This tutorial will assume you have a basic understanding of Ruby and Rails, sticking to the commands required without too much deeper explanation.
First, we’ll create our new project.
rails new vonage-rails-quickstart
Next, move into the project and add the Vonage gem to your Gemfile so we can access the Vonage SDK. We’ll also add dotenv-rails so we can use environment variables safely.
# Gemfile
gem 'vonage'
gem 'dotenv-rails', groups: [:development, :test]
Then run the bundler to install our gems.
bundle install
What Is an RCS Suggested Reply?
Let’s start by looking at how suggested replies work in RCS. Suggested replies are part of a custom RCS message, a flexible format that lets you define interactive elements like reply buttons directly in your message payload. Instead of sending plain text, you can prompt users with tappable options, making conversations faster, richer, and easier to navigate.
Now, let’s think about our RcsMessage model, which defines its attributes and how they are stored in the database. RCS Messages in the Messages API can be one of 5 types: text, image, video, file, or custom. Suggested replies are of custom type, which have the following basic structure:
{
"message_type": "custom",
"custom": {},
"to": "447700900000",
"from": "Vonage",
"channel": "rcs",
"ttl": 600,
"client_ref": "abc123",
"webhook_url": "https://example.com/status"
}
However, this is where it gets tricky because the schema of a custom object can vary widely. Read more about RCS Custom Messages.
In our use case, the API expects an outbound suggested message to have this structure:
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"text": "Which ice-cream flavour do you prefer?",
"suggestions": [
{
"reply": {
"text": "Vanilla",
"postbackData": "suggestion_1"
}
},
{
"reply": {
"text": "Chocolate",
"postbackData": "suggestion_2"
}
}
]
}
}
}
And when the user clicks a suggested reply button, the response will look like this:
{
"to": "Vonage",
"from": "447900000000",
"channel": "rcs",
"message_uuid": "aaaaaaaa-bbbb-cccc-dddd-0123456789ab",
"timestamp": "2024-02-08T10:12:44Z",
"message_type": "reply",
"reply": {
"id": "suggestion_2",
"title": "Chocolate"
}
}
How to Create an RCS Suggested Reply Model
How can we create a flexible and dynamic RCS Message model capable of accommodating both of these situations? Thankfully, ActiveRecord allows us to use JSON as a datatype directly in our model.
We’ll need 7 fields:
to: the recipient of the RCS.
from: the sender of the RCS.
status: whether an RCS has been successfully delivered or not.
message_uuid: the Vonage ID associated with the message, which will be important for tracking the status of messages.
timestamp: when a user has replied to the suggestion.
custom: JSON object which tells the Messages API that this is a suggested reply message and contains the suggested message along with suggestions.
reply: JSON object which tells the Messages API that this is a reply to a suggested message.
rails generate model RcsMessage to:string from:string message_uuid:string timestamp:string message_type:string status:string custom:json reply:json
We’ll also need to update our database with the new model.
rails db:migrate
How to Create an Outbound RCS Controller
Let’s create our controller to handle our logic.
rails g controller OutboundRcs new create
Lastly, let’s define our routes for outbound SMS.
# config/routes.rb
Rails.application.routes.draw do
# For OutboundRcs controller, new & create
get '/outbound_rcs/new', to: 'outbound_rcs#new', as: :new_outbound_rcs
post '/outbound_rcs', to: 'outbound_rcs#create', as: :outbound_rcs
... previous routes ...
end
How to Create a Vonage Application
Now that our Rails App is ready, we’ll also need to create and set up our Vonage Application. First, we need to create our app in the Vonage Dashboard. Give the app a name and turn on the Messages capability. You can add placeholder URLs for the webhooks for now. We will update these in further blog posts.Additionally in future blog posts you’ll need to link your application to your RCS Agent. Since this post only covers outbound messages and doesn’t require the use of webhooks, we can skip it for now.
A screenshot of the Vonage Developer dashboard showing the creation of a new application with authentication, privacy, and messaging capabilities settings.Make sure to generate a private.key by clicking ‘Generate public and private key’. This will download a private.key file to your computer. Then move the private.key file to the root of your Rails application.
When your application is created, take note of the application ID; you’ll need it in the next step.
Create an .env file in the root of your Rails application:
touch .env
Lastly, add the following keys with your credentials.
# .env
VONAGE_APPLICATION_ID=''
VONAGE_PRIVATE_KEY='./private.key'
RCS_SENDER_ID=''
Note: RCS_SENDER_ID is your RCS Brand Name. Be sure to check formatting requirements. For instance, spaces are not allowed. For example if your RCS Brand Name is “Ruby on Rails Quickstart”, then the SENDER_ID would be “RubyonRailsQuickstart”.
How to Initialize the Vonage Ruby Client
Before enabling the Ruby client in a complete Rails application, let’s see how we could use it more generally in Ruby code. To use the client, we’ll just need to initialize an instance with our application information stored in our environment file.
vonage = Vonage::Client.new(
application_id: ENV["VONAGE_APPLICATION_ID"],
private_key: ENV["VONAGE_PRIVATE_KEY"]
)
How to Send an RCS Message in Ruby
Now that our client is initialized, sending an RCS message becomes quite a simple two-step process. We call the messaging method to tell the client to use the Messages API and then build our RCS message:
message = vonage.messaging.rcs(
type: 'custom',
message: {
contentMessage: {
text: "Vonage APIs are easy to use.",
suggestions: [
{
reply: {
text: "Strongly Agree",
postbackData: "5"
}
},
{
reply: {
text: "Agree",
postbackData: "4"
}
},
{
reply: {
text: "Neutral",
postbackData: "3"
}
},
{
reply: {
text: "Disagree",
postbackData: "2"
}
},
{
reply: {
text: "Strongly Disagree",
postbackData: "1"
}
}
]
}
}
)
Then we pass our message to the send method. Notice that the from field is your RBM SenderID (the Name of the Brand). The SenderID requires special formatting, such as not having any spaces. Check with your account manager if you’re unsure.
vonage.messaging.send(
from: 'VonageRCSAgent',
to: '447900000000',
**message
)
Sending RCS in a Ruby on Rails Application
Now that we’ve covered how to use the Vonage Ruby client to send RCS, let’s integrate a Ruby on Rails send RCS functionality into our app with a simple form and controller. We’ll need a nice UI to handle the to, contentMessage text, and suggestions reply fields. RCS can handle up to 11 suggested replies, so we’ve added an “Add another suggestion” button to create as many as you want!
You can copy and add the form to your /app/views/outbound_rcs/new.html.erb view and associated CSS. The form has placeholders, so you know what sort of inputs are expected.
User interface for sending an RCS message, showing fields to enter the recipient's phone number, content message, and suggested reply options.Now, let’s implement the logic to make our form work. First, we’ll need to create an empty RCS instance to load the form. Then, when the form is submitted, we trigger the create method.
It should be as easy as passing our required parameters (to, from, and custom) from the form to create a new @rcs_message instance. Unfortunately, it’s a bit more complicated than that. But what’s happening there?
# app/controllers/outbound_rcs_controller.rb
class OutboundRcsController < ApplicationController
def new
@rcs_message = RcsMessage.new
end
def create
@rcs_message = RcsMessage.new(
to: safe_params[:to],
from: ENV["RCS_SENDER_ID"],
message_type: 'custom'
)
custom_message = construct_custom_message(params[:rcs_message])
@rcs_message.custom = custom_message
if @rcs_message.save
deliver @rcs_message
redirect_to :new_outbound_rcs, flash: { notice: 'RCS Sent' }
else
flash[:alert] = 'Something went wrong'
render :new, status: :unprocessable_entity
end
end
private
def safe_params
params.require(:rcs_message).permit(:to)
end
end
It looks a bit messy because:
1) Our RCS model uses the flexible JSON datatype for our custom field, which means that our form is dynamic and packages up each suggestion. But it also means that we’re not sure how many suggestions are passed.
2) We need to build the JSON object as the API expects. Our form provides each suggestion’s text, but we still need to build the suggestions into an array with the pair of text and postbackData.
To solve this problem, we can define a private controller method, construct_custom_message, to build our custom field and then add it to the newly created @rcs_message instance.
def construct_custom_message(rcs_message_params)
content_message = rcs_message_params[:contentMessage]
suggestions = rcs_message_params[:suggestions]
{
contentMessage: {
text: contentMessage,
suggestions: Array(suggestions).reject(&:blank?).each_with_index.map do |suggestion, idx|
{
reply: {
text: suggestion,
postbackData: "value#{idx + 1}"
}
}
end
}
}
end
Now that our @rcs_message has all the required fields, we can try to save it to our database and then ask the Messages API to deliver it.
The deliver method is largely the same as what we used in the previous section, except now using the Messages message object and handling the API response.
If the message is sent successfully, it returns a 202 status code along with a message_uuid. This UUID helps track delivery status using the Message Status, which we’ll cover in the next post.
def deliver(rcs_message)
message = vonage.messaging.rcs(
type: rcs_message.message_type,
message: rcs_message.custom
)
response = vonage.messaging.send(
from: ENV["RCS_SENDER_ID"],
to: rcs_message.to,
**message
)
puts response
if response.http_response.code == '202'
rcs_message.update(
message_uuid: response.entity.attributes[:message_uuid]
)
end
end
See the full outbound_rcs_controller.rb file.
Now start your Rails server:
rails s
And open http://localhost:3000/outbound_rcs/new in your browser. You can start sending RCS via your Ruby on Rails app!
Ruby SDK vs. Messages API
You might have noticed that in our deliver method, we use type instead of message_type as defined in the Messages API reference. This is because the Ruby SDK abstracts the Messages API and simply requires us to pass the type and message. Additionally, we can pass any additional options through the opts parameter. See more examples in the README.
If you prefer, you can skip the abstraction and call the Messages API directly through the send method:
client.messaging.send(
channel: 'rcs',
message_type: 'text',
to: '447700900000',
from: 'Vonage',
text: 'Hello world!'
)
Conclusion
Job well done! You’ve taken your first step into building cutting-edge messaging experiences with RCS, sending interactive suggested replies from a Ruby on Rails application using the Vonage Messages API. In the next posts, we'll expand on this foundation, showing you how to track message status updates and handle inbound user replies to create fully dynamic conversations.
If you have any questions or suggestions for more Ruby or RCS content, join the conversation with us on the Vonage Community Slack or reach out on X, formerly known as Twitter. We’d love to hear what you build next!
Share:
)
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.