Rails Integration
Install generator
rails generate whatsapp:install
Creates:
config/initializers/whatsapp.rb— configurationapp/jobs/whatsapp_send_job.rb— ActiveJob for async sending
Model macro (destination mode)
One global WhatsApp account sends to your users’ phone numbers.
class User < ApplicationRecord
has_whatsapp :phone # :phone is the column containing the WhatsApp number
end
user = User.find(1)
# Text
user.whatsapp.send_message("Your verification code is 1234")
# Media
user.whatsapp.send_image("photo.jpg", caption: "Your receipt")
user.whatsapp.send_document("report.pdf", filename: "report.pdf")
user.whatsapp.send_video("clip.mp4", caption: "Watch this")
user.whatsapp.send_audio("voice.ogg")
user.whatsapp.send_sticker("sticker.webp")
# Rich messages
user.whatsapp.send_location(latitude: 48.8566, longitude: 2.3522, name: "Paris")
user.whatsapp.send_contact(name: "Alice", phone: "+33611111111")
user.whatsapp.react(message_id: "msg123", emoji: "👍")
user.whatsapp.reply(quoted_message_id: "msg123", text: "Got it!")
# Poll
user.whatsapp.send_poll(question: "Satisfied?", options: ["Yes", "No"])
# Presence & read receipts
user.whatsapp.send_composing # typing indicator
user.whatsapp.send_recording # recording indicator
user.whatsapp.send_paused # clear indicator
user.whatsapp.mark_as_read("msg123") # send read receipt
# Async (via ActiveJob)
user.whatsapp.send_later("Your order has shipped!")
user.whatsapp.send_image_later("receipt.pdf", caption: "Your invoice")
user.whatsapp.send_document_later("report.pdf", filename: "report.pdf")
Multi-session (account mode)
Each record is its own WhatsApp account — perfect for SaaS apps where each customer connects their own number.
class Hotel < ApplicationRecord
has_whatsapp :phone, account: true
end
hotel = Hotel.find(42)
hotel.whatsapp.connect
hotel.whatsapp.qr_data # base64 QR data (nil if not pending)
hotel.whatsapp.status # :disconnected, :connecting, :qr_pending, :connected
hotel.whatsapp.connected? # true/false
# Send from the hotel's own account
hotel.whatsapp.send_message(to: "+33612345678", text: "Bienvenue chez #{hotel.name}!")
# Receive messages
hotel.whatsapp.on_message { |msg| puts msg.text }
# Polls
hotel.whatsapp.send_poll(to: "+33612345678", question: "Check-in time?", options: ["14h", "15h", "16h"])
hotel.whatsapp.on_poll_vote { |data| puts data[:votes] }
# Presence & read receipts
hotel.whatsapp.send_presence("composing", to: "+33612345678")
hotel.whatsapp.subscribe_presence("+33612345678")
hotel.whatsapp.read_messages([{ remote_jid: "33612345678@s.whatsapp.net", id: "msg1" }])
# Groups
hotel.whatsapp.groups
hotel.whatsapp.create_group(subject: "VIP Guests", participants: ["+336..."])
hotel.whatsapp.disconnect
Custom session keys:
has_whatsapp :phone, account: true # "Hotel_42"
has_whatsapp :phone, account: true, session: "my_key" # "my_key"
has_whatsapp :phone, account: true, session: -> { "hotel-#{id}-#{slug}" } # dynamic
Session management:
Whatsapp.sessions # => { "Hotel_42" => #<Session>, ... }
Whatsapp.session("Hotel_42").status
Whatsapp.disconnect_all!
View helpers
<%= whatsapp_qr(current_hotel.whatsapp, size: 256) %>
<%= whatsapp_status_badge(current_hotel.whatsapp) %>
<%= whatsapp_status(current_hotel.whatsapp) %>
<% if whatsapp_connected?(current_hotel.whatsapp) %>
<p>WhatsApp is connected!</p>
<% end %>
<%= whatsapp_rate_limit_info(current_hotel.whatsapp) %>
Webhook — receiving messages
rails generate whatsapp:webhook
Creates:
app/handlers/whatsapp_message_handler.rb— incoming message handlerapp/controllers/whatsapp/sessions_controller.rb— sessions JSON API- Routes
Handler:
class WhatsappMessageHandler < Whatsapp::MessageHandler
def call(message, session:)
case message.text&.downcase
when /\bbook/
BookingService.create_from_whatsapp(message, session: session)
when /\bhelp/
Whatsapp.session(session).send_message(to: message.from, text: "How can we help?")
end
end
end
Called for every incoming message on all sessions.
Sessions API:
GET /whatsapp/sessions — list all sessions
GET /whatsapp/sessions/:id — session detail + QR data
POST /whatsapp/sessions/:id/connect — connect
POST /whatsapp/sessions/:id/disconnect — disconnect
Notifier
For notification-style messaging without a model:
notifier = Whatsapp::Notifier.new
notifier.notify("+33612345678", "Your order has shipped!")
# With template
notifier = Whatsapp::Notifier.new(template: "Hello %{name}, your code is %{code}.")
notifier.notify("+33612345678", name: "Alice", code: "1234")
# Async
notifier = Whatsapp::Notifier.new(async: true)
notifier.notify("+33612345678", "Background notification")
# Bulk (rate-limit aware)
results = notifier.bulk([
{ to: "+33611111111", text: "Hello A" },
{ to: "+33622222222", text: "Hello B" },
])
# => { sent: 2, failed: 0, errors: [] }