xmpp/message/receive/
group_chat.rs

1// Copyright (c) 2023 xmpp-rs contributors.
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use crate::{
8    Agent, Event, RoomNick,
9    delay::StanzaTimeInfo,
10    jid::Jid,
11    parsers::{message::Message, message_correct::Replace},
12};
13
14pub async fn handle_message_group_chat(
15    agent: &mut Agent,
16    events: &mut Vec<Event>,
17    from: Jid,
18    message: &mut Message,
19    time_info: StanzaTimeInfo,
20) {
21    let config = agent.get_config().await;
22    let langs: Vec<&str> = config.lang.iter().map(String::as_str).collect();
23    let mut found_subject = false;
24
25    if let Some((_lang, subject)) = message.get_best_subject(langs.clone()) {
26        events.push(Event::RoomSubject(
27            from.to_bare(),
28            from.resource().map(RoomNick::from_resource_ref),
29            subject.clone(),
30            time_info.clone(),
31        ));
32        found_subject = true;
33    }
34
35    let Some((_lang, body)) = message.get_best_body_cloned(langs) else {
36        if !found_subject {
37            debug!(
38                "Received groupchat message without body/subject:\n{:#?}",
39                message
40            );
41        }
42        return;
43    };
44
45    let correction = message.extract_payload::<Replace>().unwrap_or_else(|e| {
46        warn!("Failed to parse <replace> payload: {e}");
47        None
48    });
49
50    // Now we have a groupchat message... which can be:
51    //
52    // - a normal MUC message from a user in a room
53    // - a MUC message correction from a user in a room
54    // - a service message from a MUC channel (barejid)
55    //
56    // In theory we can have service message correction but nope nope nope
57
58    if let Some(resource) = from.resource() {
59        // User message/correction
60
61        let event = if let Some(correction) = correction {
62            Event::RoomMessageCorrection(
63                correction.id,
64                from.to_bare(),
65                RoomNick::from_resource_ref(resource),
66                body.clone(),
67                time_info,
68            )
69        } else {
70            Event::RoomMessage(
71                message.id.clone(),
72                from.to_bare(),
73                RoomNick::from_resource_ref(resource),
74                body.clone(),
75                time_info,
76            )
77        };
78        events.push(event);
79    } else {
80        // Service message
81        if correction.is_some() {
82            warn!("Found correction in service message:\n{:#?}", message);
83        } else {
84            let event = Event::ServiceMessage(message.id.clone(), from.to_bare(), body, time_info);
85            events.push(event);
86        }
87    }
88}