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 flags: Option<MessageFlags>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 allowed_mentions: Option<CreateAllowedMentions>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub(crate) components: Option<Vec<CreateActionRow>>,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub(crate) attachments: Option<EditAttachments>,
36
37 #[serde(skip)]
38 thread_id: Option<ChannelId>,
39}
40
41impl EditWebhookMessage {
42 pub fn new() -> Self {
44 Self::default()
45 }
46
47 #[cfg(feature = "http")]
48 pub(crate) fn check_length(&self) -> Result<()> {
49 if let Some(content) = &self.content {
50 check_overflow(content.chars().count(), constants::MESSAGE_CODE_LIMIT)
51 .map_err(|overflow| Error::Model(ModelError::MessageTooLong(overflow)))?;
52 }
53
54 if let Some(embeds) = &self.embeds {
55 check_overflow(embeds.len(), constants::EMBED_MAX_COUNT)
56 .map_err(|_| Error::Model(ModelError::EmbedAmount))?;
57 for embed in embeds {
58 embed.check_length()?;
59 }
60 }
61
62 Ok(())
63 }
64
65 #[inline]
69 pub fn content(mut self, content: impl Into<String>) -> Self {
70 self.content = Some(content.into());
71 self
72 }
73
74 #[inline]
77 pub fn in_thread(mut self, thread_id: impl Into<ChannelId>) -> Self {
78 self.thread_id = Some(thread_id.into());
79 self
80 }
81
82 pub fn add_embed(mut self, embed: CreateEmbed) -> Self {
86 self.embeds.get_or_insert(Vec::new()).push(embed);
87 self
88 }
89
90 pub fn add_embeds(mut self, embeds: Vec<CreateEmbed>) -> Self {
94 self.embeds.get_or_insert(Vec::new()).extend(embeds);
95 self
96 }
97
98 pub fn embed(mut self, embed: CreateEmbed) -> Self {
103 self.embeds = Some(vec![embed]);
104 self
105 }
106
107 pub fn embeds(mut self, embeds: Vec<CreateEmbed>) -> Self {
114 self.embeds = Some(embeds);
115 self
116 }
117
118 pub fn allowed_mentions(mut self, allowed_mentions: CreateAllowedMentions) -> Self {
120 self.allowed_mentions = Some(allowed_mentions);
121 self
122 }
123
124 pub fn components(mut self, components: Vec<CreateActionRow>) -> Self {
131 self.components = Some(components);
132 self
133 }
134 super::button_and_select_menu_convenience_methods!(self.components);
135
136 pub fn flags(mut self, flags: MessageFlags) -> Self {
138 self.flags = Some(flags);
139 self
140 }
141
142 pub fn attachments(mut self, attachments: EditAttachments) -> Self {
144 self.attachments = Some(attachments);
145 self
146 }
147
148 pub fn new_attachment(mut self, attachment: CreateAttachment) -> Self {
152 let attachments = self.attachments.get_or_insert_with(Default::default);
153 self.attachments = Some(std::mem::take(attachments).add(attachment));
154 self
155 }
156
157 pub fn keep_existing_attachment(mut self, id: AttachmentId) -> Self {
159 let attachments = self.attachments.get_or_insert_with(Default::default);
160 self.attachments = Some(std::mem::take(attachments).keep(id));
161 self
162 }
163
164 pub fn clear_attachments(mut self) -> Self {
166 self.attachments = Some(EditAttachments::new());
167 self
168 }
169}
170
171#[cfg(feature = "http")]
172#[async_trait::async_trait]
173impl Builder for EditWebhookMessage {
174 type Context<'ctx> = (WebhookId, &'ctx str, MessageId);
175 type Built = Message;
176
177 async fn execute(
191 mut self,
192 cache_http: impl CacheHttp,
193 ctx: Self::Context<'_>,
194 ) -> Result<Self::Built> {
195 self.check_length()?;
196
197 let files = self.attachments.as_mut().map_or(Vec::new(), |a| a.take_files());
198
199 let http = cache_http.http();
200 if self.allowed_mentions.is_none() {
201 self.allowed_mentions.clone_from(&http.default_allowed_mentions);
202 }
203
204 http.edit_webhook_message(ctx.0, self.thread_id, ctx.1, ctx.2, &self, files).await
205 }
206}