The Mex feature wraps WhatsApp’s Meta Exchange (MEX) GraphQL API. Operations are persisted: you reference each query or mutation by a (name, id) pair pulled from a generated operation module, and pass its typed Variables. WhatsApp Web bundle updates rotate the numeric id, so the human-readable name keeps diagnostics stable across releases.
Access
Building a request
Each persisted operation lives in its own module under wacore::iq::mex_operations. Every module exposes:
NAME — the operation name (e.g. "WAWebJoinNewsletterMutation").
DOC_ID — the current persisted document ID.
OPERATION_KIND — "query" or "mutation".
Variables — a typed struct matching the operation’s input shape.
Response — a typed struct matching the operation’s output shape.
Construct a MexRequest with MexRequest::new using those constants and a Variables value:
use wacore::iq::mex_operations::fetch_newsletter;
use whatsapp_rust::features::mex::MexRequest;
let request = MexRequest::new(
fetch_newsletter::NAME,
fetch_newsletter::DOC_ID,
fetch_newsletter::Variables {
input: Some(fetch_newsletter::Input {
key: Some(jid.to_string()),
r#type: Some("JID".into()),
view_role: Some("GUEST".into()),
}),
fetch_viewer_metadata: Some(true),
fetch_full_image: Some(true),
fetch_creation_time: Some(true),
},
);
let response = client.mex().query(request).await?;
For operations whose Variables schema is too permissive to model exactly, pass any serde::Serialize value (for example a serde_json::json!({...})) as the variables — query and mutate are generic over V: Serialize.
Methods
query
Execute a GraphQL query.
pub async fn query<V: Serialize>(
&self,
request: MexRequest<V>,
) -> Result<MexResponse, MexError>
mutate
Execute a GraphQL mutation.
pub async fn mutate<V: Serialize>(
&self,
request: MexRequest<V>,
) -> Result<MexResponse, MexError>
Example — mutation with typed variables:
use wacore::iq::mex_operations::join_newsletter;
use whatsapp_rust::features::mex::MexRequest;
let request = MexRequest::new(
join_newsletter::NAME,
join_newsletter::DOC_ID,
join_newsletter::Variables {
newsletter_id: Some(jid.to_string()),
},
);
let response = client.mex().mutate(request).await?;
Example — loosely-typed variables with serde_json:
use serde_json::json;
use wacore::iq::mex::MexDoc;
use whatsapp_rust::features::mex::MexRequest;
let request = MexRequest {
doc: MexDoc {
name: "WAWebUpdateGroupPropertyMutation",
id: "8014515568645029",
},
variables: json!({
"group_id": group_jid.to_string(),
"property": "announcement",
"value": true,
}),
};
let response = client.mex().mutate(request).await?;
Types
MexDoc
A persisted-query descriptor. Re-exported from wacore::iq::mex.
pub struct MexDoc {
/// Human-readable operation name (stable across bundle releases).
pub name: &'static str,
/// Numeric persisted-query ID (rotates with bundle releases).
pub id: &'static str,
}
MexRequest
A persisted-query descriptor plus its typed variables. V is the variables type — usually the generated Variables struct for an operation, but any Serialize value works.
pub struct MexRequest<V> {
pub doc: MexDoc,
pub variables: V,
}
new
Pair an operation’s NAME and DOC_ID with its variables.
pub fn new(
name: &'static str,
id: &'static str,
variables: V,
) -> MexRequest<V>
MexResponse
Response from a GraphQL operation.
pub struct MexResponse {
/// Response data (if successful).
pub data: Option<serde_json::Value>,
/// List of errors (if any).
pub errors: Option<Vec<MexGraphQLError>>,
}
Methods:
has_data() — true if the response contains data.
has_errors() — true if the response contains errors.
fatal_error() — the first fatal error (any error with an error_code), if any.
MexGraphQLError
pub struct MexGraphQLError {
pub message: String,
pub extensions: Option<MexErrorExtensions>,
}
Methods:
error_code() — the numeric error code, if present.
is_summary() — true when the error is marked as a summary.
has_error_code() — true when an error code is set.
MexErrorExtensions
pub struct MexErrorExtensions {
pub error_code: Option<i32>,
pub is_summary: Option<bool>,
pub is_retryable: Option<bool>,
pub severity: Option<String>,
}
Error handling
pub enum MexError {
/// Payload missing or malformed with only a descriptive message.
PayloadParsing(String),
/// Payload contained an invalid JID.
InvalidJid(JidError),
/// GraphQL error with a numeric code surfaced as a typed error.
ExtensionError { code: i32, message: String },
/// Underlying IQ request failed.
Request(IqError),
/// JSON serialization or deserialization error.
Json(serde_json::Error),
}
query and mutate automatically convert any fatal GraphQL error (any error with an error_code) into MexError::ExtensionError so you can match on it without inspecting response.errors yourself.
use whatsapp_rust::features::mex::MexError;
match client.mex().query(request).await {
Ok(response) => {
if response.has_data() {
println!("Success: {:?}", response.data);
}
}
Err(MexError::ExtensionError { code, message }) => {
eprintln!("MEX error {}: {}", code, message);
}
Err(e) => eprintln!("Request failed: {}", e),
}
Response handling
Check for data
let response = client.mex().query(request).await?;
if response.has_data() {
let data = response.data.unwrap();
// Process data
}
Handle non-fatal errors
Errors without an error_code are non-fatal and surface in response.errors alongside any partial data.
let response = client.mex().query(request).await?;
if response.has_errors() {
for error in response.errors.as_ref().unwrap() {
if !error.is_summary() && !error.has_error_code() {
eprintln!("Warning: {}", error.message);
}
}
}
Decode the typed response
Generated operation modules also expose a Response struct that mirrors the GraphQL schema. Decode it from response.data with serde_json:
use wacore::iq::mex_operations::fetch_newsletter;
let response = client.mex().query(request).await?;
if let Some(data) = response.data {
let decoded: fetch_newsletter::Response = serde_json::from_value(data)?;
if let Some(newsletter) = decoded.xwa2_newsletter {
println!("Newsletter: {:?}", newsletter);
}
}
The persisted DOC_ID for each operation is regenerated from the latest WhatsApp Web bundle. Pin to a specific crate version if you need a stable wire format.