Skip to main content
The Groups struct provides methods for managing WhatsApp groups, including creating groups, managing participants, and modifying group settings.

Access

Access group operations through the client:
let groups = client.groups();

Methods

query_info

Query group information with caching support.
pub async fn query_info(&self, jid: &Jid) -> Result<GroupInfo, anyhow::Error>
Parameters:
  • jid - Group JID (must end with @g.us)
Returns:
  • GroupInfo - Contains participants list and addressing mode
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let info = client.groups().query_info(&group_jid).await?;

println!("Participants: {}", info.participants.len());
println!("Addressing mode: {:?}", info.addressing_mode);

get_participating

Get all groups the client is participating in.
pub async fn get_participating(&self) -> Result<HashMap<String, GroupMetadata>, anyhow::Error>
Returns:
  • HashMap<String, GroupMetadata> - Map of group JID strings to metadata
GroupMetadata implements PartialEq and Eq, allowing direct comparison of group metadata instances. GroupMetadata fields:
  • id: Jid - Group JID
  • subject: String - Group name
  • participants: Vec<GroupParticipant> - List of participants
  • addressing_mode: AddressingMode - Phone number or LID mode
  • creator: Option<Jid> - Group creator JID
  • creation_time: Option<u64> - Group creation timestamp (Unix seconds)
  • subject_time: Option<u64> - Subject modification timestamp (Unix seconds)
  • subject_owner: Option<Jid> - Subject owner JID
  • description: Option<String> - Group description body text
  • description_id: Option<String> - Description ID (for conflict detection)
  • description_owner: Option<Jid> - JID of the participant who set the description
  • description_time: Option<u64> - Timestamp when the description was set (Unix seconds)
  • is_locked: bool - Whether only admins can edit group info
  • is_announcement: bool - Whether only admins can send messages
  • ephemeral_expiration: u32 - Disappearing messages timer in seconds (0 = disabled)
  • ephemeral_trigger: Option<u32> - Disappearing mode trigger value (from the trigger attribute on <ephemeral>)
  • membership_approval: bool - Whether admin approval is required to join
  • member_add_mode: Option<MemberAddMode> - Who can add members
  • member_link_mode: Option<MemberLinkMode> - Who can use invite links
  • size: Option<u32> - Total participant count
  • is_parent_group: bool - Whether this group is a community parent group
  • parent_group_jid: Option<Jid> - JID of the parent community (for subgroups)
  • is_default_sub_group: bool - Whether this is the default announcement subgroup of a community
  • is_general_chat: bool - Whether this is the general chat subgroup of a community
  • allow_non_admin_sub_group_creation: bool - Whether non-admin community members can create subgroups
  • no_frequently_forwarded: bool - Whether frequently-forwarded messages are restricted
  • member_share_history_mode: Option<MemberShareHistoryMode> - Who can share message history with new members
  • growth_locked: Option<GrowthLockInfo> - Growth lock status (invite links temporarily disabled by the system)
  • is_suspended: bool - Whether the group is suspended
  • allow_admin_reports: bool - Whether admin reports are allowed
  • is_hidden_group: bool - Whether the group is hidden
  • is_incognito: bool - Whether incognito mode is enabled
  • has_group_history: bool - Whether group history is enabled
  • is_limit_sharing_enabled: bool - Whether limit sharing is enabled
See Community API for community-specific operations. GroupParticipant implements PartialEq and Eq. GroupParticipant fields:
  • jid: Jid - Participant JID
  • phone_number: Option<Jid> - Phone number JID (for LID groups)
  • participant_type: ParticipantType - Participant role (member, admin, or super admin)
Example:
let groups = client.groups().get_participating().await?;

for (jid_str, metadata) in groups {
    println!("Group: {} ({})", metadata.subject, jid_str);
    println!("  Participants: {}", metadata.participants.len());
    
    for participant in &metadata.participants {
        println!("    {} ({:?})", participant.jid, participant.participant_type);
    }
}

get_metadata

