Skip to content

Architecture ​

Ruby app
    │
    ├── HTTP  ──► commands (send, status, session...)
    └── WS    ◄── real-time events (messages, QR, connection...)
            │
            ▼
    Node.js bridge (Fastify + Baileys)
            │
            ▼
    WhatsApp Web (WebSocket)

The gem spawns a local Node.js process running a Fastify HTTP + WebSocket server wrapping Baileys. All communication stays on 127.0.0.1 with a dynamic port. Sessions are persisted to disk so you only need to scan the QR code once.

In multi-session mode, each session gets its own bridge process, dynamic port, and auth directory (auth_dir/SessionName/).

Key design decisions ​

DecisionWhy
Bridge over FFIBaileys is JS-only — a bridge is the only clean option
Fastify (not Express)Faster, built-in schema validation, native WebSocket
HTTP + WebSocketHTTP for request/response, WS for real-time events
Dynamic portNo conflicts, supports multiple sessions
1 session = 1 bridgeFull isolation per WhatsApp account
Baileys pinned to commitnpm releases lag behind, protocol changes break things
Double rate limitingRuby controls the flow, bridge is the safety net
Gaussian jitterRandom delays that look human, not uniform bot patterns

Class overview ​

ClassRole
Whatsapp::ClientCore client — connect, send, events
Whatsapp::SessionNamed session wrapping a Client (status, QR, heartbeat)
Whatsapp::SessionManagerThread-safe session registry
Whatsapp::AccountProxyProxy for account: true mode
Whatsapp::RecordProxyProxy for destination mode (has_whatsapp :phone)
Whatsapp::BridgeHTTP + WebSocket communication with Node bridge
Whatsapp::ConnectionSpawns/kills the Node bridge process
Whatsapp::HeartbeatPeriodic health check thread
Whatsapp::RateLimiterRuby-side rate limiting with gaussian jitter
Whatsapp::MessageHandlerBase class for incoming message handlers
Whatsapp::MessageDispatcherDispatches messages to configured handler
Whatsapp::NotifierNotification service with templates and bulk
Whatsapp::EventsEvent emitter
Whatsapp::MessageParsed incoming message
Whatsapp::GroupWhatsApp group object (id, subject, participants)
Whatsapp::WLoggerSecure logger with secret filtering

MIT License