Merge branch 'main' into perpetual/gateway-dev

This commit is contained in:
kozabrada123 2023-06-04 10:18:16 +02:00
commit ca9f7f6c11
3 changed files with 288 additions and 105 deletions

View File

@ -1,113 +1,111 @@
pub mod messages { use http::header::CONTENT_DISPOSITION;
use http::header::CONTENT_DISPOSITION; use http::HeaderMap;
use http::HeaderMap; use reqwest::{multipart, Client};
use reqwest::{multipart, Client}; use serde_json::to_string;
use serde_json::to_string;
use crate::instance::UserMeta; use crate::instance::UserMeta;
use crate::limit::LimitedRequester; use crate::limit::LimitedRequester;
use crate::types::{Message, MessageSendSchema, PartialDiscordFileAttachment}; use crate::types::{Message, MessageSendSchema, PartialDiscordFileAttachment};
impl Message { impl Message {
/** /**
Sends a message to the Spacebar server. Sends a message to the Spacebar server.
# Arguments # Arguments
* `url_api` - The URL of the Spacebar server's API. * `url_api` - The URL of the Spacebar server's API.
* `message` - The [`Message`] that will be sent to the Spacebar server. * `message` - The [`Message`] that will be sent to the Spacebar server.
* `limits_user` - The [`Limits`] of the user. * `limits_user` - The [`Limits`] of the user.
* `limits_instance` - The [`Limits`] of the instance. * `limits_instance` - The [`Limits`] of the instance.
* `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server.
# Errors # Errors
* [`InstanceServerError`] - If the message cannot be sent. * [`InstanceServerError`] - If the message cannot be sent.
*/ */
pub async fn send( pub async fn send(
user: &mut UserMeta, user: &mut UserMeta,
channel_id: String, channel_id: String,
message: &mut MessageSendSchema, message: &mut MessageSendSchema,
files: Option<Vec<PartialDiscordFileAttachment>>, files: Option<Vec<PartialDiscordFileAttachment>>,
) -> Result<reqwest::Response, crate::errors::InstanceServerError> { ) -> Result<reqwest::Response, crate::errors::InstanceServerError> {
let mut belongs_to = user.belongs_to.borrow_mut(); let mut belongs_to = user.belongs_to.borrow_mut();
let url_api = belongs_to.urls.get_api(); let url_api = belongs_to.urls.get_api();
let mut requester = LimitedRequester::new().await; let mut requester = LimitedRequester::new().await;
if files.is_none() { if files.is_none() {
let message_request = Client::new() let message_request = Client::new()
.post(format!("{}/channels/{}/messages/", url_api, channel_id)) .post(format!("{}/channels/{}/messages/", url_api, channel_id))
.bearer_auth(user.token()) .bearer_auth(user.token())
.body(to_string(message).unwrap()); .body(to_string(message).unwrap());
requester requester
.send_request( .send_request(
message_request, message_request,
crate::api::limits::LimitType::Channel, crate::api::limits::LimitType::Channel,
&mut belongs_to.limits, &mut belongs_to.limits,
&mut user.limits, &mut user.limits,
) )
.await .await
} else { } else {
for (index, attachment) in message.attachments.iter_mut().enumerate() { for (index, attachment) in message.attachments.iter_mut().enumerate() {
attachment.get_mut(index).unwrap().set_id(index as i16); attachment.get_mut(index).unwrap().set_id(index as i16);
}
let mut form = reqwest::multipart::Form::new();
let payload_json = to_string(message).unwrap();
let payload_field = reqwest::multipart::Part::text(payload_json);
form = form.part("payload_json", payload_field);
for (index, attachment) in files.unwrap().into_iter().enumerate() {
let (attachment_content, current_attachment) = attachment.move_content();
let (attachment_filename, _) = current_attachment.move_filename();
let part_name = format!("files[{}]", index);
let content_disposition = format!(
"form-data; name=\"{}\"'; filename=\"{}\"",
part_name, &attachment_filename
);
let mut header_map = HeaderMap::new();
header_map.insert(CONTENT_DISPOSITION, content_disposition.parse().unwrap());
let part = multipart::Part::bytes(attachment_content)
.file_name(attachment_filename)
.headers(header_map);
form = form.part(part_name, part);
}
let message_request = Client::new()
.post(format!("{}/channels/{}/messages/", url_api, channel_id))
.bearer_auth(user.token())
.multipart(form);
requester
.send_request(
message_request,
crate::api::limits::LimitType::Channel,
&mut belongs_to.limits,
&mut user.limits,
)
.await
} }
} let mut form = reqwest::multipart::Form::new();
} let payload_json = to_string(message).unwrap();
let payload_field = reqwest::multipart::Part::text(payload_json);
impl UserMeta { form = form.part("payload_json", payload_field);
/// Shorthand call for Message::send()
/** for (index, attachment) in files.unwrap().into_iter().enumerate() {
Sends a message to the Spacebar server. let (attachment_content, current_attachment) = attachment.move_content();
# Arguments let (attachment_filename, _) = current_attachment.move_filename();
* `url_api` - The URL of the Spacebar server's API. let part_name = format!("files[{}]", index);
* `message` - The [`Message`] that will be sent to the Spacebar server. let content_disposition = format!(
* `limits_user` - The [`Limits`] of the user. "form-data; name=\"{}\"'; filename=\"{}\"",
* `limits_instance` - The [`Limits`] of the instance. part_name, &attachment_filename
* `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. );
# Errors let mut header_map = HeaderMap::new();
* [`InstanceServerError`] - If the message cannot be sent. header_map.insert(CONTENT_DISPOSITION, content_disposition.parse().unwrap());
*/
pub async fn send_message( let part = multipart::Part::bytes(attachment_content)
&mut self, .file_name(attachment_filename)
message: &mut MessageSendSchema, .headers(header_map);
channel_id: String,
files: Option<Vec<PartialDiscordFileAttachment>>, form = form.part(part_name, part);
) -> Result<reqwest::Response, crate::errors::InstanceServerError> { }
Message::send(self, channel_id, message, files).await
let message_request = Client::new()
.post(format!("{}/channels/{}/messages/", url_api, channel_id))
.bearer_auth(user.token())
.multipart(form);
requester
.send_request(
message_request,
crate::api::limits::LimitType::Channel,
&mut belongs_to.limits,
&mut user.limits,
)
.await
} }
} }
} }
impl UserMeta {
/// Shorthand call for Message::send()
/**
Sends a message to the Spacebar server.
# Arguments
* `url_api` - The URL of the Spacebar server's API.
* `message` - The [`Message`] that will be sent to the Spacebar server.
* `limits_user` - The [`Limits`] of the user.
* `limits_instance` - The [`Limits`] of the instance.
* `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server.
# Errors
* [`InstanceServerError`] - If the message cannot be sent.
*/
pub async fn send_message(
&mut self,
message: &mut MessageSendSchema,
channel_id: String,
files: Option<Vec<PartialDiscordFileAttachment>>,
) -> Result<reqwest::Response, crate::errors::InstanceServerError> {
Message::send(self, channel_id, message, files).await
}
}

