serenity/builder/
create_interaction_response_followup.rs1use super::create_poll::Ready;
2#[cfg(feature = "http")]
3use super::{check_overflow, Builder};
4use super::{
5 CreateActionRow,
6 CreateAllowedMentions,
7 CreateAttachment,
8 CreateEmbed,
9 CreatePoll,
10 EditAttachments,
11};
12#[cfg(feature = "http")]
13use crate::constants;
14#[cfg(feature = "http")]
15use crate::http::CacheHttp;
16#[cfg(feature = "http")]
17use crate::internal::prelude::*;
18use crate::model::prelude::*;
19
20#[derive(Clone, Debug, Default, Serialize)]
22#[must_use]
23pub struct CreateInteractionResponseFollowup {
24 #[serde(skip_serializing_if = "Option::is_none")]
25 content: Option<String>,
26 #[serde(skip_serializing_if = "Option::is_none")]
29 tts: Option<bool>,
30 embeds: Vec<CreateEmbed>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 allowed_mentions: Option<CreateAllowedMentions>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 components: Option<Vec<CreateActionRow>>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 flags: Option<MessageFlags>,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 poll: Option<CreatePoll<Ready>>,
39 attachments: EditAttachments,
40}
41
42impl CreateInteractionResponseFollowup {
43 pub fn new() -> Self {
45 Self::default()
46 }
47
48 #[cfg(feature = "http")]
49 fn check_length(&self) -> Result<()> {
50 if let Some(content) = &self.content {
51 check_overflow(content.chars().count(), constants::MESSAGE_CODE_LIMIT)
52 .map_err(|overflow| Error::Model(ModelError::MessageTooLong(overflow)))?;
53 }
54
55 check_overflow(self.embeds.len(), constants::EMBED_MAX_COUNT)
56 .map_err(|_| Error::Model(ModelError::EmbedAmount))?;
57 for embed in &self.embeds {
58 embed.check_length()?;
59 }
60
61 Ok(())
62 }
63
64 #[inline]
68 pub fn content(mut self, content: impl Into<String>) -> Self {
69 self.content = Some(content.into());
70 self
71 }
72
73 pub fn tts(mut self, tts: bool) -> Self {
79 self.tts = Some(tts);
80 self
81 }
82
83 pub fn add_file(mut self, file: CreateAttachment) -> Self {
85 self.attachments = self.attachments.add(file);
86 self
87 }
88
89 pub fn add_files(mut self, files: impl IntoIterator<Item = CreateAttachment>) -> Self {
91 for file in files {
92 self.attachments = self.attachments.add(file);
93 }
94 self
95 }
96
97 pub fn files(mut self, files: impl IntoIterator<Item = CreateAttachment>) -> Self {
102 self.attachments = EditAttachments::new();
103 self.add_files(files)
104 }
105
106 pub fn add_embed(mut self, embed: CreateEmbed) -> Self {
108 self.embeds.push(embed);
109 self
110 }
111
112 pub fn add_embeds(mut self, embeds: Vec<CreateEmbed>) -> Self {
114 self.embeds.extend(embeds);
115 self
116 }
117
118 pub fn embed(self, embed: CreateEmbed) -> Self {
123 self.embeds(vec![embed])
124 }
125
126 pub fn embeds(mut self, embeds: Vec<CreateEmbed>) -> Self {
131 self.embeds = embeds;
132 self
133 }
134
135 pub fn allowed_mentions(mut self, allowed_mentions: CreateAllowedMentions) -> Self {
137 self.allowed_mentions = Some(allowed_mentions);
138 self
139 }
140
141 pub fn flags(mut self, flags: MessageFlags) -> Self {
143 self.flags = Some(flags);
144 self
145 }
146
147 pub fn ephemeral(mut self, ephemeral: bool) -> Self {
149 let mut flags = self.flags.unwrap_or_else(MessageFlags::empty);
150
151 if ephemeral {
152 flags |= MessageFlags::EPHEMERAL;
153 } else {
154 flags &= !MessageFlags::EPHEMERAL;
155 };
156
157 self.flags = Some(flags);
158 self
159 }
160
161 pub fn poll(mut self, poll: CreatePoll<Ready>) -> Self {
165 self.poll = Some(poll);
166 self
167 }
168
169 pub fn components(mut self, components: Vec<CreateActionRow>) -> Self {
171 self.components = Some(components);
172 self
173 }
174 super::button_and_select_menu_convenience_methods!(self.components);
175}
176
177#[cfg(feature = "http")]
178#[async_trait::async_trait]
179impl Builder for CreateInteractionResponseFollowup {
180 type Context<'ctx> = (Option<MessageId>, &'ctx str);
181 type Built = Message;
182
183 async fn execute(
195 mut self,
196 cache_http: impl CacheHttp,
197 ctx: Self::Context<'_>,
198 ) -> Result<Self::Built> {
199 self.check_length()?;
200
201 let files = self.attachments.take_files();
202
203 let http = cache_http.http();
204 if self.allowed_mentions.is_none() {
205 self.allowed_mentions.clone_from(&http.default_allowed_mentions);
206 }
207
208 match ctx.0 {
209 Some(id) => http.as_ref().edit_followup_message(ctx.1, id, &self, files).await,
210 None => http.as_ref().create_followup_message(ctx.1, &self, files).await,
211 }
212 }
213}