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 for a specific group.
pub async fn get_metadata(&self, jid: &Jid) -> Result<GroupMetadata, anyhow::Error>
Parameters:
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:
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 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_invite_link
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:
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_member_link_mode
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:
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:
| Method | Description |
|---|
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) -> Jid | Convert 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),
}