xmpp: Add Agent::send_raw_message

xmppftw created

Change summary

xmpp/ChangeLog           |  1 
xmpp/src/agent.rs        |  4 ++
xmpp/src/message/send.rs | 60 +++++++++++++++++++++++++++++++++++++++--
3 files changed, 62 insertions(+), 3 deletions(-)

Detailed changes

xmpp/ChangeLog 🔗

@@ -15,6 +15,7 @@ XXXX-YY-ZZ [ RELEASER <admin@localhost> ]
       - Agent::send_room_private_message now takes RoomPrivateMessageSettings (!487)
     * Added:
       - Agent::send_room_message takes RoomMessageSettings argument (!483)
+      - Agent::send_raw_message takes RawMessageSettings for any message type (!487)
     * Fixes:
       - Use tokio::sync::RwLock not std::sync::RwLock (!432)
       - Agent::wait_for_events now return Vec<Event> and sets inner tokio_xmpp Client

xmpp/src/agent.rs 🔗

@@ -49,6 +49,10 @@ impl Agent {
         muc::room::leave_room(self, settings).await
     }
 
+    pub async fn send_raw_message<'a>(&mut self, settings: message::send::RawMessageSettings<'a>) {
+        message::send::send_raw_message(self, settings).await
+    }
+
     pub async fn send_message<'a>(&mut self, settings: message::send::MessageSettings<'a>) {
         message::send::send_message(self, settings).await
     }

xmpp/src/message/send.rs 🔗

@@ -4,13 +4,67 @@
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-use tokio_xmpp::{
-    jid::BareJid,
-    parsers::message::{Body, Message, MessageType},
+use crate::{
+    minidom::Element,
+    parsers::message::{Body, Message, MessagePayload, MessageType},
+    tokio_xmpp::jid::{BareJid, Jid},
 };
 
 use crate::Agent;
 
+#[derive(Clone, Debug)]
+pub struct RawMessageSettings<'a> {
+    pub recipient: Jid,
+    pub message_type: MessageType,
+    pub message: &'a str,
+    pub lang: Option<&'a str>,
+    pub payloads: Vec<Element>,
+}
+
+impl<'a> RawMessageSettings<'a> {
+    pub fn new(recipient: Jid, message_type: MessageType, message: &'a str) -> Self {
+        Self {
+            recipient,
+            message_type,
+            message,
+            lang: None,
+            payloads: Vec::new(),
+        }
+    }
+
+    pub fn with_lang(mut self, lang: &'a str) -> Self {
+        self.lang = Some(lang);
+        self
+    }
+
+    pub fn with_payload(mut self, payload: impl MessagePayload) -> Self {
+        self.payloads.push(payload.into());
+        self
+    }
+}
+
+pub async fn send_raw_message<'a>(agent: &mut Agent, settings: RawMessageSettings<'a>) {
+    let RawMessageSettings {
+        recipient,
+        message_type,
+        message,
+        lang,
+        payloads,
+    } = settings;
+
+    let mut stanza = Message::new(Some(recipient));
+
+    for payload in payloads {
+        stanza.payloads.push(payload);
+    }
+
+    stanza.type_ = message_type;
+    stanza
+        .bodies
+        .insert(lang.unwrap_or("").to_string(), Body(String::from(message)));
+    agent.client.send_stanza(stanza.into()).await.unwrap();
+}
+
 #[derive(Clone, Debug)]
 pub struct MessageSettings<'a> {
     pub recipient: BareJid,