Skip to content

Events & Messages ​

Convenience methods ​

ruby
client.on_qr        { |qr_string| ... }  # QR code data string
client.on_message   { |msg| ... }        # Live messages only (Whatsapp::Message)
client.on_connected { ... }              # Successfully connected

Message status callbacks ​

Track delivery status of sent messages:

ruby
# All status changes
client.on_message_status do |data|
  puts "#{data[:id]} → #{data[:status]}"
  # data = { id:, to:, from_me:, status:, status_code: }
end

# Specific statuses
client.on_message_sent      { |data| puts "Sent: #{data[:id]}" }
client.on_message_delivered { |data| puts "Delivered: #{data[:id]}" }
client.on_message_read      { |data| puts "Read: #{data[:id]}" }

Status values: pending, sent, delivered, read, played, error.

Presence updates ​

ruby
# Subscribe to a contact's presence
client.subscribe_presence("+33612345678")

# React to presence changes
client.on_presence_update do |data|
  # data = { id: "[email protected]", presences: { ... } }
  puts data
end

Read receipts ​

ruby
# Mark messages as read (send blue ticks)
client.read_messages([
  { remote_jid: "[email protected]", id: "msg123" }
])

# React to read receipts from contacts
client.on_message_receipt do |data|
  puts data
end

Poll votes ​

Poll votes are encrypted by WhatsApp. The bridge automatically decrypts them using Baileys' getAggregateVotesInPollMessage and emits a high-level poll.vote event.

ruby
client.on_poll_vote do |data|
  data[:poll_message_id]  # ID of the poll message
  data[:remote_jid]       # JID of the chat
  data[:votes]            # [{ name: "Option A", voters: ["jid1", ...] }, ...]
end

Low-level events ​

ruby
client.on('qr')              { |data| ... }  # QR code for authentication
client.on('connected')       { |data| ... }  # Connected
client.on('disconnected')    { |data| ... }  # Connection lost
client.on('message.new')     { |msg|  ... }  # Live incoming (same as on_message)
client.on('message')         { |msg|  ... }  # All messages (live + history sync)
client.on('message.status')  { |data| ... }  # Message delivery status update
client.on('health.ok')       { |data| ... }  # Heartbeat success
client.on('health.failure')  { |data| ... }  # Heartbeat failure
client.on('health.recovered'){ |data| ... }
client.on('presence.update')            { |data| ... }  # Presence change
client.on('message-receipt.update')     { |data| ... }  # Read receipt
client.on('poll.vote')                  { |data| ... }  # Poll vote results

History sync vs live messages ​

On first connection, Baileys syncs your message history. on_message filters these out and only delivers real-time messages. Use on_message_any if you need the full history.

ruby
client.on_message_any { |msg| ... }  # All messages including history sync

Message object ​

ruby
client.on_message do |msg|
  msg.id                # Message ID
  msg.from              # Sender JID ("[email protected]")
  msg.text              # Text content
  msg.timestamp         # Time object
  msg.type              # :text, :image, :video, :audio, :document, :sticker, :location, :contact
  msg.from_me?          # Sent by you?
  msg.group?            # From a group chat?
  msg.media?            # Contains media? (image, video, audio, document, sticker)
  msg.location?         # Location message?
  msg.contact?          # Contact card?
  msg.reply?            # Reply to another message?
  msg.caption           # Media caption
  msg.location          # { latitude:, longitude:, name:, address: }
  msg.contact_info      # { display_name:, vcard: }
  msg.quoted_message_id # ID of the quoted message
  msg.raw               # Full raw data hash from Baileys
end

Error handling ​

ruby
begin
  client.send_message(to: "+33...", text: "hello")
rescue Whatsapp::RateLimited => e
  # Rate limit exceeded — wait and retry
rescue Whatsapp::NotConnected
  # WhatsApp not connected — scan QR or reconnect
rescue Whatsapp::BridgeNotRunning
  # Node bridge process is not running
rescue Whatsapp::BridgeTimeout
  # Bridge failed to start within timeout
rescue Whatsapp::BridgeError => e
  # Bridge HTTP error (e.status_code, e.body)
rescue Whatsapp::NodeNotFound
  # Node.js not found on the system
rescue Whatsapp::MessageFailed => e
  # Delivery failed (e.to, e.reason)
end

Error classes reference ​

ClassDescription
Whatsapp::ErrorBase error class (extends StandardError)
Whatsapp::BridgeNotRunningBridge Node.js process is not running
Whatsapp::BridgeTimeoutBridge failed to start within configured timeout
Whatsapp::BridgeErrorHTTP error from bridge (status_code, body)
Whatsapp::NotConnectedClient is not connected to WhatsApp
Whatsapp::MessageFailedMessage delivery failed (to, reason)
Whatsapp::NodeNotFoundNode.js binary not found on the system
Whatsapp::RateLimitedRate limit exceeded (period, limit, current, recipient)
Whatsapp::WebhookSignatureErrorWebhook HMAC signature verification failed
Whatsapp::WhatsAppErrorWhatsApp protocol/server error (code)

MIT License