> ## Documentation Index
> Fetch the complete documentation index at: https://whatsapp-rust.jlucaso.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Community

> Community operations — create, deactivate, and manage community subgroups

The `Community` feature provides methods for managing WhatsApp communities, including creation, subgroup linking/unlinking, and metadata queries. Community mutations use IQ stanzas (`w:g2` namespace) while metadata queries use MEX (GraphQL).

## Access

Access community operations through the client:

```rust theme={null}
let community = client.community();
```

## Methods

### create

Create a new community.

```rust theme={null}
pub async fn create(
    &self,
    options: CreateCommunityOptions,
) -> Result<CreateCommunityResult, CommunityError>
```

**Parameters:**

* `options` — Community creation options (see [CreateCommunityOptions](#createcommunityoptions))

**Returns:**

* `CreateCommunityResult` — Contains the full `metadata: GroupMetadata` for the created community parent group

**Example:**

```rust theme={null}
use whatsapp_rust::features::community::CreateCommunityOptions;

let mut options = CreateCommunityOptions::new("My Community");
options.description = Some("A great community".to_string());
options.closed = true;

let result = client.community().create(options).await?;
println!("Created community: {} ({})", result.metadata.subject, result.metadata.id);
if let Some(desc) = &result.metadata.description {
    println!("Description: {}", desc);
}
```

<Note>
  Since v0.6, `community().create()` returns the full `GroupMetadata` instead of just the JID. The library inlines the community description directly into the create stanza (matching WA Web), so the returned metadata already contains it — no separate `set_description` round-trip is needed. If you previously read `result.gid`, switch to `result.metadata.id` (`GroupMetadata` uses `id: Jid`).
</Note>

### get\_participating

Fetch all parent/community groups the logged-in account currently participates in.

```rust theme={null}
pub async fn get_participating(&self) -> Result<HashMap<Jid, GroupMetadata>, CommunityError>
```

**Returns:**

* `HashMap<Jid, GroupMetadata>` — Map of community JID to metadata

**Example:**

```rust theme={null}
let communities = client.community().get_participating().await?;

for (jid, metadata) in communities {
    println!("Community: {} ({})", metadata.subject, jid);
}
```

### deactivate

Deactivate (delete) a community. Subgroups are unlinked but not deleted.

```rust theme={null}
pub async fn deactivate(&self, community_jid: &Jid) -> Result<(), CommunityError>
```

**Parameters:**

* `community_jid` — JID of the community to deactivate

**Example:**

```rust theme={null}
client.community().deactivate(&community_jid).await?;
```

### link\_subgroups

Link existing groups as subgroups of a community.

```rust theme={null}
pub async fn link_subgroups(
    &self,
    community_jid: &Jid,
    subgroup_jids: &[Jid],
) -> Result<LinkSubgroupsResult, CommunityError>
```

**Parameters:**

* `community_jid` — JID of the parent community
* `subgroup_jids` — Array of group JIDs to link

**Returns:**

* `LinkSubgroupsResult` — Contains `linked_jids` (successfully linked) and `failed_groups` (JID + error code pairs)

**Example:**

```rust theme={null}
let subgroup_jids = vec![
    "120363001111111@g.us".parse()?,
    "120363002222222@g.us".parse()?,
];

let result = client.community()
    .link_subgroups(&community_jid, &subgroup_jids)
    .await?;

println!("Linked: {:?}", result.linked_jids);
for (jid, error_code) in &result.failed_groups {
    eprintln!("Failed: {} (error {})", jid, error_code);
}
```

### create\_subgroup

Create a new group that is already linked as a subgroup of a community, in one call.

```rust theme={null}
pub async fn create_subgroup(
    &self,
    name: &str,
    participants: &[Jid],
    parent_jid: &Jid,
) -> Result<CreateCommunityResult, CommunityError>
```

**Parameters:**

* `name` — Name of the new subgroup
* `participants` — Initial participant JIDs to add to the subgroup
* `parent_jid` — JID of the parent community to link the new subgroup under

**Returns:**

* `CreateCommunityResult` — Contains the full `metadata: GroupMetadata` for the created subgroup

**Example:**

```rust theme={null}
let participants = vec![
    "5511999999999@s.whatsapp.net".parse()?,
];

let result = client.community()
    .create_subgroup("My Subgroup", &participants, &community_jid)
    .await?;

println!("Created subgroup: {} ({})", result.metadata.subject, result.metadata.id);
```

<Note>
  Equivalent to creating a group and then calling [`link_subgroups`](#link_subgroups), but done in a single round-trip.
</Note>

### unlink\_subgroups

Unlink subgroups from a community.

```rust theme={null}
pub async fn unlink_subgroups(
    &self,
    community_jid: &Jid,
    subgroup_jids: &[Jid],
    remove_orphan_members: bool,
) -> Result<UnlinkSubgroupsResult, CommunityError>
```

**Parameters:**

* `community_jid` — JID of the parent community
* `subgroup_jids` — Array of subgroup JIDs to unlink
* `remove_orphan_members` — Whether to remove members who are only in the community through the unlinked subgroups

**Returns:**

* `UnlinkSubgroupsResult` — Contains `unlinked_jids` (successfully unlinked) and `failed_groups` (JID + error code pairs)

**Example:**

```rust theme={null}
let result = client.community()
    .unlink_subgroups(&community_jid, &subgroup_jids, true)
    .await?;

println!("Unlinked: {:?}", result.unlinked_jids);
```

### get\_subgroups

Fetch all subgroups of a community via MEX (GraphQL).

```rust theme={null}
pub async fn get_subgroups(
    &self,
    community_jid: &Jid,
) -> Result<Vec<CommunitySubgroup>, CommunityError>
```

**Parameters:**

* `community_jid` — JID of the community

**Returns:**

* `Vec<CommunitySubgroup>` — List of subgroups with metadata

**Example:**

```rust theme={null}
let subgroups = client.community()
    .get_subgroups(&community_jid)
    .await?;

for sg in &subgroups {
    println!("{}: {} (default: {}, general: {})",
        sg.id, sg.subject, sg.is_default_sub_group, sg.is_general_chat);
}
```

### get\_subgroup\_participant\_counts

Fetch participant counts per subgroup via MEX (GraphQL).

```rust theme={null}
pub async fn get_subgroup_participant_counts(
    &self,
    community_jid: &Jid,
) -> Result<Vec<(Jid, u32)>, CommunityError>
```

**Parameters:**

* `community_jid` — JID of the community

**Returns:**

* `Vec<(Jid, u32)>` — Pairs of subgroup JID and participant count

**Example:**

```rust theme={null}
let counts = client.community()
    .get_subgroup_participant_counts(&community_jid)
    .await?;

for (jid, count) in &counts {
    println!("{}: {} participants", jid, count);
}
```

### query\_linked\_group

Query a linked subgroup's metadata from the parent community.

```rust theme={null}
pub async fn query_linked_group(
    &self,
    community_jid: &Jid,
    subgroup_jid: &Jid,
) -> Result<GroupMetadata, CommunityError>
```

**Parameters:**

* `community_jid` — JID of the parent community
* `subgroup_jid` — JID of the subgroup to query

**Returns:**

* `GroupMetadata` — Full group metadata (see [Groups API](/api/groups#get_metadata))

**Example:**

```rust theme={null}
let metadata = client.community()
    .query_linked_group(&community_jid, &subgroup_jid)
    .await?;

println!("Subject: {}", metadata.subject);
```

### join\_subgroup

Join a linked subgroup via the parent community.

```rust theme={null}
pub async fn join_subgroup(
    &self,
    community_jid: &Jid,
    subgroup_jid: &Jid,
) -> Result<GroupMetadata, CommunityError>
```

**Parameters:**

* `community_jid` — JID of the parent community
* `subgroup_jid` — JID of the subgroup to join

**Returns:**

* `GroupMetadata` — Metadata of the joined subgroup

**Example:**

```rust theme={null}
let metadata = client.community()
    .join_subgroup(&community_jid, &subgroup_jid)
    .await?;

println!("Joined: {}", metadata.subject);
```

### get\_linked\_groups\_participants

Get all participants across all linked groups of a community.

```rust theme={null}
pub async fn get_linked_groups_participants(
    &self,
    community_jid: &Jid,
) -> Result<Vec<GroupParticipant>, CommunityError>
```

**Parameters:**

* `community_jid` — JID of the community

**Returns:**

* `Vec<GroupParticipant>` — List of participants across all subgroups

**Example:**

```rust theme={null}
let participants = client.community()
    .get_linked_groups_participants(&community_jid)
    .await?;

for p in &participants {
    println!("{} (admin: {})", p.jid, p.is_admin);
}
```

### remove\_participants

Remove participants from a community.

```rust theme={null}
pub async fn remove_participants(
    &self,
    community_jid: &Jid,
    participants: &[Jid],
) -> Result<Vec<ParticipantChangeResponse>, CommunityError>
```

**Parameters:**

* `community_jid` — JID of the community
* `participants` — Array of participant JIDs to remove

**Returns:**

* `Vec<ParticipantChangeResponse>` — Result for each participant (see [`ParticipantChangeResponse`](/api/groups#participantchangeresponse))

**Example:**

```rust theme={null}
let to_remove = vec!["15551234567@s.whatsapp.net".parse()?];

let results = client.community()
    .remove_participants(&community_jid, &to_remove)
    .await?;

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

## Types

### CreateCommunityOptions

Options for creating a new community. Implements `PartialEq` and `Eq`.

```rust theme={null}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CreateCommunityOptions {
    pub name: String,
    pub description: Option<String>,
    pub closed: bool,
    pub allow_non_admin_sub_group_creation: bool,
    pub create_general_chat: bool,
}
```

**Fields:**

* `name` — Community name
* `description` — Optional description. Since v0.6 it's inlined as a `<description>` child of the create stanza, so the community is created with the description in a single round-trip (no follow-up `set_description` IQ needed).
* `closed` — Whether the community requires approval to join (default: `false`)
* `allow_non_admin_sub_group_creation` — Whether non-admin members can create subgroups (default: `false`)
* `create_general_chat` — Whether to create a general chat subgroup (default: `true`)

**Constructor:**

```rust theme={null}
let options = CreateCommunityOptions::new("My Community");
```

### CreateCommunityResult

Result of creating a community.

```rust theme={null}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct CreateCommunityResult {
    pub metadata: GroupMetadata,
}
```

The `metadata` field carries the full community parent metadata from the server, with the inline `description: Option<String>` already populated. See [`GroupMetadata`](/api/groups#groupmetadata) for the full field list.

`CreateCommunityResult` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

<Note>
  Prior to v0.6 this struct exposed only `gid: Jid` and derived `PartialEq, Eq`. The `Eq` derives were dropped because `GroupMetadata` does not implement them.
</Note>

### CommunitySubgroup

A subgroup within a community. Implements `PartialEq` and `Eq`.

```rust theme={null}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct CommunitySubgroup {
    pub id: Jid,
    pub subject: String,
    pub participant_count: Option<u32>,
    pub is_default_sub_group: bool,
    pub is_general_chat: bool,
    pub creation: Option<u64>,
    pub owner: Option<Jid>,
}
```

`CommunitySubgroup` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

**Fields:**

* `id` — Subgroup JID
* `subject` — Subgroup name
* `participant_count` — Number of participants (if available)
* `is_default_sub_group` — Whether this is the default announcement subgroup
* `is_general_chat` — Whether this is the general chat subgroup
* `creation` — Subgroup creation timestamp (Unix seconds), if available
* `owner` — JID of the subgroup owner, if available

### LinkSubgroupsResult

Result of linking subgroups to a community. Implements `PartialEq` and `Eq`.

```rust theme={null}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct LinkSubgroupsResult {
    pub linked_jids: Vec<Jid>,
    pub failed_groups: Vec<(Jid, u32)>,
}
```

`LinkSubgroupsResult` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

### UnlinkSubgroupsResult

Result of unlinking subgroups from a community. Implements `PartialEq` and `Eq`.

```rust theme={null}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct UnlinkSubgroupsResult {
    pub unlinked_jids: Vec<Jid>,
    pub failed_groups: Vec<(Jid, u32)>,
}
```

`UnlinkSubgroupsResult` is `#[non_exhaustive]`: struct-literal construction and exhaustive struct destructuring from outside the crate are both disallowed. Field reads are unaffected; add `..` to any exhaustive destructuring patterns.

### GroupType

Classification of a group within the community hierarchy. Implements `PartialEq` and `Eq`.

```rust theme={null}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GroupType {
    Default,
    Community,
    LinkedSubgroup,
    LinkedAnnouncementGroup,
    LinkedGeneralGroup,
}
```

`GroupType` is `#[non_exhaustive]`, so match statements should include a wildcard arm to handle future variants.

**Variants:**

* `Default` — Regular standalone group
* `Community` — Community parent group
* `LinkedSubgroup` — A subgroup linked to a community
* `LinkedAnnouncementGroup` — The default announcement subgroup of a community
* `LinkedGeneralGroup` — The general chat subgroup of a community

Use the `group_type()` function to classify a group:

```rust theme={null}
use whatsapp_rust::features::community::{group_type, GroupType};

let metadata = client.groups().get_metadata(&group_jid).await?;
let gtype = group_type(&metadata);
```

## Error handling

All community methods return `Result<T, CommunityError>`:

```rust theme={null}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum CommunityError {
    #[error("{0}")]
    Iq(#[from] IqError),
    #[error("{0}")]
    Mex(#[from] MexError),
    #[error("{0}")]
    Group(#[from] GroupError),
    #[error("invalid community request: {0}")]
    InvalidRequest(String),
}
```

```rust theme={null}
use whatsapp_rust::CommunityError;

match client.community().deactivate(&community_jid).await {
    Ok(_) => println!("Community deactivated"),
    Err(CommunityError::Iq(e)) => eprintln!("Server error: {}", e),
    Err(CommunityError::Mex(e)) => eprintln!("MEX error: {}", e),
    Err(e) => eprintln!("Error: {}", e),
}
```
