Expand description
§whatsapp-rust
A high-performance, async Rust library for the WhatsApp Web API. Inspired by whatsmeow (Go) and Baileys (TypeScript).
Documentation | llms.txt | llms-full.txt
§Features
- Authentication — QR code pairing, pair code linking, persistent sessions
- Messaging — E2E encrypted (Signal Protocol), 1-on-1 and group chats, editing, reactions, quoting, receipts
- Media — Upload/download images, videos, documents, GIFs, audio with automatic encryption
- Voice calls — 1:1 VoIP audio calls with built-in MLOW or external encoded Opus/MLOW; see the codec boundary and production profiles
- Groups & Communities — Create, manage, invite, membership approval, subgroup linking
- Newsletters — Create, join, send messages, reactions
- Status — Text, image, and video status posts with privacy controls
- Contacts — Phone number lookup, profile pictures, user info, business profiles
- Presence & Chat State — Online/offline, typing indicators, blocking
- Chat Actions — Archive, pin, mute, star messages
- Profile — Set push name, status text, profile picture
- Privacy — Fetch/set privacy settings, disappearing messages
- Modular — Pluggable storage, transport, HTTP client, and async runtime; SQLite, Tokio WebSocket, and ureq ship as the defaults, swap any of them with
default-features = false - Native plugins — Build-time, type-safe extensions with scoped capabilities and lifecycle ownership behind the
pluginsfeature - Runtime agnostic — Bring your own async runtime via the
Runtimetrait (Tokio included by default)
For the full API reference and guides, see the documentation.
§Quick Start
[dependencies]
whatsapp-rust = "0.7"
tokio = { version = "1", features = ["macros", "rt-multi-thread", "signal"] }use whatsapp_rust::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let bot = Bot::builder()
.with_backend(SqliteStore::new("whatsapp.db").await?)
.on_qr_code(|code, _timeout| async move {
println!("Scan to pair:\n{code}");
})
.on_message(|ctx| async move {
if ctx.message.text_content() == Some("ping") {
let _ = ctx.reply("pong").await;
}
})
.build()
.await?;
// Runs until logout or shutdown; a single await.
bot.run().await;
Ok(())
}The default cargo features wire up the Tokio WebSocket transport, the ureq HTTP client, the SQLite store, and the Tokio runtime; only the storage backend has to be chosen explicitly. Every piece is replaceable through the builder (with_transport_factory, with_http_client, with_runtime) for custom environments such as wasm or embedded targets.
Native plugin APIs are opt-in: use features = ["plugins"] when implementing a
plugin in the application. Published plugin crates can enable that feature in
their own whatsapp-rust dependency, and Cargo feature unification activates it
for the consumer. See agent_docs/plugin_architecture.md
for the host contract and type-safe API example.
§One dependency is enough
whatsapp-rust re-exports the whole stack, so you never need to declare the sibling crates (wacore, wacore-binary, waproto, whatsapp-rust-tokio-transport, whatsapp-rust-ureq-http-client, whatsapp-rust-sqlite-storage) yourself, including when pinning a git revision:
[dependencies]
whatsapp-rust = { git = "https://github.com/oxidezap/whatsapp-rust", rev = "<commit>" }- Protobuf types:
whatsapp_rust::waproto::whatsapp(aliased aswain the prelude) - Core protocol/types:
whatsapp_rust::wacore,whatsapp_rust::wacore_binary(Jidis also at the crate root) - Bundled implementations:
whatsapp_rust::transport::TokioWebSocketTransportFactory,whatsapp_rust::http::UreqHttpClient,whatsapp_rust::store::SqliteStore, each behind its default-on cargo feature (tokio-transport,ureq-client,sqlite-storage)
With default-features = false, pick only what you need (e.g. features = ["tokio-runtime", "tokio-transport", "ureq-client"] for a custom store while keeping the bundled networking).
To run the bot in the background instead of blocking, use spawn() and keep the handle:
use whatsapp_rust::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let bot = Bot::builder()
.with_backend(SqliteStore::new("whatsapp.db").await?)
.build()
.await?;
let handle = bot.spawn(); // full Client API stays available via handle.client()
tokio::signal::ctrl_c().await?;
handle.shutdown().await; // graceful: flushes pending state, then stops
Ok(())
}Run the included demo bot:
cargo run --example demo # QR code only
cargo run --example demo -- -p 15551234567 # Pair code + QR code
cargo run --example demo -- -p 15551234567 -c MYCODE # Custom pair code§Project Structure
whatsapp-rust/
├── src/ # Main client library
├── wacore/ # Platform-agnostic core (no runtime deps)
│ ├── binary/ # WhatsApp binary protocol
│ ├── libsignal/ # Signal Protocol implementation
│ └── appstate/ # App state management
├── waproto/ # Protocol Buffers definitions
├── storages/sqlite-storage # SQLite backend
├── transports/tokio-transport
└── http_clients/ureq-client§Disclaimer
This is an unofficial, open-source reimplementation. Using custom WhatsApp clients may violate Meta’s Terms of Service and could result in account suspension. Use at your own risk.
§Acknowledgements
Re-exports§
pub use cache::Freshness;pub use cache_config::CacheConfig;pub use cache_config::CacheEntryConfig;pub use cache_config::CacheStores;pub use client::ClientError;pub use client::NodeFilter;pub use client::MemoryReport;pub use client::ResourceReport;pub use client::CallError;pub use client::Voip;pub use client::Client;pub use client::ClientBuild;pub use client::ClientBuilder;pub use client::ClientBuilderError;pub use client::RawNodeLease;pub use client::ClientLifecycle;client-lifecyclepub use client::ConnectionScope;client-lifecyclepub use client::ConnectionScopeState;client-lifecyclepub use client::ConnectError;pub use client::ConnectStage;pub use client::SignalMaintenanceError;pub use types::durability_hook::InboundDurabilityHook;pub use types::retry_admission::RetryAdmission;pub use error::ErrorChainExt;pub use error::ServerRejection;pub use error::Sources;pub use handlers::chatstate::ChatStateEvent;pub use plugins::ClientPlugin;pluginspub use plugins::PluginCapabilities;pluginspub use plugins::PluginCapability;pluginspub use plugins::PluginConnectionScope;pluginspub use plugins::PluginConnectionTasks;pluginspub use plugins::PluginContext;pluginspub use plugins::PluginCoreEventSubscription;pluginspub use plugins::PluginCoreEvents;pluginspub use plugins::PluginEventEndpointConfig;pluginspub use plugins::PluginEventEndpointStats;pluginspub use plugins::PluginEventEnvelope;pluginspub use plugins::PluginEventOverflow;pluginspub use plugins::PluginEventPayloadEncoding;pluginspub use plugins::PluginEventPublishError;pluginspub use plugins::PluginEventPublishReport;pluginspub use plugins::PluginEventPublisherStats;pluginspub use plugins::PluginEventReceiveError;pluginspub use plugins::PluginEventRouteError;pluginspub use plugins::PluginEventRouter;pluginspub use plugins::PluginEventRouterStats;pluginspub use plugins::PluginEventSelector;pluginspub use plugins::PluginEventSubscribeError;pluginspub use plugins::PluginEventSubscription;pluginspub use plugins::PluginEventTopic;pluginspub use plugins::PluginEventTryReceiveError;pluginspub use plugins::PluginEvents;pluginspub use plugins::PluginFuture;pluginspub use plugins::PluginHealth;pluginspub use plugins::PluginHostConfig;pluginspub use plugins::PluginHostStats;pluginspub use plugins::PluginIq;pluginspub use plugins::PluginIqError;pluginspub use plugins::PluginManifest;pluginspub use plugins::PluginMessaging;pluginspub use plugins::PluginMessagingError;pluginspub use plugins::PluginPlanError;pluginspub use plugins::PluginResourceError;pluginspub use plugins::PluginState;pluginspub use plugins::PluginStats;pluginspub use plugins::PluginTasks;pluginspub use plugins::UntypedClientPlugin;pluginspub use request::IqError;pub use runtime_impl::TokioRuntime;tokio-runtimepub use send::EditOptions;pub use send::PinDuration;pub use send::RevokeType;pub use send::SendError;pub use send::SendOptions;pub use send::SendResult;pub use upload::UploadOptions;pub use features::AppStateError;pub use features::BatchGroupResult;pub use features::Blocking;pub use features::BlockingError;pub use features::ChatActions;pub use features::ChatStateError;pub use features::ChatStateType;pub use features::Chatstate;pub use features::Comments;pub use features::Community;pub use features::CommunityError;pub use features::CommunitySubgroup;pub use features::ContactError;pub use features::Contacts;pub use features::CreateCommunityOptions;pub use features::CreateCommunityResult;pub use features::CreateGroupResult;pub use features::EncryptedEdit;pub use features::EventCreationParams;pub use features::Events;pub use features::GroupError;pub use features::GroupMetadata;pub use features::GroupParticipant;pub use features::GroupType;pub use features::Groups;pub use features::Labels;pub use features::LinkSubgroupsResult;pub use features::MediaReupload;pub use features::MediaReuploadError;pub use features::MediaReuploadRequest;pub use features::MessageEditError;pub use features::MessageRetransmission;pub use features::Mex;pub use features::MexError;pub use features::MexRequest;pub use features::Newsletter;pub use features::NewsletterError;pub use features::NewsletterMessage;pub use features::NewsletterMessageType;pub use features::NewsletterMetadata;pub use features::NewsletterReactionCount;pub use features::NewsletterRole;pub use features::NewsletterState;pub use features::NewsletterVerification;pub use features::PollError;pub use features::PollOptionResult;pub use features::Polls;pub use features::Presence;pub use features::PresenceError;pub use features::PresenceStatus;pub use features::PreviousDescription;pub use features::Profile;pub use features::ProfileError;pub use features::RetryRequestError;pub use features::RetryRequestOptions;pub use features::RetryRequestOutcome;pub use features::SecretEncKind;pub use features::SecretEncrypted;pub use features::Signal;pub use features::SignalError;pub use features::SignalSessionInfo;pub use features::SignalSessionMigration;pub use features::StanzaRejection;pub use features::StanzaResponseError;pub use features::Status;pub use features::StatusPrivacySetting;pub use features::StatusSendOptions;pub use features::SyncActionMessageRange;pub use features::TcToken;pub use features::TcTokenError;pub use features::UnlinkSubgroupsResult;pub use features::group_type;pub use features::message_key;pub use features::message_range;pub use shutdown::shutdown_signal;signalpub use wacore;pub use wacore_binary;pub use waproto;pub use anyhow;pub use async_channel;pub use bytes;pub use futures;pub use serde;pub use serde_json;pub use wacore::chrono;pub use waproto::buffa;
Modules§
- appstate_
sync - bot
- cache
- The client’s in-process cache type.
- cache_
config - cache_
store - Typed cache wrapper that dispatches to either the in-process
Cacheor a customCacheStorebackend (e.g., Redis). - client
- download
- error
- Typed recovery over the error chain.
- features
- handlers
- handshake
- history_
sync - http
- jid_
utils - keepalive
- lid_
pn_ cache - LID-PN (Linked ID to Phone Number) Cache
- media
- High-level media-message builders.
- mediaconn
- Media connection management.
- message
- pair
- pair_
code - Pair code authentication for phone number linking.
- passkey
PasskeyAuthenticator— the single pluggable point of the SHORTCAKE_PASSKEY login flow (seewacore::shortcakefor the deterministic protocol core).- pdo
- PDO (Peer Data Operation) support for requesting message content from the primary device.
- plugins
plugins - Build-time client plugins and their capability-scoped host.
- portable_
cache - Portable in-process cache: the client’s sole cache backend, on every target including wasm32.
- prekeys
- Pre-key management for Signal Protocol.
- prelude
- One-import surface for the common bot path:
use whatsapp_rust::prelude::*;. - privacy_
settings - Privacy settings IQ specification.
- proto_
helpers - receipt
- request
- retry
- runtime_
impl tokio-runtime - schemas
- Auto-generated AppState (syncd) action schemas (WhatsApp 2.3000.1042742319). DO NOT EDIT.
- send
- Outgoing message pipeline.
- session
- shutdown
signal - Graceful-shutdown signal for the bundled binaries.
- socket
- spam_
report - Spam reporting feature.
- sticker_
pack - Sticker pack creation helpers.
- store
- sync_
task - telemetry
- Optional metrics emission (the
metricsfeature). No-op when the feature is off. Optional metrics emission via themetricsfacade. - traits
- Storage traits for the WhatsApp client.
- transport
- types
- unified_
session - Unified session telemetry manager.
- upload
- usync
- User device list synchronization.
- version
- webp
- WebP format utilities.
Macros§
- require_
from_ jid - Extract the required
fromJID attribute from aNodeRef, or log a warning and return from the enclosing function.
Structs§
- Alloc
Snapshot - Point-in-time copy of an
AllocMeter. Counters are cumulative over the meter’s lifetime. - Blocklist
Entry - A single blocklist entry from the response.
- Client
Profile - Collection
Stats - Entry count plus estimated retained bytes for one internal collection.
- Compact
String - A
CompactStringis a compact string type that can be used almost anywhere aStringorstrcan be used. - Group
Create Options - Options for creating a new group.
- Group
Description - A validated group description string.
- Group
Ephemeral Settings - Disappearing-message settings carried by a group’s
<ephemeral>node. - Group
Participant Details - Less-common participant metadata, allocated only when at least one field is present.
- Group
Participant Options - Options for a participant when creating a group.
- Group
Profile Picture - A single group profile picture result.
- Group
Subject - A validated group subject string.
- Growth
Lock Info - Growth lock info (system-managed, read-only).
- Http
Resource Report - Per-session footprint of a
crate::net::HttpClient: idle connection-pool buffers plus any in-flight download/media buffering the impl can see. - IsOn
Whats AppResult - Jid
- Membership
Request - MexError
Extensions - MEX GraphQL error extensions.
- MexGraphQL
Error - MEX GraphQL error.
- MexResponse
- MEX GraphQL response.
- MsgSecret
Retention - Per-add-on-kind retention horizons applied to the parent message’s event time. Defaults are derived from verified protocol limits, not guesses.
- Node
Builder - Owned
Node Ref - A decoded node that owns its decompressed buffer. The inner
NodeRefborrows string/byte payloads directly from the buffer, avoiding copies. Container allocations (attribute Vec, child Vec) still occur during decode. - Participant
Change Response - Response for participant change operations. Success:
erroris None;typeis often omitted by the server. Onerror == "403"the<add_request>child (add_requestfield) carries the V4 invite token. - Poll
Vote Ciphertext - The encrypted vote payload and its GCM IV, paired so the two same-typed byte slices can’t be transposed at a call site.
- Profile
Picture - Profile picture information.
- Reachout
Timelock - SetProfile
Picture Response - Response from setting a profile picture.
- Spam
Report Request - A request to report a message as spam.
- Spam
Report Result - The result of a spam report.
- Stats
Snapshot - Point-in-time copy of
SessionStats, plus client-level counters the client fills in (Self::reconnect_errors,Self::resends_throttled). - Storage
Resource Report - Process-local resource footprint a storage backend attributes to one
session. Returned by
store::traits::DeviceStore::resource_report. - Transport
Resource Report - Per-session footprint of a
crate::net::Transport: read/write framing buffers plus a best-effort TLS/noise session-state estimate. - User
Info - User information from usync.
- Usync
Subprotocol Error - Verified
Name - Verified name certificate information.
Enums§
- EncType
- Classification of an encryption node’s type.
- Event
Response Type - Group
Appeal Status - Review state for an appeal on a suspended group.
- Group
Join Error - Error codes returned when joining a group via invite.
- Invite
Info Error - Error codes returned when querying invite group info.
- Join
Group Result - Result of joining a group via invite code.
- Media
Retry Result - Result of a media retry request.
- Member
AddMode - Member add mode for who can add participants.
- Member
Link Mode - Member link mode for group invite links.
- Member
Share History Mode - Who can share message history with new members.
- Membership
Approval Mode - Membership approval mode for join requests.
- MsgSecret
Policy - How the core manages
messageSecretpersistence. - Nack
Reason - Participant
Type - Participant type (admin level).
- Picture
Type - Profile picture query type.
- Retry
Reason - Retry reason codes matching WhatsApp Web’s RetryReason enum. These are included in the retry receipt to help the sender understand why the message couldn’t be decrypted.
- Server
- Known WhatsApp server identifiers.
- Spam
Flow - The type of spam flow indicating the source of the report.
- Stanza
Type - Type-safe
<message type="...">value for the send-time override.
Traits§
- Cache
Store - Backend trait for pluggable cache storage.
- Original
Message Resolver - App-supplied fallback returning a parent message’s 32-byte
messageSecreton a store miss, keyed by the non-AD(chat, sender, msg_id). - Runtime
- A runtime-agnostic abstraction over async executor capabilities.