Get metadata for a specific group.
pub async fn get_metadata(&self, jid: &Jid) -> Result<GroupMetadata, anyhow::Error>
Parameters:
  • jid - Group JID
Returns:
  • GroupMetadata - Group metadata (see get_participating for fields)
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let metadata = client.groups().get_metadata(&group_jid).await?;

println!("Subject: {}", metadata.subject);
println!("Mode: {:?}", metadata.addressing_mode);

create_group

Create a new group.
pub async fn create_group(
    &self,
    options: GroupCreateOptions,
) -> Result<CreateGroupResult, anyhow::Error>
Parameters:
  • options: GroupCreateOptions - Group creation options
    • subject: String - Group name (max 100 characters)
    • participants: Vec<GroupParticipantOptions> - Initial participants
    • member_link_mode: Option<MemberLinkMode> - Who can use invite links (default: AdminLink)
    • member_add_mode: Option<MemberAddMode> - Who can add members (default: AllMemberAdd)
    • membership_approval_mode: Option<MembershipApprovalMode> - Require admin approval (default: Off)
    • ephemeral_expiration: Option<u32> - Disappearing messages timer in seconds (default: 0)
    • is_parent: bool - Create as a community parent group (default: false)
    • closed: bool - Whether the community requires approval to join. Only used when is_parent is true (default: false)
    • allow_non_admin_sub_group_creation: bool - Allow non-admin members to create subgroups. Only used when is_parent is true (default: false)
    • create_general_chat: bool - Create a general chat subgroup alongside the community. Only used when is_parent is true (default: false)
Returns:
  • CreateGroupResult with gid: Jid field.
When the PRIVACY_TOKEN_ON_GROUP_CREATE AB prop is enabled, the library automatically resolves and attaches privacy tokens (tc_token) to each participant during group creation. This is handled internally — you don’t need to manage tokens yourself. Example:
use whatsapp_rust::features::groups::{GroupCreateOptions, GroupParticipantOptions};

let participant1: Jid = "15551234567@s.whatsapp.net".parse()?;
let participant2: Jid = "15559876543@s.whatsapp.net".parse()?;

let options = GroupCreateOptions::builder()
    .subject("My New Group")
    .participants(vec![
        GroupParticipantOptions::new(participant1),
        GroupParticipantOptions::new(participant2),
    ])
    .build();

let result = client.groups().create_group(options).await?;
println!("Created group: {}", result.gid);

set_subject

Change the group name.
pub async fn set_subject(&self, jid: &Jid, subject: GroupSubject) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • subject - New group name (max 100 characters)
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let new_subject = GroupSubject::new("Updated Group Name")?;

client.groups().set_subject(&group_jid, new_subject).await?;

set_description

Set or delete the group description.
pub async fn set_description(
    &self,
    jid: &Jid,
    description: Option<GroupDescription>,
    prev: Option<String>,
) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • description - New description (max 2048 characters) or None to delete
  • prev - Current description ID for conflict detection (pass None if unknown)
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let desc = GroupDescription::new("This is our group chat")?;

client.groups().set_description(&group_jid, Some(desc), None).await?;

// Delete description
client.groups().set_description(&group_jid, None, None).await?;

leave

Leave a group.
pub async fn leave(&self, jid: &Jid) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID to leave
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
client.groups().leave(&group_jid).await?;

add_participants

Add participants to a group.
pub async fn add_participants(
    &self,
    jid: &Jid,
    participants: &[Jid],
) -> Result<Vec<ParticipantChangeResponse>, anyhow::Error>
Parameters:
  • jid - Group JID
  • participants - Array of participant JIDs to add
Returns:
  • Vec<ParticipantChangeResponse> - Result for each participant
When the PRIVACY_TOKEN_ON_GROUP_PARTICIPANT_ADD AB prop is enabled, the library automatically resolves and attaches privacy tokens (tc_token) to each participant. This is handled internally — you don’t need to manage tokens yourself. Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let new_members = vec![
    "15551234567@s.whatsapp.net".parse()?,
    "15559876543@s.whatsapp.net".parse()?,
];

let results = client.groups().add_participants(&group_jid, &new_members).await?;

