
シェア:
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.
How to Send WhatsApp Messages with Ruby on Rails
所要時間:5 分
Introduction
WhatsApp is one of the most popular messaging platforms in the world, with over two billion users, and it’s fast becoming a go-to channel for customer support, updates, and marketing automation.
In this tutorial, you’ll learn how to send WhatsApp messages from a Ruby on Rails application using the Vonage Messages API. As a bonus, you’ll also learn to add interactive reply buttons so users can respond more easily and intuitively.
TL;DR: Get the complete Rails WhatsApp Quickstart on GitHub
A Ruby on Rails app sending a WhatsApp message through the Vonage Messages API.
Prerequisites
You’ll need the following before you start:
Ruby and Rails are installed on your machine
This tutorial uses Rails 7+, but it works identically on Rails 8+
A verified WhatsApp Business Account (WABA)
Don’t have a WhatsApp Business Account yet? Start with our Sandbox Quickstart for WhatsApp to test with minimal setup.
The dotenv-rails gem for managing credentials
A Vonage API Account
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.
Step 1: Create a Ruby on Rails Application
Begin by creating a new Rails app:
rails new vonage-rails-whatsapp
cd vonage-rails-whatsappAdd your dependencies, the Vonage Ruby SDK and dotenv:
bundle add vonage dotenv-rails
Create a WhatsAppMessage Model
We’ll create a model to store each message’s details, such as the sender, recipient, and delivery status. To properly handle different message types and store sender information, let's add additional fields:
message_type: Distinguish between "text", "reply", and other message types
profile_name: Store the sender's WhatsApp display name
reply_data: Store the full JSON data for interactive button replies
rails g model WhatsappMessage to:string from:string text:text status:string message_uuid:string is_inbound:boolean message_type:string profile_name:string reply_data:textAnd then run the migration:
rails db:migrate
Create a Controller and Routes
We’ll use a controller to handle sending messages and showing the form.
rails g controller OutboundWhatsapp new createThen define the routes in config/routes.rb:
Rails.application.routes.draw do
get '/outbound_whatsapp/new', to: 'outbound_whatsapp#new', as: :new_outbound_whatsapp
post '/outbound_whatsapp', to: 'outbound_whatsapp#create', as: :outbound_whatsapp
# Bonus route for interactive messages
post '/outbound_whatsapp/interactive', to: 'outbound_whatsapp#interactive', as: :interactive_whatsapp
end
Why not use resources here?
For this tutorial, we’re using explicit get/post routes. This keeps the mapping between each URL and controller action very explicit for readers who may be newer to Rails routing. In a production app, you can absolutely switch to resourceful routing and collection routes if you prefer a more idiomatic RESTful style.
The equivalent would be:
resources :outbound_whatsapp, only: [:new, :create] do
collection do
post :interactive
end
end
Step 2: Configure Your Application
Create a Vonage Application
To create an application, go to the Create an Application page on the Vonage Dashboard, and define a Name for your Application.

