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