for result in results {
    println!("Added: {:?}", result);
}

remove_participants

Remove participants from a group.
pub async fn remove_participants(
    &self,
    jid: &Jid,
    participants: &[Jid],
) -> Result<Vec<ParticipantChangeResponse>, anyhow::Error>
Parameters:
  • jid - Group JID
  • participants - Array of participant JIDs to remove
Returns:
  • Vec<ParticipantChangeResponse> - Result for each participant
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let to_remove = vec!["15551234567@s.whatsapp.net".parse()?];

client.groups().remove_participants(&group_jid, &to_remove).await?;

promote_participants

Promote participants to admin.
pub async fn promote_participants(
    &self,
    jid: &Jid,
    participants: &[Jid],
) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • participants - Array of participant JIDs to promote
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let to_promote = vec!["15551234567@s.whatsapp.net".parse()?];

client.groups().promote_participants(&group_jid, &to_promote).await?;

demote_participants

Demote admin participants to regular members.
pub async fn demote_participants(
    &self,
    jid: &Jid,
    participants: &[Jid],
) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • participants - Array of admin JIDs to demote
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let to_demote = vec!["15551234567@s.whatsapp.net".parse()?];

client.groups().demote_participants(&group_jid, &to_demote).await?;
Get or reset the group invite link.
pub async fn get_invite_link(&self, jid: &Jid, reset: bool) -> Result<String, anyhow::Error>
Parameters:
  • jid - Group JID
  • reset - Whether to reset and generate a new invite link
Returns:
  • String - Invite link code
Example:
let group_jid: Jid = "123456789@g.us".parse()?;

// Get current invite link
let link = client.groups().get_invite_link(&group_jid, false).await?;
println!("Invite link: https://chat.whatsapp.com/{}", link);

// Reset and get new link
let new_link = client.groups().get_invite_link(&group_jid, true).await?;
println!("New invite link: https://chat.whatsapp.com/{}", new_link);

join_with_invite_code

Join a group using an invite code or full invite URL.
pub async fn join_with_invite_code(&self, code: &str) -> Result<JoinGroupResult, anyhow::Error>
Parameters:
  • code - Invite code or full URL (e.g., "AbCdEfGh" or "https://chat.whatsapp.com/AbCdEfGh")
Returns:
  • JoinGroupResult - Either Joined(Jid) if immediately joined, or PendingApproval(Jid) if the group requires admin approval
Example:
use whatsapp_rust::features::groups::JoinGroupResult;

// Join using a full URL or just the code
let result = client.groups().join_with_invite_code("https://chat.whatsapp.com/AbCdEfGh").await?;

match &result {
    JoinGroupResult::Joined(jid) => println!("Joined group: {}", jid),
    JoinGroupResult::PendingApproval(jid) => println!("Pending approval for group: {}", jid),
}

// Access the group JID regardless of result
println!("Group JID: {}", result.group_jid());

join_with_invite_v4

Accept a V4 group invite received as a GroupInviteMessage (not a link). V4 invites are sent directly by a group admin as a message, rather than shared as a URL.
pub async fn join_with_invite_v4(
    &self,
    group_jid: &Jid,
    code: &str,
    expiration: i64,
    admin_jid: &Jid,
) -> Result<JoinGroupResult, anyhow::Error>
Parameters:
  • group_jid - The target group JID
  • code - Invite code from the GroupInviteMessage
  • expiration - Invite expiration timestamp (Unix seconds). The method returns an error if the invite has expired.
  • admin_jid - JID of the admin who sent the invite
Returns:
  • JoinGroupResult - Either Joined(Jid) if immediately joined, or PendingApproval(Jid) if the group requires admin approval
Example:
use whatsapp_rust::features::groups::JoinGroupResult;

let group_jid: Jid = "123456789@g.us".parse()?;
let admin_jid: Jid = "15551234567@s.whatsapp.net".parse()?;

let result = client.groups().join_with_invite_v4(
    &group_jid,
    "AbCdEfGh",
    1735689600,    // expiration timestamp
    &admin_jid,
).await?;

