Skip to main content
Use client.media_reupload() when a media reference has expired. Keep the original MessageRef and the 32-byte media key together. A media key is separate from the secrets used by message add-ons.

Methods

request

Obtain the target from an inbound message or a send result. For stored metadata, validate it with MessageRef::new. Received group and broadcast messages require the original sender. Newsletter references belong to a separate domain and cannot be used here.

request_many

request_many(&[MediaReuploadRequest<'_>]) returns Vec<Result<MediaRetryResult, MediaReuploadError>> in input order, with one result per request. One failure does not discard the other results.
Identical requests share one recovery, both within a batch and across concurrent callers. Identity includes the message ID, normalized target and participant, direction, and media key. Reusing an in-flight ID for a different target or key returns Conflict(MessageId). In a batch, the first occurrence reserves that ID; identical later entries share its result, including duplicates beyond the concurrency window. The batch reserves every input before execution and runs at most 32 distinct operations at once. Duplicate subscribers share a slot. Completed operations free capacity even while an earlier input remains pending; results are placed back into input order. Dropping one caller leaves other subscribers running. Dropping the last subscriber removes the operation and its waiters immediately. Completion, failure, and timeout release the registration too. client.memory_report().await.media_reuploads counts distinct in-flight operations, not their coalesced subscribers.

Protocol flow

  1. Require the local account’s LID. There is no fallback to the local PN.
  2. For a PN chat on a LID-migrated account, use its mapped LID when available. Otherwise retain the supplied chat identity.
  3. Register both the receipt ACK waiter and the media-retry notification waiter before sending the encrypted server-error receipt.
  4. Wait for the matching receipt ACK. Sending through the transport alone does not confirm this step. A server rejection returns Rejected.
  5. Await and decrypt the notification. A notification received during send or ACK processing remains buffered. The encrypted notification must contain the matching stanza ID.
MediaReuploadPhase::SendAndAck has a 30-second budget that includes send_node and ACK waiting. After a successful ACK, MediaReuploadPhase::Notification has its own 30-second budget. An early notification cannot hide a rejected receipt.

Types

MediaReuploadRequest

MediaRetryResult

A successful request returns this result; inspect the variant before retrying the download.

Error handling

MediaReuploadError is non-exhaustive. Match with a fallback arm. Client and internal errors retain their original causes for all subscribers. std::error::Error::source() exposes the underlying typed cause rather than the sharing Arc, so error-chain inspection and downcasting remain available. An invalid encrypted notification is an error, including a missing or mismatched stanza ID. MediaReuploadPhase is also non-exhaustive and is exported from the crate root. Replace AckTimeout with Timeout { phase: MediaReuploadPhase::SendAndAck } and the former unit Timeout with the Notification phase. Cancelled means waiter-channel closure. Dropping your future returns no error and follows the subscriber cleanup rules above. Rejected preserves the complete response, including unknown fields and the raw error code. Missing, nonnumeric, or out-of-range codes produce None. Read response.as_arc() only when you need the original stanza. Debug redacts its contents and opaque client/internal causes; explicit source access and reupload error Display can still expose those causes.