Breaking changes
Typed MEX operationsMexRequest is now generic over its variables type (MexRequest<V>), and the request carries a MexDoc (operation name + persisted document ID) instead of a free-form doc_id: &str. Variables are serialized straight to the wire — there’s no intermediate serde_json::Value step — so callers pass either a typed Variables struct from a generated operation module or any serde::Serialize value.
The generated modules live under wacore::iq::mex_operations and expose NAME, DOC_ID, OPERATION_KIND, Variables, and Response per persisted query. Build a request with MexRequest::new:
Mex::query and Mex::mutate are now generic over V: Serialize, and a new MexError::InvalidJid variant surfaces JID parsing failures from MEX payloads. See MEX (GraphQL) for the full reference.
If you previously built requests with
MexRequest { doc_id, variables }, switch to MexRequest::new(NAME, DOC_ID, variables) using the generated module’s constants — or, for ad-hoc operations, set doc: MexDoc { name, id } directly. Numeric DOC_IDs rotate with WhatsApp Web bundle releases; the stable NAME keeps diagnostics readable across versions.New features
Client::send_reaction helper
Send a reaction to a DM, group, or status@broadcast message in one call. The helper builds the underlying ReactionMessage (including sender_timestamp_ms) and routes the stanza through the standard send path, so retry, fan-out, and phash handling all apply. Pass an empty string to remove a previous reaction. For groups and status, set target_key.participant to the original sender so the receipt can be attributed. See send_reaction.
MessageContext::react shortcut
Inside an event handler, MessageContext::react reacts to the incoming message without manually rebuilding the message key — it fills in chat, message ID, and group/status participant for you.
Newsletter (channel) reactions still go through
client.newsletter().send_reaction() because they use a different plaintext stanza format.client.newsletter(). Both go out as plaintext <message> stanzas (no Signal encryption) and key off the message’s wire message_id — not the server_id used for reactions. See edit_message and revoke_message.
send_message_impl, pin_message, and Client::edit_message / Client::revoke_message now reject newsletter JIDs at the root of the encrypted send path. A mis-routed channel JID surfaces a clear error that names the mis-route instead of producing a malformed encrypted fan-out. Use client.newsletter() for any channel send, edit, or revoke.