match &result {
    JoinGroupResult::Joined(jid) => println!("Joined group: {}", jid),
    JoinGroupResult::PendingApproval(jid) => println!("Pending approval for group: {}", jid),
}
V4 invites expire. The method automatically checks the expiration timestamp and returns an error if the invite has already expired. You can pass 0 as the expiration to skip the expiration check.

get_invite_info

Get group metadata from an invite code without joining the group.
pub async fn get_invite_info(&self, code: &str) -> Result<GroupMetadata, anyhow::Error>
Parameters:
  • code - Invite code or full URL
Returns:
  • GroupMetadata - Group metadata (see get_participating for fields)
Example:
// Preview a group before joining
let metadata = client.groups().get_invite_info("AbCdEfGh").await?;

println!("Group: {}", metadata.subject);
println!("Participants: {}", metadata.participants.len());
println!("Approval required: {}", metadata.membership_approval);

set_locked

Lock or unlock the group so only admins can change group info.
pub async fn set_locked(&self, jid: &Jid, locked: bool) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • locked - true to lock (only admins edit info), false to unlock
Example:
let group_jid: Jid = "123456789@g.us".parse()?;

// Lock group info
client.groups().set_locked(&group_jid, true).await?;

// Unlock group info
client.groups().set_locked(&group_jid, false).await?;

set_announce

Set announcement mode. When enabled, only admins can send messages.
pub async fn set_announce(&self, jid: &Jid, announce: bool) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • announce - true to enable (only admins send), false to disable
Example:
let group_jid: Jid = "123456789@g.us".parse()?;

// Enable announcement mode
client.groups().set_announce(&group_jid, true).await?;

// Disable announcement mode
client.groups().set_announce(&group_jid, false).await?;

set_ephemeral

Set the disappearing messages timer on the group.
pub async fn set_ephemeral(&self, jid: &Jid, expiration: u32) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • expiration - Timer duration in seconds. Common values: 86400 (24 hours), 604800 (7 days), 7776000 (90 days). Pass 0 to disable.
Example:
let group_jid: Jid = "123456789@g.us".parse()?;

// Enable 7-day disappearing messages
client.groups().set_ephemeral(&group_jid, 604800).await?;

// Disable disappearing messages
client.groups().set_ephemeral(&group_jid, 0).await?;

set_membership_approval

Set membership approval mode. When enabled, new members must be approved by an admin.
pub async fn set_membership_approval(
    &self,
    jid: &Jid,
    mode: MembershipApprovalMode,
) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • mode - MembershipApprovalMode::On to require approval, MembershipApprovalMode::Off to disable
Example:
use whatsapp_rust::features::groups::MembershipApprovalMode;

let group_jid: Jid = "123456789@g.us".parse()?;

// Require admin approval
client.groups().set_membership_approval(&group_jid, MembershipApprovalMode::On).await?;

// Remove approval requirement
client.groups().set_membership_approval(&group_jid, MembershipApprovalMode::Off).await?;

get_membership_requests

Get pending membership approval requests for a group.
pub async fn get_membership_requests(
    &self,
    jid: &Jid,
) -> Result<Vec<MembershipRequest>, anyhow::Error>
Parameters:
  • jid - Group JID
Returns:
  • Vec<MembershipRequest> - List of pending requests
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let requests = client.groups().get_membership_requests(&group_jid).await?;

for request in &requests {
    println!("Pending request from: {}", request.jid);
    if let Some(time) = request.request_time {
        println!("  Requested at: {}", time);
    }
}

approve_membership_requests

Approve pending membership requests for a group.
pub async fn approve_membership_requests(
    &self,
    jid: &Jid,
    participants: &[Jid],
) -> Result<Vec<ParticipantChangeResponse>, anyhow::Error>
Parameters:
  • jid - Group JID
  • participants - Array of JIDs to approve
Returns:
  • Vec<ParticipantChangeResponse> - Result for each participant
Example:
let group_jid: Jid = "123456789@g.us".parse()?;

