New features
One dependency is enough
whatsapp-rust now re-exports wacore, wacore_binary, and waproto wholesale. A consumer needs exactly one Cargo.toml line:
whatsapp_rust::wacore::..., whatsapp_rust::waproto::whatsapp, etc.) are reachable through the main crate, including when pinning a git revision.
UreqHttpClient moved from the misplaced whatsapp_rust::transport to whatsapp_rust::http. A new whatsapp_rust::prelude covers the common bot path in one import line (including wa as the protobuf alias):
Simplified lifecycle
Bot::run(self) now runs the bot on the current task with a single await. Bot::spawn(self) starts it in the background and returns a BotHandle:
BotHandle resolves to () (was Result<(), Canceled>). Dropping the handle still aborts the task — the e2e harness relies on this.
Builder defaults
With the default cargo features, transport, HTTP client, and runtime are pre-filled (Tokio WebSocket, ureq, Tokio), so only the backend has to be provided:with_* setters are now available in every typestate, so they also work as overrides. The typestate markers got names (MissingBackend, MissingTransport, MissingHttpClient, MissingRuntime) — a missing-field compile error now names which field is missing.
with_backend accepts impl Backend + 'static (no caller-side Arc::new). with_backend_arc accepts an already-shared Arc<dyn Backend>.
Typed event registrars
Dedicated builder methods cover the common event path — nomatch &*event needed:
on_event / on_event_for are unchanged as catch-alls. with_event_handler registers a struct-based EventHandler directly on the bus for stateful handlers (eliminates the clone-dance that closure captures force on consumers).
All handlers accumulate — registering a second handler now runs both instead of silently replacing the first.
The bus still skips materializing events nobody wants: the adapter registers the union of all handler interests and filters per handler at dispatch.
Messaging sugar
New helpers for the common send paths:ctx.send_message(wa::Message { ... }) path is unchanged for advanced cases.
BotBuilderError typed
BotBuilderError::Other(anyhow) is gone. The only variant is now Store(StoreError) — the one error build() can actually produce.
Breaking changes
| Old | New |
|---|---|
bot.run().await?.await? | bot.run().await (foreground) or let handle = bot.spawn() (background) |
.with_backend(Arc::new(store)) | .with_backend(store) — Arc wrapping is internal |
.with_backend(arc) for a shared Arc | .with_backend_arc(arc) |
use whatsapp_rust::transport::UreqHttpClient | use whatsapp_rust::http::UreqHttpClient |
bot::Missing typestate marker | bot::MissingBackend / MissingTransport / MissingHttpClient / MissingRuntime |
BotBuilderError::Other(anyhow) | removed; only BotBuilderError::Store(StoreError) |
| Registering two handlers — second replaces first | Both run; handlers accumulate |
Migration guide
Lifecycle:UreqHttpClient import:
Cargo.toml: