discord_webhook/
models.rs

1use serde::{Deserialize, Serialize};
2
3type Snowflake = String;
4
5#[derive(Deserialize, Debug)]
6pub struct Webhook {
7    pub id: Snowflake,
8    #[serde(rename = "type")]
9    pub webhook_type: i8,
10    pub guild_id: Snowflake,
11    pub channel_id: Snowflake,
12    pub name: Option<String>,
13    pub avatar: Option<String>,
14    pub token: String,
15    pub application_id: Option<Snowflake>,
16}
17
18#[derive(Serialize, Debug)]
19pub struct Message {
20    pub content: Option<String>,
21    pub username: Option<String>,
22    pub avatar_url: Option<String>,
23    pub tts: bool,
24    pub embeds: Vec<Embed>,
25    pub allow_mentions: Option<AllowedMentions>,
26}
27
28impl Message {
29    pub fn new() -> Self {
30        Self {
31            content: None,
32            username: None,
33            avatar_url: None,
34            tts: false,
35            embeds: vec![],
36            allow_mentions: None,
37        }
38    }
39
40    pub fn content(&mut self, content: &str) -> &mut Self {
41        self.content = Some(content.to_owned());
42        self
43    }
44
45    pub fn username(&mut self, username: &str) -> &mut Self {
46        self.username = Some(username.to_owned());
47        self
48    }
49
50    pub fn avatar_url(&mut self, avatar_url: &str) -> &mut Self {
51        self.avatar_url = Some(avatar_url.to_owned());
52        self
53    }
54
55    pub fn tts(&mut self, tts: bool) -> &mut Self {
56        self.tts = tts;
57        self
58    }
59
60    pub fn embed<Func>(&mut self, func: Func) -> &mut Self
61    where
62        Func: Fn(&mut Embed) -> &mut Embed,
63    {
64        let mut embed = Embed::new();
65        func(&mut embed);
66        self.embeds.push(embed);
67
68        self
69    }
70
71    pub fn allow_mentions(
72        &mut self,
73        parse: Option<Vec<AllowedMention>>,
74        roles: Option<Vec<Snowflake>>,
75        users: Option<Vec<Snowflake>>,
76        replied_user: bool,
77    ) -> &mut Self {
78        self.allow_mentions = Some(AllowedMentions::new(parse, roles, users, replied_user));
79        self
80    }
81}
82
83#[derive(Serialize, Debug)]
84pub struct Embed {
85    pub title: Option<String>,
86    #[serde(rename = "type")]
87    embed_type: String,
88    pub description: Option<String>,
89    pub url: Option<String>,
90    pub timestamp: Option<String>, // ISO8601,
91    pub color: Option<String>,
92    pub footer: Option<EmbedFooter>,
93    pub image: Option<EmbedImage>,
94    pub video: Option<EmbedVideo>,
95    pub thumbnail: Option<EmbedThumbnail>,
96    pub provider: Option<EmbedProvider>,
97    pub author: Option<EmbedAuthor>,
98    pub fields: Vec<EmbedField>,
99}
100
101impl Embed {
102    pub fn new() -> Self {
103        Self {
104            title: None,
105            embed_type: String::from("rich"),
106            description: None,
107            url: None,
108            timestamp: None,
109            color: None,
110            footer: None,
111            image: None,
112            video: None,
113            thumbnail: None,
114            provider: None,
115            author: None,
116            fields: vec![],
117        }
118    }
119
120    pub fn title(&mut self, title: &str) -> &mut Self {
121        self.title = Some(title.to_owned());
122        self
123    }
124
125    pub fn description(&mut self, description: &str) -> &mut Self {
126        self.description = Some(description.to_owned());
127        self
128    }
129
130    pub fn url(&mut self, url: &str) -> &mut Self {
131        self.url = Some(url.to_owned());
132        self
133    }
134
135    pub fn timestamp(&mut self, timestamp: &str) -> &mut Self {
136        self.timestamp = Some(timestamp.to_owned());
137        self
138    }
139
140    pub fn color(&mut self, color: &str) -> &mut Self {
141        self.color = Some(color.to_owned());
142        self
143    }
144
145    pub fn footer(&mut self, text: &str, icon_url: Option<String>) -> &mut Self {
146        self.footer = Some(EmbedFooter::new(text, icon_url));
147        self
148    }
149
150    pub fn image(&mut self, url: &str) -> &mut Self {
151        self.image = Some(EmbedImage::new(url));
152        self
153    }
154
155    pub fn video(&mut self, url: &str) -> &mut Self {
156        self.video = Some(EmbedVideo::new(url));
157        self
158    }
159
160    pub fn thumbnail(&mut self, url: &str) -> &mut Self {
161        self.thumbnail = Some(EmbedThumbnail::new(url));
162        self
163    }
164
165    pub fn provider(&mut self, name: &str, url: &str) -> &mut Self {
166        self.provider = Some(EmbedProvider::new(name, url));
167        self
168    }
169
170    pub fn author(
171        &mut self,
172        name: &str,
173        url: Option<String>,
174        icon_url: Option<String>,
175    ) -> &mut Self {
176        self.author = Some(EmbedAuthor::new(name, url, icon_url));
177        self
178    }
179
180    pub fn field(&mut self, name: &str, value: &str, inline: bool) -> &mut Self {
181        if self.fields.len() == 10 {
182            panic!("You can't have more than")
183        }
184
185        self.fields.push(EmbedField::new(name, value, inline));
186        self
187    }
188}
189
190#[derive(Serialize, Debug)]
191pub struct EmbedField {
192    pub name: String,
193    pub value: String,
194    pub inline: bool,
195}
196
197impl EmbedField {
198    pub fn new(name: &str, value: &str, inline: bool) -> Self {
199        Self {
200            name: name.to_owned(),
201            value: value.to_owned(),
202            inline,
203        }
204    }
205}
206
207#[derive(Serialize, Debug)]
208pub struct EmbedFooter {
209    pub text: String,
210    pub icon_url: Option<String>,
211}
212
213impl EmbedFooter {
214    pub fn new(text: &str, icon_url: Option<String>) -> Self {
215        Self {
216            text: text.to_owned(),
217            icon_url,
218        }
219    }
220}
221
222pub type EmbedImage = EmbedUrlSource;
223pub type EmbedThumbnail = EmbedUrlSource;
224pub type EmbedVideo = EmbedUrlSource;
225
226#[derive(Serialize, Debug)]
227pub struct EmbedUrlSource {
228    pub url: String,
229}
230
231impl EmbedUrlSource {
232    pub fn new(url: &str) -> Self {
233        Self {
234            url: url.to_owned(),
235        }
236    }
237}
238
239#[derive(Serialize, Debug)]
240pub struct EmbedProvider {
241    pub name: String,
242    pub url: String,
243}
244
245impl EmbedProvider {
246    pub fn new(name: &str, url: &str) -> Self {
247        Self {
248            name: name.to_owned(),
249            url: url.to_owned(),
250        }
251    }
252}
253
254#[derive(Serialize, Debug)]
255pub struct EmbedAuthor {
256    pub name: String,
257    pub url: Option<String>,
258    pub icon_url: Option<String>,
259}
260
261impl EmbedAuthor {
262    pub fn new(name: &str, url: Option<String>, icon_url: Option<String>) -> Self {
263        Self {
264            name: name.to_owned(),
265            url,
266            icon_url,
267        }
268    }
269}
270
271pub enum AllowedMention {
272    RoleMention,
273    UserMention,
274    EveryoneMention,
275}
276
277fn resolve_allowed_mention_name(allowed_mention: AllowedMention) -> String {
278    match allowed_mention {
279        AllowedMention::RoleMention => "roles".to_string(),
280        AllowedMention::UserMention => "users".to_string(),
281        AllowedMention::EveryoneMention => "everyone".to_string(),
282    }
283}
284
285#[derive(Serialize, Debug)]
286pub struct AllowedMentions {
287    pub parse: Option<Vec<String>>,
288    pub roles: Option<Vec<Snowflake>>,
289    pub users: Option<Vec<Snowflake>>,
290    pub replied_user: bool,
291}
292
293impl AllowedMentions {
294    pub fn new(
295        parse: Option<Vec<AllowedMention>>,
296        roles: Option<Vec<Snowflake>>,
297        users: Option<Vec<Snowflake>>,
298        replied_user: bool,
299    ) -> Self {
300        let mut parse_strings: Vec<String> = vec![];
301        if parse.is_some() {
302            parse
303                .unwrap()
304                .into_iter()
305                .for_each(|x| parse_strings.push(resolve_allowed_mention_name(x)))
306        }
307
308        Self {
309            parse: Some(parse_strings),
310            roles,
311            users,
312            replied_user,
313        }
314    }
315}