If you intend to use an API that uses Webhooks, you will need a private key. Click “Generate public and private key”, your download should start automatically. Store it securely; this key cannot be re-downloaded if lost. It will follow the naming convention private_<your app id>.key. This key can now be used to authenticate API calls. Note: Your key will not work until your application is saved.
Choose the capabilities you need (e.g., Voice, Messages, RTC, etc.) and provide the required webhooks (e.g., event URLs, answer URLs, or inbound message URLs). These will be described in the tutorial.
To save and deploy, click "Generate new application" to finalize the setup. Your application is now ready to use with Vonage APIs.
Before sending messages, you’ll need a Vonage Messages API application.
Log in to your Vonage Dashboard.
Create a new application and enable the Messages capability.
Add placeholder webhook URLs for:
Inbound:https://example.com/inbound
Status:https://example.com/status
Click Generate public and private key
Move the downloaded private.key file to the root (vonage-rails-whatsapp) of your Rails app.
Note your Application ID for later use.
Click Save
Link your WhatsApp number under the Link external accounts tab.
You’re now ready to authenticate and send messages.
Viewing the WhatsApp-Rails application in the Vonage dashboard with an active WhatsApp number linked.
Add Your Environment Variables
Store your credentials securely in an .env file:
touch .envThen open the .env file and update with your credentials:
VONAGE_APPLICATION_ID=your_application_id
VONAGE_PRIVATE_KEY=./private.key
VONAGE_WHATSAPP_NUMBER=14157386102
>> For more help, check out: Working with Environment Variables in Ruby
Step 3. Send a WhatsApp Text Message
Before building everything into Rails, let’s understand what’s happening behind the scenes. The Vonage Ruby SDK gives you a single client for accessing multiple Vonage APIs, including the Messages API, which we’ll use for WhatsApp.
How the Vonage Client Works in Ruby
The Ruby client is initialized with your application’s credentials, coming from the .env file.
vonage = Vonage::Client.new(
application_id: ENV["VONAGE_APPLICATION_ID"],
private_key: ENV["VONAGE_PRIVATE_KEY"]
)
>> Note: For production-grade projects, you’ll want to store your Vonage credentials securely using Rails Encrypted Credentials
Once initialized, you can use this client to send any supported message type (SMS, WhatsApp, Messenger, Viber) through the messaging.send method.
Here’s what sending a WhatsApp text message looks like in plain Ruby:
response = vonage.messaging.send(
to: "14155551234",
from: ENV["VONAGE_WHATSAPP_NUMBER"],
channel: "whatsapp",
message_type: "text",
text: "Hey, it's your friends from Vonage!"
)
puts response.inspectIf the message sends successfully, Vonage returns a 202 status code along with a unique message_uuid.
Sending WhatsApp Messages in a Ruby on Rails Application
Now that you understand how the Vonage client works in isolation, let’s connect it to your Rails application.
We’ll add the logic to our OutboundWhatsappController to create and send WhatsApp messages from the web form.
Open app/controllers/outbound_whatsapp_controller.rb and replace its contents with (ignore the interactive message for now):
class OutboundWhatsappController < ApplicationController
def new
@whatsapp_message = WhatsappMessage.new
end
def create
@whatsapp_message = WhatsappMessage.new(safe_params)
if @whatsapp_message.save
deliver(@whatsapp_message)
redirect_to :new_outbound_whatsapp, notice: 'WhatsApp message sent!'
else
flash[:alert] = 'Something went wrong'
render :new
end
end
private
def safe_params
params.require(:whatsapp_message).permit(:to, :text)
end
def deliver(whatsapp_message)
vonage = Vonage::Client.new(
application_id: ENV["VONAGE_APPLICATION_ID"],
private_key: ENV["VONAGE_PRIVATE_KEY"]
)
response = vonage.messaging.send(
message_type: "text",
text: whatsapp_message.text,
to: whatsapp_message.to,
from: ENV['VONAGE_WHATSAPP_NUMBER'],
channel: "whatsapp"
)
if response.http_response.code == "202"
whatsapp_message.update(
message_uuid: response.entity.attributes[:message_uuid]
)
end
end
end
Inside the deliver method, the process follows four key steps. First, it initializes a new Vonage Client. Next, it sends a WhatsApp text message by calling messaging.send with the required parameters. In this quickstart we always send from a single WhatsApp number configured via the VONAGE_WHATSAPP_NUMBER environment variable. But in a more advanced app, you could expose a from field and let users choose which number to send from.
Once the request is made, the method checks the API response. If the server returns an HTTP 202 status code, it means the message was successfully accepted for delivery. Finally, the method saves the unique message_uuid returned by Vonage.
Add a Simple View
Now create app/views/outbound_whatsapp/new.html.erb for the text message form (ignore the interactive message for now):
<h1>Send a WhatsApp Message</h1>
<%= form_with model: @whatsapp_message, url: outbound_whatsapp_path, local: true do |f| %>
<div>
<%= f.label :to, "To (Recipient WhatsApp Number)" %><br>
<%= f.text_field :to, placeholder: "e.g. 14155551234" %>
</div>
<div>
<%= f.label :text, "Message" %><br>
<%= f.text_area :text, rows: 4, placeholder: "Type your message..." %>
</div>
<%= f.submit "Send Message", class: "btn btn-primary" %>
<% end %> Step 4: Run and Test
Start your Rails server:
rails sThen openhttp://localhost:3000/outbound_whatsapp/new.
You should be able to send a WhatsApp message from a form that looks like this:
A Rails form for sending WhatsApp messages using the Vonage Messages API.
Bonus: Add Interactive Reply Buttons
Now, let’s make your messages more engaging by sending interactive reply buttons. These messages let users tap one of several options instead of typing, making your app feel more like a chatbot.
A Ruby on Rails app sending an interactive WhatsApp message with reply buttons using the Vonage Messages API.
Add an Interactive Action
In your existing OutboundWhatsappController, add this new method:
def interactive
unless params[:to].present?
redirect_to :new_outbound_whatsapp, alert: "Recipient number is required!"
return
end
vonage = Vonage::Client.new(
application_id: ENV["VONAGE_APPLICATION_ID"],
private_key: ENV["VONAGE_PRIVATE_KEY"]
)
interactive_message = {
from: ENV["VONAGE_WHATSAPP_NUMBER"],
to: params[:to],
channel: "whatsapp",
message_type: "custom",
custom: {
type: "interactive",
interactive: {
type: "button",
header: {
type: "text",
text: "Delivery time"
},
body: {
text: "Which time would you like us to deliver your order at?"
},
footer: {
text: "Please allow 15 minutes either side of your chosen time."
},
action: {
buttons: [
{
type: "reply",
reply: { id: "slot-1", title: "15:00" }
},
{
type: "reply",
reply: { id: "slot-2", title: "16:30" }
},
{
type: "reply",
reply: { id: "slot-3", title: "17:15" }
}
]
}
}
}
}
response = vonage.messaging.send(**interactive_message)
Rails.logger.info("📤 Sent interactive message to #{params[:to]}: #{response.inspect}")
redirect_to :new_outbound_whatsapp, notice: "Interactive message sent to #{params[:to]}!"
end Add a Form to Trigger It
Update app/views/outbound_whatsapp/new.html.erb to include:
<hr>
<h3>Try an Interactive Message</h3>
<p>Send a sample interactive WhatsApp message with reply buttons.</p>
<%= form_with url: interactive_whatsapp_path, method: :post, local: true do |f| %>
<div>
<%= f.label :to, "To (Recipient WhatsApp Number)" %><br>
<%= f.text_field :to, placeholder: "e.g. 14155551234", required: true %>
</div>
<%= f.submit "Send Interactive Message", class: "btn btn-secondary" %>
<% end %> Try It Out
Reload your browser, add a recipient phone number, and click “Send Interactive Message”.
You’ll receive a WhatsApp message and be able to see the confirmation in your Rails server:
Terminal output confirming successful delivery of an interactive WhatsApp message using the Vonage Messages API in a Ruby on Rails app.However, what happened to that message? Was it opened? Was it read? Which option did the user select? We have no way of knowing. Keep reading to find out how we handle actions from our users.
Explore Further
Our current app is incomplete. We don’t handle incoming messages, message status, or message payloads to tell us the user’s selection.
In the next tutorial, How to Receive WhatsApp Messages in Rails, we’ll cover all these topics which will allow you to build more dynamic applications.
Conclusion
You’ve now built a Ruby on Rails app that sends both WhatsApp text messages and interactive reply button messages using the Vonage Messages API.
You learned how to:
Configure a Vonage WhatsApp application
Send outbound text messages from Rails
Add interactive buttons for richer conversations
What other Rails topics are you interested in? Have you played RCS (Rich Communications Services) yet? Try sending RCS Suggested Replies, they're like WhatsApp replies but right inside your default messaging app.
Have questions or ideas? Join us on the Vonage Community Slack or follow @VonageDev on X (formerly Twitter).
シェア:
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.



