1#![allow(deprecated)]
3
4use super::attachment::Attachment;
5use crate::{
6 application::command::CommandOptionChoice,
7 channel::message::{AllowedMentions, Component, Embed, MessageFlags},
8 poll::Poll,
9};
10use serde::{Deserialize, Serialize};
11use serde_repr::{Deserialize_repr, Serialize_repr};
12
13#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
19pub struct InteractionResponse {
20 #[serde(rename = "type")]
22 pub kind: InteractionResponseType,
23 #[serde(skip_serializing_if = "Option::is_none")]
36 pub data: Option<InteractionResponseData>,
37}
38
39#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
41pub struct InteractionResponseData {
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub allowed_mentions: Option<AllowedMentions>,
45 #[serde(skip_serializing_if = "Option::is_none")]
47 pub attachments: Option<Vec<Attachment>>,
48 #[serde(skip_serializing_if = "Option::is_none")]
53 pub choices: Option<Vec<CommandOptionChoice>>,
54 #[serde(default, skip_serializing_if = "Option::is_none")]
56 pub components: Option<Vec<Component>>,
57 #[serde(skip_serializing_if = "Option::is_none")]
59 pub content: Option<String>,
60 #[serde(skip_serializing_if = "Option::is_none")]
62 pub custom_id: Option<String>,
63 #[serde(default, skip_serializing_if = "Option::is_none")]
65 pub embeds: Option<Vec<Embed>>,
66 #[serde(skip_serializing_if = "Option::is_none")]
71 pub flags: Option<MessageFlags>,
72 #[serde(skip_serializing_if = "Option::is_none")]
74 pub title: Option<String>,
75 #[serde(skip_serializing_if = "Option::is_none")]
77 pub tts: Option<bool>,
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub poll: Option<Poll>,
81}
82
83#[derive(Clone, Copy, Debug, Deserialize_repr, Eq, Hash, PartialEq, Serialize_repr)]
85#[non_exhaustive]
86#[repr(u8)]
87pub enum InteractionResponseType {
88 Pong = 1,
90 ChannelMessageWithSource = 4,
92 DeferredChannelMessageWithSource = 5,
95 DeferredUpdateMessage = 6,
100 UpdateMessage = 7,
104 ApplicationCommandAutocompleteResult = 8,
106 Modal = 9,
108 #[deprecated(note = "Deprecated by Discord in favor of Premium Buttons")]
115 PremiumRequired = 10,
116}
117
118#[cfg(test)]
119mod tests {
120 use crate::{
121 channel::message::MessageFlags,
122 http::{
123 attachment::Attachment,
124 interaction::{InteractionResponse, InteractionResponseData, InteractionResponseType},
125 },
126 };
127 use serde::{Deserialize, Serialize};
128 use serde_test::Token;
129 use static_assertions::{assert_fields, assert_impl_all};
130 use std::fmt::Debug;
131
132 assert_fields!(
133 InteractionResponseData: allowed_mentions,
134 choices,
135 components,
136 content,
137 embeds,
138 flags,
139 tts
140 );
141 assert_impl_all!(
142 InteractionResponseData: Clone,
143 Debug,
144 Deserialize<'static>,
145 PartialEq,
146 Send,
147 Serialize,
148 Sync
149 );
150
151 #[test]
152 fn interaction_response() {
153 let value = InteractionResponse {
154 kind: InteractionResponseType::ChannelMessageWithSource,
155 data: Some(InteractionResponseData {
156 allowed_mentions: None,
157 attachments: None,
158 choices: None,
159 components: None,
160 content: Some("test".into()),
161 custom_id: None,
162 embeds: None,
163 flags: Some(MessageFlags::EPHEMERAL),
164 title: None,
165 tts: None,
166 poll: None,
167 }),
168 };
169
170 serde_test::assert_tokens(
171 &value,
172 &[
173 Token::Struct {
174 name: "InteractionResponse",
175 len: 2,
176 },
177 Token::Str("type"),
178 Token::U8(4),
179 Token::Str("data"),
180 Token::Some,
181 Token::Struct {
182 name: "InteractionResponseData",
183 len: 2,
184 },
185 Token::Str("content"),
186 Token::Some,
187 Token::Str("test"),
188 Token::Str("flags"),
189 Token::Some,
190 Token::U64(64),
191 Token::StructEnd,
192 Token::StructEnd,
193 ],
194 );
195 }
196
197 #[test]
198 fn interaction_response_with_attachments() {
199 let value = InteractionResponse {
200 kind: InteractionResponseType::ChannelMessageWithSource,
201 data: Some(InteractionResponseData {
202 attachments: Some(Vec::from([Attachment {
203 description: None,
204 file: "file data".into(),
205 filename: "filename.jpg".into(),
206 id: 1,
207 }])),
208 ..InteractionResponseData::default()
209 }),
210 };
211
212 serde_test::assert_ser_tokens(
213 &value,
214 &[
215 Token::Struct {
216 name: "InteractionResponse",
217 len: 2,
218 },
219 Token::Str("type"),
220 Token::U8(InteractionResponseType::ChannelMessageWithSource as u8),
221 Token::Str("data"),
222 Token::Some,
223 Token::Struct {
224 name: "InteractionResponseData",
225 len: 1,
226 },
227 Token::Str("attachments"),
228 Token::Some,
229 Token::Seq { len: Some(1) },
230 Token::Struct {
231 name: "Attachment",
232 len: 2,
233 },
234 Token::Str("filename"),
235 Token::Str("filename.jpg"),
236 Token::Str("id"),
237 Token::U64(1),
238 Token::StructEnd,
239 Token::SeqEnd,
240 Token::StructEnd,
241 Token::StructEnd,
242 ],
243 );
244 }
245}