// Get pending requests
let requests = client.groups().get_membership_requests(&group_jid).await?;
let jids: Vec<Jid> = requests.iter().map(|r| r.jid.clone()).collect();

// Approve all pending requests
let results = client.groups().approve_membership_requests(&group_jid, &jids).await?;

for result in results {
    println!("Approved {}: status {:?}", result.jid, result.status);
}

reject_membership_requests

Reject pending membership requests for a group.
pub async fn reject_membership_requests(
    &self,
    jid: &Jid,
    participants: &[Jid],
) -> Result<Vec<ParticipantChangeResponse>, anyhow::Error>
Parameters:
  • jid - Group JID
  • participants - Array of JIDs to reject
Returns:
  • Vec<ParticipantChangeResponse> - Result for each participant
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let to_reject = vec!["15551234567@s.whatsapp.net".parse()?];

let results = client.groups().reject_membership_requests(&group_jid, &to_reject).await?;

set_member_add_mode

Set who can add members to the group.
pub async fn set_member_add_mode(
    &self,
    jid: &Jid,
    mode: MemberAddMode,
) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • mode - MemberAddMode::AdminAdd to restrict to admins, MemberAddMode::AllMemberAdd to allow all members
Example:
use whatsapp_rust::features::groups::MemberAddMode;

let group_jid: Jid = "123456789@g.us".parse()?;

// Only admins can add members
client.groups().set_member_add_mode(&group_jid, MemberAddMode::AdminAdd).await?;

// All members can add others
client.groups().set_member_add_mode(&group_jid, MemberAddMode::AllMemberAdd).await?;

set_no_frequently_forwarded

Restrict or allow frequently-forwarded messages in the group.
pub async fn set_no_frequently_forwarded(
    &self,
    jid: &Jid,
    restrict: bool,
) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • restrict - true to restrict frequently-forwarded messages, false to allow them
Example:
let group_jid: Jid = "123456789@g.us".parse()?;

// Restrict frequently-forwarded messages
client.groups().set_no_frequently_forwarded(&group_jid, true).await?;

// Allow frequently-forwarded messages
client.groups().set_no_frequently_forwarded(&group_jid, false).await?;

set_allow_admin_reports

Enable or disable admin reports in the group.
pub async fn set_allow_admin_reports(
    &self,
    jid: &Jid,
    allow: bool,
) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • allow - true to enable admin reports, false to disable
Example:
let group_jid: Jid = "123456789@g.us".parse()?;

// Enable admin reports
client.groups().set_allow_admin_reports(&group_jid, true).await?;

// Disable admin reports
client.groups().set_allow_admin_reports(&group_jid, false).await?;

set_group_history

Enable or disable group history sharing.
pub async fn set_group_history(&self, jid: &Jid, enabled: bool) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
  • enabled - true to enable group history, false to disable
Example:
let group_jid: Jid = "123456789@g.us".parse()?;

// Enable group history
client.groups().set_group_history(&group_jid, true).await?;

// Disable group history
client.groups().set_group_history(&group_jid, false).await?;
Set who can share invite links. This uses the MEX (Mutation Exchange) protocol.
pub async fn set_member_link_mode(
    &self,
    jid: &Jid,
    mode: MemberLinkMode,
) -> Result<(), MexError>
Parameters:
  • jid - Group JID
  • mode - MemberLinkMode::AdminLink to restrict to admins, MemberLinkMode::AllMemberLink to allow all members
Example:
use whatsapp_rust::features::groups::MemberLinkMode;

let group_jid: Jid = "123456789@g.us".parse()?;

// Only admins can share invite links
client.groups().set_member_link_mode(&group_jid, MemberLinkMode::AdminLink).await?;

// All members can share invite links
client.groups().set_member_link_mode(&group_jid, MemberLinkMode::AllMemberLink).await?;
This method uses the MEX protocol and returns MexError instead of anyhow::Error. See the MEX API for details on MEX errors.

set_member_share_history_mode