View File

@ -1,5 +1,7 @@
pub mod channels; pub mod channels;
pub mod messages; pub mod messages;
pub mod reactions;
pub use channels::*; pub use channels::*;
pub use messages::*; pub use messages::*;
pub use reactions::*;

View File

@ -0,0 +1,183 @@
use reqwest::Client;
use crate::{
instance::UserMeta,
limit::LimitedRequester,
types::{self, Snowflake},
};
/**
Extends the [`types::Reaction`] struct with useful metadata.
*/
pub struct ReactionMeta {
pub message_id: types::Snowflake,
pub channel_id: types::Snowflake,
pub reaction: types::Reaction,
}
impl ReactionMeta {
/**
Deletes all reactions for a message.
# Arguments
* `user` - A mutable reference to a [`UserMeta`] instance.
# Returns
A `Result` containing a [`reqwest::Response`] or a [`crate::errors::InstanceServerError`].
# Reference
See [https://discord.com/developers/docs/resources/channel#delete-all-reactions](https://discord.com/developers/docs/resources/channel#delete-all-reactions)
*/
pub async fn delete_all(
&self,
user: &mut UserMeta,
) -> Result<reqwest::Response, crate::errors::InstanceServerError> {
let mut belongs_to = user.belongs_to.borrow_mut();
let url = format!(
"{}/channels/{}/messages/{}/reactions/",
belongs_to.urls.get_api(),
self.channel_id,
self.message_id
);
let request = Client::new().delete(url).bearer_auth(user.token());
LimitedRequester::new()
.await
.send_request(
request,
crate::api::limits::LimitType::Channel,
&mut belongs_to.limits,
&mut user.limits,
)
.await
}
/**
Gets a list of users that reacted with a specific emoji to a message.
# Arguments
* `emoji` - A string slice containing the emoji to search for. The emoji must be URL Encoded or
the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the
format name:id with the emoji name and emoji id.
* `user` - A mutable reference to a [`UserMeta`] instance.
# Returns
A `Result` containing a [`reqwest::Response`] or a [`crate::errors::InstanceServerError`].
# Reference
See [https://discord.com/developers/docs/resources/channel#get-reactions](https://discord.com/developers/docs/resources/channel#get-reactions)
*/
pub async fn get(
&self,
emoji: &str,
user: &mut UserMeta,
) -> Result<reqwest::Response, crate::errors::InstanceServerError> {
let mut belongs_to = user.belongs_to.borrow_mut();
let url = format!(
"{}/channels/{}/messages/{}/reactions/{}/",
belongs_to.urls.get_api(),
self.channel_id,
self.message_id,
emoji
);
let request = Client::new().get(url).bearer_auth(user.token());
LimitedRequester::new()
.await
.send_request(
request,
crate::api::limits::LimitType::Channel,
&mut belongs_to.limits,
&mut user.limits,
)
.await
}
/**
Deletes all the reactions for a given `emoji` on a message. This endpoint requires the
MANAGE_MESSAGES permission to be present on the current user. Fires a `Message Reaction
Remove Emoji` Gateway event.
# Arguments
* `emoji` - A string slice containing the emoji to delete. The `emoji` must be URL Encoded or
the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the
format name:id with the emoji name and emoji id.
* `user` - A mutable reference to a [`UserMeta`] instance.
# Returns
A `Result` containing a [`reqwest::Response`] or a [`crate::errors::InstanceServerError`].
# Reference
See [https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji](https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji)
*/
pub async fn delete_emoji(
&self,
emoji: &str,
user: &mut UserMeta,
) -> Result<reqwest::Response, crate::errors::InstanceServerError> {
let mut belongs_to = user.belongs_to.borrow_mut();
let url = format!(
"{}/channels/{}/messages/{}/reactions/{}/",
belongs_to.urls.get_api(),
self.channel_id,
self.message_id,
emoji
);
let request = Client::new().delete(url).bearer_auth(user.token());
LimitedRequester::new()
.await
.send_request(
request,
crate::api::limits::LimitType::Channel,
&mut belongs_to.limits,
&mut user.limits,
)
.await
}
}
impl types::Reaction {
/**
Create a reaction for the message.
This endpoint requires the READ_MESSAGE_HISTORY permission
to be present on the current user. Additionally, if nobody else has reacted to the message using
this emoji, this endpoint requires the ADD_REACTIONS permission to be present on the current
user. Fires a Message Reaction Add Gateway event.
# Arguments
* `emoji` - A string slice containing the emoji to delete. The `emoji` must be URL Encoded or
the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the
format name:id with the emoji name and emoji id.
* `user` - A mutable reference to a [`UserMeta`] instance.
# Returns
A `Result` containing a [`reqwest::Response`] or a [`crate::errors::InstanceServerError`].
Returns a 204 empty response on success.
# Reference
See [https://discord.com/developers/docs/resources/channel#create-reaction](https://discord.com/developers/docs/resources/channel#create-reaction)
*/
pub async fn create(
channel_id: &Snowflake,
message_id: &Snowflake,
emoji: &str,
user: &mut UserMeta,
) -> Result<reqwest::Response, crate::errors::InstanceServerError> {
let mut belongs_to = user.belongs_to.borrow_mut();
let url = format!(
"{}/channels/{}/messages/{}/reactions/{}/@me/",
belongs_to.urls.get_api(),
channel_id,
message_id,
emoji
);
let request = Client::new().put(url).bearer_auth(user.token());
LimitedRequester::new()
.await
.send_request(
request,
crate::api::limits::LimitType::Channel,
&mut belongs_to.limits,
&mut user.limits,
)
.await
}
}