Documentation Index Fetch the complete documentation index at: https://mintlify.com/jlucaso1/whatsapp-rust/llms.txt
Use this file to discover all available pages before exploring further.
Overview
WhatsApp-Rust is a high-performance, async Rust library for the WhatsApp Web API. The project follows a modular, layered architecture that separates protocol concerns from runtime concerns, enabling platform-agnostic core logic with pluggable backends.
Workspace Structure
The project is organized as a Cargo workspace with multiple crates:
whatsapp-rust/
├── src/ # Main client library
├── wacore/ # Platform-agnostic core
│ ├── binary/ # WhatsApp binary protocol
│ ├── libsignal/ # Signal Protocol implementation
│ ├── appstate/ # App state management
│ ├── noise/ # Noise Protocol handshake
│ └── derive/ # Derive macros
├── waproto/ # Protocol Buffers definitions
├── storages/sqlite-storage/ # SQLite backend
├── transports/tokio-transport/ # Tokio WebSocket transport
└── http_clients/ureq-client/ # HTTP client for media
Three Main Crates
Location: wacore/
Purpose: Contains core logic for the WhatsApp binary protocol, cryptography primitives, IQ protocol types, and state management traits.
Key Features:
No runtime dependencies on Tokio or specific databases
Pure protocol implementation
Cryptographic operations (Signal Protocol, Noise Protocol)
Type-safe protocol node builders
Key Modules:
wacore /
├── binary / // Binary protocol encoding/decoding
├── libsignal / // E2E encryption
├── noise / // Noise Protocol handshake
├── appstate / // App state sync protocol
├── iq / // Type-safe IQ protocol types
├── protocol . rs // ProtocolNode trait
├── types /
│ ├── events . rs // Event definitions
│ └── message . rs // Message types
└── store /
├── traits . rs // Storage trait definitions
└── device . rs // Device state model
waproto - Protocol Buffers
Location: waproto/
Purpose: Houses WhatsApp’s Protocol Buffers definitions compiled to Rust structs.
Build Process:
// build.rs uses prost to compile .proto files
prost_build :: compile_protos ( & [ "src/whatsapp.proto" ], & [ "src/" ]) ? ;
Generated Types:
Message - All message types
WebMessageInfo - Message metadata
HistorySync - Chat history
SyncActionValue - App state mutations
whatsapp-rust - Main Client
Location: src/
Purpose: Integrates wacore with the Tokio runtime, provides high-level client API, and manages storage.
Key Features:
Asynchronous operations with Tokio
SQLite persistence (pluggable)
Event bus system
Feature modules (groups, media, etc.)
Key Components
Client
Location: src/client.rs
Purpose: Orchestrates connection lifecycle, event bus, and high-level operations.
pub struct Client {
pub ( crate ) core : wacore :: client :: CoreClient ,
pub ( crate ) persistence_manager : Arc < PersistenceManager >,
pub ( crate ) media_conn : Arc < RwLock < Option < MediaConn >>>,
pub ( crate ) noise_socket : Arc < Mutex < Option < Arc < NoiseSocket >>>>,
// ... connection state, caches, locks
}
Responsibilities:
Connection management
Request/response routing
Event dispatching
Session management
PersistenceManager
Location: src/store/persistence_manager.rs
Purpose: Manages all state changes and persistence.
pub struct PersistenceManager {
device : Arc < RwLock < Device >>,
backend : Arc < dyn Backend >,
dirty : Arc < AtomicBool >,
save_notify : Arc < Notify >,
}
Critical Pattern:
Never modify Device state directly
Use DeviceCommand + process_command()
For read-only: get_device_snapshot()
Signal Protocol
Location: wacore/libsignal/ & src/store/signal*.rs
Purpose: End-to-end encryption via Signal Protocol implementation.
Features:
Double Ratchet algorithm
Pre-key bundles
Session management
Sender keys for groups
Socket & Handshake
Location: src/socket/, src/handshake.rs
Purpose: WebSocket connection and Noise Protocol handshake.
Flow:
WebSocket connection
Noise handshake (XX pattern)
Encrypted frame exchange
Module Interactions
Layer Responsibilities
Protocol logic
State traits
Cryptographic helpers
Data models
Example: IQ Protocol
// wacore/src/iq/groups.rs
pub struct GroupQueryIq {
group_jid : Jid ,
}
impl IqSpec for GroupQueryIq {
type Response = GroupInfoResponse ;
fn build_iq ( & self ) -> InfoQuery <' static > { /* ... */ }
fn parse_response ( & self , response : & Node ) -> Result < Self :: Response > { /* ... */ }
}
whatsapp-rust Layer (Runtime)
Runtime orchestration
Storage integration
User-facing API
Example: Feature API
// src/features/groups.rs
impl Client {
pub async fn get_group_info ( & self , jid : & Jid ) -> Result < GroupInfoResponse > {
self . execute ( GroupQueryIq :: new ( jid )) . await
}
}
Protocol Entry Points
Incoming Messages
Flow: src/message.rs → Signal decryption → Event dispatch
// src/message.rs
pub async fn handle_message ( client : & Arc < Client >, node : & Node ) {
// 1. Extract encrypted message
// 2. Decrypt via Signal Protocol
// 3. Dispatch Event::Message
}
Outgoing Messages
Flow: src/send.rs → Signal encryption → Socket send
// src/send.rs
pub async fn send_message ( client : & Arc < Client >, msg : & Message ) {
// 1. Encrypt via Signal Protocol
// 2. Build protocol node
// 3. Send via NoiseSocket
}
Socket Communication
Flow: src/socket/ → Noise framing → Transport
// src/socket/mod.rs
impl NoiseSocket {
pub async fn send_node ( & self , node : Node ) -> Result <()> {
// 1. Marshal to binary
// 2. Encrypt with Noise
// 3. Frame and send
}
}
Concurrency Patterns
Per-Chat Message Queues
Prevents race conditions where a later message is processed before the PreKey message:
pub ( crate ) message_queues : Cache < String , mpsc :: Sender < Arc < Node >>>,
Per-Device Session Locks
Prevents concurrent Signal protocol operations on the same session:
pub ( crate ) session_locks : Cache < String , Arc < tokio :: sync :: Mutex <()>>>,
Background Saver
Periodic persistence with dirty flag optimization:
impl PersistenceManager {
pub fn run_background_saver ( self : Arc < Self >, interval : Duration ) {
tokio :: spawn ( async move {
loop {
// Wait for notification or interval
self . save_to_disk () . await ;
}
});
}
}
Feature Organization
Location: src/features/
features/
├── mod.rs // Feature exports
├── groups.rs // Group management
├── presence.rs // Presence updates
├── media.rs // Media upload/download
└── contacts.rs // Contact operations
Pattern:
impl Client {
/// High-level feature method
pub async fn create_group ( & self , subject : & str , participants : & [ Jid ]) -> Result < Jid > {
// Use wacore IqSpec for protocol
let spec = CreateGroupIq :: new ( subject , participants ) ? ;
self . execute ( spec ) . await
}
}
State Management Flow
Best Practices
State Management
// Use DeviceCommand for state changes
client . persistence_manager
. process_command ( DeviceCommand :: SetPushName ( name ))
. await ;
Async Operations
// Wrap blocking I/O in spawn_blocking
let result = tokio :: task :: spawn_blocking ( move || {
// Heavy crypto or blocking HTTP
expensive_operation ()
}) . await ? ;
Error Handling
use thiserror :: Error ;
use anyhow :: Result ;
#[derive( Debug , Error )]
pub enum SocketError {
#[error( "connection closed" )]
Closed ,
#[error( "encryption failed: {0}" )]
Encryption ( String ),
}
// Use anyhow::Result for functions with multiple error types
pub async fn complex_operation () -> Result <()> {
// Automatically converts errors with ?
socket_operation () ? ;
storage_operation () ? ;
Ok (())
}
Authentication Learn about QR code and pair code flows
Events Understand the event system and handlers
Storage Explore storage backends and state management
Getting Started Build your first WhatsApp bot