1use crate::client::Client;
2use wacore::client::context::GroupInfo;
3use wacore_binary::builder::NodeBuilder;
4use wacore_binary::jid::Jid;
5
6impl Client {
7 pub async fn query_group_info(&self, jid: &Jid) -> Result<GroupInfo, anyhow::Error> {
8 if let Some(cached) = self.group_cache.get(jid) {
9 return Ok(cached.value().clone());
10 }
11
12 use wacore_binary::node::NodeContent;
13 let query_node = NodeBuilder::new("query")
14 .attr("request", "interactive")
15 .build();
16 let iq = crate::request::InfoQuery {
17 namespace: "w:g2",
18 query_type: crate::request::InfoQueryType::Get,
19 to: jid.clone(),
20 content: Some(NodeContent::Nodes(vec![query_node])),
21 id: None,
22 target: None,
23 timeout: None,
24 };
25
26 let resp_node = self.send_iq(iq).await?;
27
28 let group_node = resp_node
29 .get_optional_child("group")
30 .ok_or_else(|| anyhow::anyhow!("<group> not found in group info response"))?;
31
32 let mut participants = Vec::new();
33 let mut lid_to_pn_map = std::collections::HashMap::new();
34
35 let addressing_mode_str = group_node
36 .attrs()
37 .optional_string("addressing_mode")
38 .unwrap_or("pn");
39 let addressing_mode = match addressing_mode_str {
40 "lid" => crate::types::message::AddressingMode::Lid,
41 _ => crate::types::message::AddressingMode::Pn,
42 };
43
44 for participant_node in group_node.get_children_by_tag("participant") {
45 let participant_jid = participant_node.attrs().jid("jid");
46 participants.push(participant_jid.clone());
47
48 if addressing_mode == crate::types::message::AddressingMode::Lid
50 && let Some(phone_number) = participant_node.attrs().optional_jid("phone_number")
51 {
52 lid_to_pn_map.insert(participant_jid.user.clone(), phone_number);
54 }
55 }
56
57 let mut info = GroupInfo::new(participants, addressing_mode);
58 if !lid_to_pn_map.is_empty() {
59 info.set_lid_to_pn_map(lid_to_pn_map);
60 }
61 self.group_cache.insert(jid.clone(), info.clone());
62
63 Ok(info)
64 }
65}