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}