summary refs log tree commit diff
path: root/src/system/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/system/util.rs')
-rw-r--r--src/system/util.rs113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/system/util.rs b/src/system/util.rs
new file mode 100644
index 0000000..4b51c09
--- /dev/null
+++ b/src/system/util.rs
@@ -0,0 +1,113 @@
+use futures::future::join_all;
+use twilight_http::Client;
+use twilight_model::channel::{message::{AllowedMentions, MentionType, MessageType}, Message};
+use std::sync::Arc;
+use tokio::sync::Mutex;
+use twilight_model::http::attachment::Attachment;
+
+pub enum ProxyError {
+    InvalidMessage(twilight_validate::message::MessageValidationError),
+    AttachmentRequest(reqwest::Error),
+    MessageCreate(twilight_http::error::Error),
+    ResponseDeserialization(twilight_http::response::DeserializeBodyError),
+}
+
+impl From<twilight_validate::message::MessageValidationError> for ProxyError {
+    fn from(value: twilight_validate::message::MessageValidationError) -> Self {
+        ProxyError::InvalidMessage(value)
+    }
+}
+
+impl From<reqwest::Error> for ProxyError{
+    fn from(value: reqwest::Error) -> Self {
+        ProxyError::AttachmentRequest(value)
+    }
+}
+
+impl From<twilight_http::error::Error> for ProxyError{
+    fn from(value: twilight_http::error::Error) -> Self {
+        ProxyError::MessageCreate(value)
+    }
+}
+
+impl From<twilight_http::response::DeserializeBodyError> for ProxyError{
+    fn from(value: twilight_http::response::DeserializeBodyError) -> Self {
+        ProxyError::ResponseDeserialization(value)
+    }
+}
+
+pub async fn duplicate_message(client: &Arc<Mutex<Client>>, message: &Message, content: &str) -> Result<Message, ProxyError> {
+    let client = client.lock().await;
+
+    let mut create_message = client.create_message(message.channel_id).content(content)?;
+
+    let mut allowed_mentions = AllowedMentions {
+        parse: Vec::new(),
+        replied_user: false,
+        roles: message.mention_roles.clone(),
+        users: message.mentions.iter().map(|user| user.id).collect(),
+    };
+
+    if message.mention_everyone {
+        allowed_mentions.parse.push(MentionType::Everyone);
+    }
+
+    if message.kind == MessageType::Reply {
+        if let Some(ref_message) = message.referenced_message.as_ref() {
+            create_message = create_message.reply(ref_message.id);
+
+            let pings_referenced_author = message
+                .mentions
+                .iter()
+                .any(|user| user.id == ref_message.author.id);
+
+            if pings_referenced_author {
+                allowed_mentions.replied_user = true;
+            } else {
+                allowed_mentions.replied_user = false;
+            }
+        } else {
+            panic!("Cannot proxy message: Was reply but no referenced message");
+        }
+    }
+
+    let attachments = join_all(message.attachments.iter().map(|attachment| async {
+        let filename = attachment.filename.clone();
+        let description_opt = attachment.description.clone();
+        let bytes = reqwest::get(attachment.proxy_url.clone())
+            .await?
+            .bytes()
+            .await?;
+        let mut new_attachment =
+            Attachment::from_bytes(filename, bytes.try_into().unwrap(), attachment.id.into());
+
+        if let Some(description) = description_opt {
+            new_attachment.description(description);
+        }
+
+        Ok(new_attachment)
+    }))
+    .await
+    .iter()
+    .filter_map(
+        |result: &Result<Attachment, ProxyError>| match result {
+            Ok(attachment) => Some(attachment.clone()),
+            Err(_) => None,
+        },
+    )
+    .collect::<Vec<_>>();
+
+    if attachments.len() > 0 {
+        create_message = create_message.attachments(attachments.as_slice())?;
+    }
+
+    if let Some(flags) = message.flags {
+        create_message = create_message.flags(flags);
+    }
+
+    create_message = create_message.allowed_mentions(Some(&allowed_mentions));
+    let new_message = create_message.await?.model().await?;
+
+    Ok(new_message)
+}
+