Skip to main content

Overview

By default, every inbound history-sync notification from the phone is accepted and enters the major-sync queue for download, decompression, and dispatch as Event::HistorySync. That matches WhatsApp Web’s behavior and is the right choice for a client that needs history. A bot that only cares about a subset of syncs — or that wants to skip peer-data-request chunks, cap per-chunk size, or drop everything past initial pairing — can register a HistorySyncAdmission policy. The policy runs synchronously on the receive path and can reject a notification before the client starts any history-sync activity. Leaving the policy unset keeps the default behavior at zero cost. The receive path only checks that the optional policy is None.
This is an opt-in seam. Rejecting a notification is a deliberate decision to drop a chunk the phone offered; the SDK will never do this on its own.

When to use it

Consider a policy when:
  • You want to admit some history-sync types but not others (for example, accept INITIAL_BOOTSTRAP but reject RECENT).
  • You want to bound per-chunk cost with a size guard on file_length or inline_payload_len.
  • You want to drop peer-data-request responses that your bot never issued.
  • You need finer control than the all-or-nothing .skip_history_sync() toggle already exposes.
Use .skip_history_sync() if you want to drop every history-sync notification unconditionally. That toggle is simpler and takes precedence over any registered admission policy — the policy is not consulted when skip_history_sync is on. Registration for device pairing and the require_full_sync request are unchanged. The policy runs after pairing completes and only gates the delivery of individual history-sync chunks from the phone.

Scope

The policy is consulted for every inbound history-sync notification that reaches handle_history_sync, except in two cases:
  • The client is shutting down (the notification is dropped without consulting the policy or sending a receipt).
  • skip_history_sync is enabled (the client sends a hist_sync receipt and never calls the policy).
A RejectAndAcknowledge decision:
  • Sends a hist_sync receipt so the phone considers the chunk delivered and stops re-uploading it.
  • Does not enqueue the notification onto the major-sync worker.
  • Does not emit Event::HistorySync.
The receipt is permanent from the phone’s perspective. RejectAndAcknowledge is not a way to shed load and get the chunk back later — the phone will not offer it again. If you need transient load shedding, do it inside Accept by throttling downstream work, not by rejecting.

Types

HistorySyncMetadata and HistorySyncDecision are #[non_exhaustive] — new fields or variants may appear in future releases. Match with a wildcard arm on HistorySyncDecision and treat missing metadata fields as unknown rather than empty. HistorySyncAdmission is object-safe and WASM-safe (MaybeSendSync is Send + Sync on native targets, unbounded on wasm32). It is re-exported from the crate root alongside HistorySyncMetadata and HistorySyncDecision. decide runs inline on the receive path and is deliberately synchronous. A slow or awaiting policy would stall history-sync intake. Keep it to a fast local decision (a comparison, an atomic counter, a bitmask over sync_type); do no I/O or blocking inside it.

Metadata fields

Opting in

Register the policy on the builder before the client connects. Both Bot::builder() and ClientBuilder expose the same method.
If you already hold the policy behind an Arc, use with_history_sync_admission_arc to avoid re-boxing:
The policy is fixed at build time. Live tuning belongs inside the policy itself (atomics, a shared config handle), not in re-registration.

Example: cap chunk size

Drop any chunk whose sender-declared file size exceeds a threshold, and accept everything else.
Because file_length is sender-declared and not validated, this is a best-effort gate. A chunk whose actual payload exceeds the declared size will still be admitted if the declared value is under the cap; use the standard memory-report counters to observe realised cost.

Precedence

Two related settings take precedence over the admission policy:
  1. Shutdown. During shutdown the notification is dropped silently, without a receipt and without consulting the policy.
  2. skip_history_sync. When on, the client sends a hist_sync receipt and skips the policy. Change the toggle at runtime with Client::set_skip_history_sync.
The require_full_sync and history_sync_config fields set at pairing time are independent of this hook. They shape what the phone offers; the admission policy shapes what the client accepts once the phone offers it.

See also