Set who can share message history with new members. This uses the MEX protocol.
pub async fn set_member_share_history_mode(
    &self,
    jid: &Jid,
    mode: MemberShareHistoryMode,
) -> Result<(), MexError>
Parameters:
  • jid - Group JID
  • mode - MemberShareHistoryMode::AdminShare to restrict to admins, MemberShareHistoryMode::AllMemberShare to allow all members
Example:
use whatsapp_rust::features::groups::MemberShareHistoryMode;

let group_jid: Jid = "123456789@g.us".parse()?;

// Only admins can share history with new members
client.groups().set_member_share_history_mode(
    &group_jid,
    MemberShareHistoryMode::AdminShare,
).await?;

// All members can share history
client.groups().set_member_share_history_mode(
    &group_jid,
    MemberShareHistoryMode::AllMemberShare,
).await?;

set_limit_sharing

Enable or disable limit sharing in the group. This uses the MEX protocol.
pub async fn set_limit_sharing(&self, jid: &Jid, enabled: bool) -> Result<(), MexError>
Parameters:
  • jid - Group JID
  • enabled - true to enable limit sharing, false to disable
Example:
let group_jid: Jid = "123456789@g.us".parse()?;

// Enable limit sharing
client.groups().set_limit_sharing(&group_jid, true).await?;

// Disable limit sharing
client.groups().set_limit_sharing(&group_jid, false).await?;

cancel_membership_requests

Cancel pending membership requests from the requesting user’s side.
pub async fn cancel_membership_requests(
    &self,
    jid: &Jid,
    participants: &[Jid],
) -> Result<Vec<ParticipantChangeResponse>, anyhow::Error>
Parameters:
  • jid - Group JID
  • participants - Array of JIDs whose pending requests to cancel
Returns:
  • Vec<ParticipantChangeResponse> - Result for each participant
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let to_cancel = vec!["15551234567@s.whatsapp.net".parse()?];

let results = client.groups().cancel_membership_requests(&group_jid, &to_cancel).await?;

revoke_request_code

Revoke invitation codes from specific participants. This is an admin operation.
pub async fn revoke_request_code(
    &self,
    jid: &Jid,
    participants: &[Jid],
) -> Result<Vec<ParticipantChangeResponse>, anyhow::Error>
Parameters:
  • jid - Group JID
  • participants - Array of participant JIDs whose invitation codes to revoke
Returns:
  • Vec<ParticipantChangeResponse> - Result for each participant
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
let to_revoke = vec!["15551234567@s.whatsapp.net".parse()?];

let results = client.groups().revoke_request_code(&group_jid, &to_revoke).await?;

acknowledge

Acknowledge a group notification.
pub async fn acknowledge(&self, jid: &Jid) -> Result<(), anyhow::Error>
Parameters:
  • jid - Group JID
Example:
let group_jid: Jid = "123456789@g.us".parse()?;
client.groups().acknowledge(&group_jid).await?;

batch_get_info

Batch query group info for multiple groups at once.
pub async fn batch_get_info(
    &self,
    jids: Vec<Jid>,
) -> Result<Vec<BatchGroupResult>, anyhow::Error>
Parameters:
  • jids - List of group JIDs to query (max 10,000)
Returns:
  • Vec<BatchGroupResult> - Result for each group
Example:
use whatsapp_rust::features::groups::BatchGroupResult;

let group_jids: Vec<Jid> = vec![
    "120363012345678@g.us".parse()?,
    "120363087654321@g.us".parse()?,
];

let results = client.groups().batch_get_info(group_jids).await?;

for result in results {
    match result {
        BatchGroupResult::Full(metadata) => {
            println!("Group: {} - {}", metadata.id, metadata.subject);
        }
        BatchGroupResult::Truncated { id, size } => {
            println!("Truncated: {} (size: {:?})", id, size);
        }
        BatchGroupResult::Forbidden(id) => {
            println!("Forbidden: {}", id);
        }
        BatchGroupResult::NotFound(id) => {
            println!("Not found: {}", id);
        }
    }
}

get_profile_pictures

