mod.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 tokio_xmpp::{
 8    parsers::{
 9        message::{Message, MessageType},
10        muc::user::MucUser,
11        ns,
12    },
13    Jid,
14};
15
16use crate::{pubsub, Agent, Event};
17
18pub async fn handle_message(agent: &mut Agent, message: Message) -> Vec<Event> {
19    let mut events = vec![];
20    let from = message.from.clone().unwrap();
21    let langs: Vec<&str> = agent.lang.iter().map(String::as_str).collect();
22    match message.get_best_body(langs) {
23        Some((_lang, body)) => match message.type_ {
24            MessageType::Groupchat => {
25                let event = match from.clone() {
26                    Jid::Full(full) => Event::RoomMessage(
27                        message.id.clone(),
28                        from.to_bare(),
29                        full.resource_str().to_owned(),
30                        body.clone(),
31                    ),
32                    Jid::Bare(bare) => {
33                        Event::ServiceMessage(message.id.clone(), bare, body.clone())
34                    }
35                };
36                events.push(event)
37            }
38            MessageType::Chat | MessageType::Normal => {
39                let mut found_special_message = false;
40
41                for payload in &message.payloads {
42                    if let Ok(_) = MucUser::try_from(payload.clone()) {
43                        let event = match from.clone() {
44                            Jid::Bare(bare) => {
45                                // TODO: Can a service message be of type Chat/Normal and not Groupchat?
46                                warn!("Received misformed MessageType::Chat in muc#user namespace from a bare JID.");
47                                Event::ServiceMessage(message.id.clone(), bare, body.clone())
48                            }
49                            Jid::Full(full) => Event::RoomPrivateMessage(
50                                message.id.clone(),
51                                full.to_bare(),
52                                full.resource_str().to_owned(),
53                                body.clone(),
54                            ),
55                        };
56
57                        found_special_message = true;
58                        events.push(event);
59                    }
60                }
61
62                if !found_special_message {
63                    let event =
64                        Event::ChatMessage(message.id.clone(), from.to_bare(), body.clone());
65                    events.push(event)
66                }
67            }
68            _ => (),
69        },
70        None => (),
71    }
72    for child in message.payloads {
73        if child.is("event", ns::PUBSUB_EVENT) {
74            let new_events = pubsub::handle_event(&from, child, agent).await;
75            events.extend(new_events);
76        }
77    }
78
79    events
80}