serenity/builder/
edit_webhook_message.rs1#[cfg(feature = "http")]
2use super::{check_overflow, Builder};
3use super::{
4 CreateActionRow,
5 CreateAllowedMentions,
6 CreateAttachment,
7 CreateEmbed,
8 EditAttachments,
9};
10#[cfg(feature = "http")]
11use crate::constants;
12#[cfg(feature = "http")]
13use crate::http::CacheHttp;
14#[cfg(feature = "http")]
15use crate::internal::prelude::*;
16use crate::model::prelude::*;
17
18#[derive(Clone, Debug, Default, Serialize)]
22#[must_use]
23pub struct EditWebhookMessage {
24 #[serde(skip_serializing_if = "Option::is_none")]
25 content: Option<String>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 embeds: Option<Vec<CreateEmbed>>,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 allowed_mentions: Option<CreateAllowedMentions>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub(crate) components: Option<Vec<CreateActionRow>>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub(crate) attachments: Option<EditAttachments>,
34
35 #[serde(skip)]
36 thread_id: Option<ChannelId>,
37}
38
39impl EditWebhookMessage {
40 pub fn new() -> Self {
42 Self::default()
43 }
44
45 #[cfg(feature = "http")]
46 pub(crate) fn check_length(&self) -> Result<()> {
47 if let Some(content) = &self.content {
48 check_overflow(content.chars().count(), constants::MESSAGE_CODE_LIMIT)
49 .map_err(|overflow| Error::Model(ModelError::MessageTooLong(overflow)))?;
50 }
51
52 if let Some(embeds) = &self.embeds {
53 check_overflow(embeds.len(), constants::EMBED_MAX_COUNT)
54 .map_err(|_| Error::Model(ModelError::EmbedAmount))?;
55 for embed in embeds {
56 embed.check_length()?;
57 }
58 }
59
60 Ok(())
61 }
62
63 #[inline]
67 pub fn content(mut self, content: impl Into<String>) -> Self {
68 self.content = Some(content.into());
69 self
70 }
71
72 #[inline]
75 pub fn in_thread(mut self, thread_id: impl Into<ChannelId>) -> Self {
76 self.thread_id = Some(thread_id.into());
77 self
78 }
79
80 pub fn add_embed(mut self, embed: CreateEmbed) -> Self {
84 self.embeds.get_or_insert(Vec::new()).push(embed);
85 self
86 }
87
88 pub fn add_embeds(mut self, embeds: Vec<CreateEmbed>) -> Self {
92 self.embeds.get_or_insert(Vec::new()).extend(embeds);
93 self
94 }
95
96 pub fn embed(mut self, embed: CreateEmbed) -> Self {
101 self.embeds = Some(vec![embed]);
102 self
103 }
104
105 pub fn embeds(mut self, embeds: Vec<CreateEmbed>) -> Self {
112 self.embeds = Some(embeds);
113 self
114 }
115
116 pub fn allowed_mentions(mut self, allowed_mentions: CreateAllowedMentions) -> Self {
118 self.allowed_mentions = Some(allowed_mentions);
119 self
120 }
121
122 pub fn components(mut self, components: Vec<CreateActionRow>) -> Self {
129 self.components = Some(components);
130 self
131 }
132 super::button_and_select_menu_convenience_methods!(self.components);
133
134 pub fn attachments(mut self, attachments: EditAttachments) -> Self {
136 self.attachments = Some(attachments);
137 self
138 }
139
140 pub fn new_attachment(mut self, attachment: CreateAttachment) -> Self {
144 let attachments = self.attachments.get_or_insert_with(Default::default);
145 self.attachments = Some(std::mem::take(attachments).add(attachment));
146 self
147 }
148
149 pub fn keep_existing_attachment(mut self, id: AttachmentId) -> Self {
151 let attachments = self.attachments.get_or_insert_with(Default::default);
152 self.attachments = Some(std::mem::take(attachments).keep(id));
153 self
154 }
155
156 pub fn clear_attachments(mut self) -> Self {
158 self.attachments = Some(EditAttachments::new());
159 self
160 }
161}
162
163#[cfg(feature = "http")]
164#[async_trait::async_trait]
165impl Builder for EditWebhookMessage {
166 type Context<'ctx> = (WebhookId, &'ctx str, MessageId);
167 type Built = Message;
168
169 async fn execute(
183 mut self,
184 cache_http: impl CacheHttp,
185 ctx: Self::Context<'_>,
186 ) -> Result<Self::Built> {
187 self.check_length()?;
188
189 let files = self.attachments.as_mut().map_or(Vec::new(), |a| a.take_files());
190
191 let http = cache_http.http();
192 if self.allowed_mentions.is_none() {
193 self.allowed_mentions.clone_from(&http.default_allowed_mentions);
194 }
195
196 http.edit_webhook_message(ctx.0, self.thread_id, ctx.1, ctx.2, &self, files).await
197 }
198}