Batch fetch group profile pictures.
pub async fn get_profile_pictures(
    &self,
    group_jids: Vec<Jid>,
    picture_type: PictureType,
) -> Result<Vec<GroupProfilePicture>, anyhow::Error>
Parameters:
  • group_jids - List of group JIDs (max 1,000)
  • picture_type - PictureType::Preview for thumbnails or PictureType::Image for full-size
Returns:
  • Vec<GroupProfilePicture> - Profile picture data for each group
Example:
use whatsapp_rust::features::groups::{PictureType, GroupProfilePicture};

let group_jids: Vec<Jid> = vec![
    "120363012345678@g.us".parse()?,
    "120363087654321@g.us".parse()?,
];

let pictures = client.groups().get_profile_pictures(group_jids, PictureType::Preview).await?;

for pic in pictures {
    if let Some(url) = &pic.url {
        println!("Group {}: {}", pic.group_jid, url);
    }
}

Types

GroupInfo

Cached group information returned by query_info. Contains participant list, addressing mode, and LID-to-phone mappings for privacy-addressed groups.
pub struct GroupInfo {
    pub participants: Vec<Jid>,
    pub addressing_mode: AddressingMode,
}
Methods:
MethodDescription
lid_to_pn_map() -> &HashMap<String, Jid>Access the LID-to-phone number mapping
phone_jid_for_lid_user(lid_user: &str) -> Option<&Jid>Look up the phone JID for a LID user
lid_jid_for_phone_user(phone_user: &str) -> Option<&Jid>Look up the LID JID for a phone number
phone_device_jid_to_lid(phone_device_jid: &Jid) -> JidConvert a phone-based device JID to LID format
Example:
let info = client.groups().query_info(&group_jid).await?;

// Access participants and addressing mode
for participant in &info.participants {
    println!("Participant: {}", participant);
}

// For LID-addressed groups, resolve phone numbers
if info.addressing_mode == AddressingMode::Lid {
    if let Some(phone_jid) = info.phone_jid_for_lid_user("lid_user_id") {
        println!("Phone: {}", phone_jid);
    }
}

GroupSubject

Validated group name with 100 character limit.
impl GroupSubject {
    pub fn new(subject: impl Into<String>) -> Result<Self, anyhow::Error>
    pub fn into_string(self) -> String
}

GroupDescription

Validated group description with 2048 character limit.
impl GroupDescription {
    pub fn new(description: impl Into<String>) -> Result<Self, anyhow::Error>
    pub fn into_string(self) -> String
}

MemberAddMode

pub enum MemberAddMode {
    AdminAdd,      // Only admins can add members
    AllMemberAdd,  // All members can add
}

ParticipantType

Participant role within a group.
pub enum ParticipantType {
    Member,     // Regular member
    Admin,      // Group admin
    SuperAdmin, // Group creator / super admin
}
Methods:
  • is_admin(&self) -> bool - Returns true if admin or super admin

MemberLinkMode

Controls who can use invite links to join the group.
pub enum MemberLinkMode {
    AdminLink,      // Only admins can share invite links
    AllMemberLink,  // All members can share invite links
}

MemberShareHistoryMode

Controls who can share message history with new members.
pub enum MemberShareHistoryMode {
    AdminShare,      // Only admins can share history
    AllMemberShare,  // All members can share history
}

MembershipApprovalMode

pub enum MembershipApprovalMode {
    Off,  // No approval required
    On,   // Admin approval required
}

GroupParticipantOptions

Options for specifying a participant when creating or modifying a group.
pub struct GroupParticipantOptions {
    pub jid: Jid,
    pub phone_number: Option<Jid>,
    pub privacy: Option<Vec<u8>>,
}
Constructors:
  • GroupParticipantOptions::new(jid) - Create from a JID
  • GroupParticipantOptions::from_phone(phone_number) - Create from a phone number JID
  • GroupParticipantOptions::from_lid_and_phone(lid, phone_number) - Create from a LID and phone number
Builder methods:
  • .with_phone_number(jid) - Attach a phone number JID (for LID participants)
  • .with_privacy(token) - Attach a privacy token (tc_token bytes)
