diff --git a/src/builder/create_message.rs b/src/builder/create_message.rs index 315872ad627..3f4bdfdb502 100644 --- a/src/builder/create_message.rs +++ b/src/builder/create_message.rs @@ -71,10 +71,6 @@ pub struct CreateMessage<'a> { enforce_nonce: bool, #[serde(skip_serializing_if = "Option::is_none")] poll: Option>, - - // The following fields are handled separately. - #[serde(skip)] - reactions: Cow<'a, [ReactionType]>, } impl<'a> CreateMessage<'a> { @@ -140,12 +136,6 @@ impl<'a> CreateMessage<'a> { self } - /// Adds a list of reactions to create after the message's sent. - pub fn reactions(mut self, reactions: impl Into>) -> Self { - self.reactions = reactions.into(); - self - } - /// Appends a file to the message. /// /// **Note**: Requires the [Attach Files] permission. @@ -287,12 +277,7 @@ impl<'a> CreateMessage<'a> { /// [Send Messages]: Permissions::SEND_MESSAGES /// [Attach Files]: Permissions::ATTACH_FILES #[cfg(feature = "http")] - pub async fn execute( - mut self, - http: &Http, - channel_id: GenericChannelId, - guild_id: Option, - ) -> Result { + pub async fn execute(mut self, http: &Http, channel_id: GenericChannelId) -> Result { self.check_length()?; let files = self.attachments.new_attachments(); @@ -300,18 +285,6 @@ impl<'a> CreateMessage<'a> { self.allowed_mentions.clone_from(&http.default_allowed_mentions); } - let mut message = http.send_message(channel_id, files, &self).await?; - - for reaction in self.reactions.iter() { - http.create_reaction(channel_id, message.id, reaction).await?; - } - - // HTTP sent Messages don't have guild_id set, so we fill it in ourselves by best effort - if message.guild_id.is_none() { - // If we were called from GuildChannel, we can fill in the GuildId ourselves. - message.guild_id = guild_id; - } - - Ok(message) + http.send_message(channel_id, files, &self).await } } diff --git a/src/http/client.rs b/src/http/client.rs index 62b5990ddd3..503772d395a 100644 --- a/src/http/client.rs +++ b/src/http/client.rs @@ -4381,7 +4381,7 @@ impl Http { pub async fn request(&self, req: Request<'_>) -> Result { let method = req.method.reqwest_method(); let response = if let Some(ratelimiter) = &self.ratelimiter { - ratelimiter.perform(req).await? + ratelimiter.perform(&req).await? } else { let request = req .build( diff --git a/src/http/multipart.rs b/src/http/multipart.rs index 1c6ec6d5c80..1b7c734a286 100644 --- a/src/http/multipart.rs +++ b/src/http/multipart.rs @@ -49,7 +49,8 @@ impl Multipart<'_> { }, MultipartUpload::Attachments(attachment_files) => { for (idx, file) in attachment_files.into_iter().enumerate() { - multipart = multipart.part(format!("files[{idx}]"), file.into_part().await?); + let part = file.into_part().await?; + multipart = multipart.part(format!("files[{idx}]"), part); } }, } diff --git a/src/http/ratelimiting.rs b/src/http/ratelimiting.rs index fd1a8ee77ae..9068c2569c9 100644 --- a/src/http/ratelimiting.rs +++ b/src/http/ratelimiting.rs @@ -171,7 +171,7 @@ impl Ratelimiter { /// /// Only error kind that may be returned is [`Error::Http`]. #[cfg_attr(feature = "tracing_instrument", instrument)] - pub async fn perform(&self, req: Request<'_>) -> Result { + pub async fn perform(&self, req: &Request<'_>) -> Result { loop { // This will block if another thread hit the global ratelimit. drop(self.global.lock().await); @@ -185,7 +185,7 @@ impl Ratelimiter { let ratelimiting_bucket = req.route.ratelimiting_bucket(); let delay_time = { let mut bucket = self.routes.entry(ratelimiting_bucket).or_default(); - bucket.pre_hook(&req, &*self.ratelimit_callback.read()) + bucket.pre_hook(req, &*self.ratelimit_callback.read()) }; if let Some(delay_time) = delay_time { @@ -244,7 +244,7 @@ impl Ratelimiter { { bucket.post_hook( &response, - &req, + req, &*self.ratelimit_callback.read(), self.absolute_ratelimits, ) diff --git a/src/http/request.rs b/src/http/request.rs index 8dbb1af3f8e..6db32cf598e 100644 --- a/src/http/request.rs +++ b/src/http/request.rs @@ -75,6 +75,13 @@ impl<'a> Request<'a> { token: Option<&str>, proxy: Option<&str>, ) -> Result { + // Build the multipart first, as to keep future size small. + let multipart = if let Some(multipart) = self.multipart { + Some(multipart.build_form().await?) + } else { + None + }; + let mut path = self.route.path().into_owned(); if let Some(proxy) = proxy { @@ -100,9 +107,9 @@ impl<'a> Request<'a> { ); } - if let Some(multipart) = self.multipart { + if let Some(multipart) = multipart { // Setting multipart adds the content-length header. - builder = builder.multipart(multipart.build_form().await?); + builder = builder.multipart(multipart); } else if let Some(bytes) = self.body { headers.insert(CONTENT_LENGTH, bytes.len().into()); headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json")); diff --git a/src/model/channel/channel_id.rs b/src/model/channel/channel_id.rs index 0778b27ffa6..eb97be46bb7 100644 --- a/src/model/channel/channel_id.rs +++ b/src/model/channel/channel_id.rs @@ -923,7 +923,7 @@ impl GenericChannelId { /// See [`CreateMessage::execute`] for a list of possible errors, and their corresponding /// reasons. pub async fn send_message(self, http: &Http, builder: CreateMessage<'_>) -> Result { - builder.execute(http, self, None).await + builder.execute(http, self).await } /// Starts typing in the channel for an indefinite period of time. diff --git a/src/model/channel/guild_channel.rs b/src/model/channel/guild_channel.rs index c90bcb0aa2b..bbd6d5d1146 100644 --- a/src/model/channel/guild_channel.rs +++ b/src/model/channel/guild_channel.rs @@ -340,7 +340,9 @@ impl GuildChannel { /// See [`CreateMessage::execute`] for a list of possible errors, and their corresponding /// reasons. pub async fn send_message(&self, http: &Http, builder: CreateMessage<'_>) -> Result { - builder.execute(http, self.id.widen(), Some(self.base.guild_id)).await + let mut message = self.id.widen().send_message(http, builder).await?; + message.guild_id = Some(self.base.guild_id); + Ok(message) } /// Retrieves [`Member`]s from the current channel. diff --git a/src/model/channel/thread.rs b/src/model/channel/thread.rs index 911888f097c..69115c8c096 100644 --- a/src/model/channel/thread.rs +++ b/src/model/channel/thread.rs @@ -210,7 +210,9 @@ impl GuildThread { /// See [`CreateMessage::execute`] for a list of possible errors, and their corresponding /// reasons. pub async fn send_message(&self, http: &Http, builder: CreateMessage<'_>) -> Result { - builder.execute(http, self.id.widen(), Some(self.base.guild_id)).await + let mut message = self.id.widen().send_message(http, builder).await?; + message.guild_id = Some(self.base.guild_id); + Ok(message) } } diff --git a/src/model/user.rs b/src/model/user.rs index dbcb654fdd4..9cb396c6eac 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -618,12 +618,10 @@ impl UserId { cache_http: impl CacheHttp, builder: CreateMessage<'_>, ) -> Result { - self.create_dm_channel(&cache_http) - .await? - .id - .widen() - .send_message(cache_http.http(), builder) - .await + // Do not refactor this to a one liner. The PrivateChannel from `create_dm_channel` + // should be dropped before the `send_message` call to avoid bloating future sizes. + let dm_channel_id = self.create_dm_channel(&cache_http).await?.id; + dm_channel_id.widen().send_message(cache_http.http(), builder).await } /// This is an alias of [`Self::direct_message`].