Skip to main content
The Presence struct provides methods for managing your online/offline status and subscribing to contact presence updates.

Access

Access presence operations through the client:

Methods

set

Set your presence status (online or offline).
Parameters:
  • status: PresenceStatus - Either Available (online) or Unavailable (offline)
Requirements:
  • Push name must be set before sending presence
  • Returns error if push name is empty
Example:

set_available

Convenience method to set status to available (online).
Example:

set_unavailable

Convenience method to set status to unavailable (offline).
Example:

subscribe

Subscribe to a contact’s presence updates.
Parameters:
  • jid - Contact JID to subscribe to
Behavior:
  • Sends a <presence type="subscribe"> stanza
  • Automatically includes TC token if available for the contact
  • Tracks the subscription internally so it can be restored on reconnect
  • Used to receive notifications when the contact goes online/offline
Example:

unsubscribe

Unsubscribe from a contact’s presence updates.
Parameters:
  • jid - Contact JID to unsubscribe from
Behavior:
  • Sends a <presence type="unsubscribe"> stanza
  • Removes the contact from the internal subscription tracker
  • You will no longer receive presence updates for this contact
Example:

PresenceStatus Enum

PresenceStatus is #[non_exhaustive], so match statements should include a wildcard arm to handle future variants. Methods:
  • as_str() - Returns "available" or "unavailable"
Conversion:

Push name requirement

WhatsApp requires a push name (display name) to be set before sending presence updates. This matches WhatsApp Web behavior. Error example:
The push name is typically set during the pairing/connection process from app state sync.

Wire Format

Setting Presence

Subscribing to Presence

Unsubscribing from Presence

TC token handling

When subscribing to presence, the library automatically:
  • Looks up TC token for the target JID
  • Includes token as child node if available
  • Skips token if not found (non-error)
This matches WhatsApp Web’s privacy gating behavior.

Subscription Tracking

The library automatically tracks which contacts you have subscribed to. This enables automatic re-subscription after a reconnect, so you don’t lose presence updates when the connection drops.

How it works

  • Calling subscribe(jid) adds the contact to an internal tracked set
  • Calling unsubscribe(jid) removes the contact from the tracked set
  • Duplicate subscriptions are deduplicated automatically
  • On reconnect, the library re-subscribes to all tracked contacts

Automatic re-subscription on reconnect

When the client reconnects after a connection drop, it automatically calls resubscribe_presence_subscriptions() to restore all tracked presence subscriptions. This happens transparently — you don’t need to manually re-subscribe after a reconnect. As of whatsapp-rust#1405, the walk is windowed rather than one contact at a time: tracked JIDs are processed 8 at a time (matching the noise sender’s own queue depth), with one get_tc_tokens call per window instead of one lookup per contact, and the window’s <presence type="subscribe"> stanzas issued together so the transport sender can coalesce them into fewer writes. For 24 tracked contacts this is 3 batched calls instead of 24 individual lookups — a backend that hasn’t overridden get_tc_tokens’s default still runs one query per JID underneath each call, but the built-in SqliteStore collapses each window to a single IN (...) query, i.e. 3 DB reads instead of 24. The transport writes only shrink to the extent the sender coalesces the window’s stanzas; the guarantee is fewer writes than one per contact, not a fixed count. The re-subscription process includes safety checks, now applied per window rather than per JID:
  • Bails out early if the connection generation changes (a new reconnect occurred), so a reconnect landing mid-walk stops it within one window rather than after the whole tracked set
  • Skips re-subscription if the client is no longer connected
  • Re-checks each JID against the tracked set both before and after its window’s tcToken lookup, so an unsubscribe racing the walk is honored — a JID unsubscribed before its window starts, or while the window’s lookup is in flight, is left out of that window’s sends rather than resubscribed
This matches WhatsApp Web behavior, which re-subscribes to all active presence subscriptions after reconnecting. The per-window (rather than per-JID) safety checks are a narrower guarantee than a strictly per-JID re-check would give, but the batching that motivates it — coalesced backend reads and transport writes — needs a unit wider than one JID to pay off.

Behavior Notes

Available (Online)

When setting status to Available, the library automatically:
  1. Validates push name is set
  2. Sends unified session (internal protocol requirement)
  3. Broadcasts presence stanza with push name

Unavailable (Offline)

When setting status to Unavailable:
  1. Validates push name is set
  2. Broadcasts unavailable presence
Note: This marks you as offline but doesn’t disconnect the client.

PresenceError

The set, set_available, and set_unavailable methods return Result<(), PresenceError>:
Variants:
  • PushNameEmpty - Push name must be set before sending presence
  • Client — wraps a ClientError (connection errors from set, set_available, set_unavailable, subscribe, and unsubscribe)
  • Other - Wraps any other error (network, connection, etc.)

Error handling

Complete Example

Receiving presence updates

After subscribing to a contact’s presence, you’ll receive presence events through the event handler. See the Events documentation for details on handling incoming presence updates.