You typically don’t need to set the privacy field manually. When AB props are enabled, the library automatically resolves and attaches privacy tokens during create_group and add_participants operations.
Example:
use whatsapp_rust::features::groups::GroupParticipantOptions;

let participant = GroupParticipantOptions::new("15551234567@s.whatsapp.net".parse()?);

JoinGroupResult

Result of joining a group via invite code.
pub enum JoinGroupResult {
    Joined(Jid),          // Successfully joined
    PendingApproval(Jid), // Membership approval required
}
Methods:
  • group_jid(&self) -> &Jid - Returns the group JID regardless of result variant

MembershipRequest

A pending membership approval request.
pub struct MembershipRequest {
    pub jid: Jid,
    pub request_time: Option<u64>,
}

ParticipantChangeResponse

Result of a participant change operation (add, remove, approve, reject).
pub struct ParticipantChangeResponse {
    pub jid: Jid,
    pub status: Option<String>,
    pub error: Option<String>,
}

AddressingMode

pub enum AddressingMode {
    Pn,   // Phone number addressing
    Lid,  // LID (privacy) addressing
}

BatchGroupResult

Result for a single group in a batch query.
pub enum BatchGroupResult {
    Full(Box<GroupMetadata>),           // Full group metadata
    Truncated { id: Jid, size: Option<u32> },  // Only ID and size returned
    Forbidden(Jid),                     // Access denied
    NotFound(Jid),                      // Group does not exist
}

GrowthLockInfo

Growth lock information (system-managed, read-only). When present, invite links are temporarily disabled by the system.
pub struct GrowthLockInfo {
    pub lock_type: String,
    pub expiration: u64,
}

PictureType

Profile picture query type for batch fetching.
pub enum PictureType {
    Preview,  // Thumbnail / preview size
    Image,    // Full-size image
}

GroupProfilePicture

A single group profile picture result from a batch query.
pub struct GroupProfilePicture {
    pub group_jid: Jid,
    pub url: Option<String>,
    pub direct_path: Option<String>,
    pub photo_id: Option<String>,
}

CreateGroupResult

Result of creating a group.
pub struct CreateGroupResult {
    pub gid: Jid,
}

GroupJoinError

Error codes returned when joining a group via invite fails.
pub enum GroupJoinError {
    AlreadyMember,       // 304 - Already a member of the group
    BadRequest,          // 400 - Invalid request
    Forbidden,           // 403 - Not allowed to join
    NotFound,            // 404 - Group not found
    NotAllowed,          // 405 - Join method not allowed
    Conflict,            // 409 - Conflicting state
    Gone,                // 410 - Group no longer exists
    CommunityFull,       // 412 - Community has reached capacity
    GroupFull,           // 419 - Group has reached capacity
    Locked,              // 423 - Group is locked
    Unknown(u16),        // Other error code
}
Methods:
  • from_code(code: u16) -> Self - Create from a numeric status code
  • code(&self) -> u16 - Get the numeric status code

InviteInfoError

Error codes returned when fetching group info from an invite code.
pub enum InviteInfoError {
    BadRequest,            // 400 - Invalid request
    NotAuthorized,         // 401 - Not authorized
    NotFound,              // 404 - Invite code not found
    NotAcceptable,         // 406 - Not acceptable
    Gone,                  // 410 - Invite code expired
    ParentGroupSuspended,  // 416 - Parent community is suspended
    Locked,                // 423 - Group is locked
    GrowthLocked,          // 436 - Group growth is temporarily locked
    Unknown(u16),          // Other error code
}
Methods:
  • from_code(code: u16) -> Self - Create from a numeric status code
  • code(&self) -> u16 - Get the numeric status code

Error handling

All methods return Result<T, anyhow::Error>. Common errors:
  • Invalid JID format
  • Network errors
  • Permission denied (not admin)
  • Group not found
  • Subject/description too long
  • Participant not found
match client.groups().set_subject(&group_jid, subject).await {
    Ok(_) => println!("Subject updated"),
    Err(e) => eprintln!("Failed to update subject: {}", e),
}