discord_webhook_rs/
discord.rs1use super::Embed;
2
3use reqwest::blocking::{Client, Response};
4use serde_json::{Map, Value};
5
6#[derive(Debug)]
7pub enum Error {
8 Request(reqwest::Error),
9 MaxContent,
10 MaxEmbed,
11 MaxField,
12 InvalidColor,
13 InvalidEmbed,
14 MissingNameField,
15 MissingValueField,
16}
17
18pub struct Webhook {
19 url: String,
20 username: Option<String>,
21 avatar_url: Option<String>,
22 content: Option<String>,
23 embeds: Vec<Embed>,
24}
25
26impl Webhook {
27 pub fn new(url: impl Into<String>) -> Self {
28 Webhook {
29 url: url.into(),
30 username: None,
31 avatar_url: None,
32 content: None,
33 embeds: Vec::new(),
34 }
35 }
36
37 pub fn username(mut self, username: impl Into<String>) -> Self {
38 self.username = Some(username.into());
39 self
40 }
41
42 pub fn avatar_url(mut self, avatar_url: impl Into<String>) -> Self {
43 self.avatar_url = Some(avatar_url.into());
44 self
45 }
46
47 pub fn content(mut self, content: impl Into<String>) -> Self {
48 self.content = Some(content.into());
49 self
50 }
51
52 pub fn add_embed(mut self, embed: Embed) -> Self {
53 self.embeds.push(embed);
54 self
55 }
56
57 fn verify(&self) -> Result<(), Error> {
58 if let Some(content) = &self.content {
59 if content.len() > 2000 {
60 return Err(Error::MaxContent);
61 }
62 }
63
64 if self.embeds.len() > 10 {
65 return Err(Error::MaxEmbed);
66 }
67
68 Ok(())
69 }
70
71 fn build(&self) -> Result<Value, Error> {
72 self.verify()?;
73
74 let mut obj = Map::new(); if let Some(content) = &self.content {
77 obj.insert("content".into(), Value::String(content.clone()));
78 } else {
79 obj.insert("content".into(), Value::String("Hello from Rust!".into()));
80 }
81
82 if let Some(username) = &self.username {
83 obj.insert("username".into(), Value::String(username.clone()));
84 }
85
86 if let Some(avatar_url) = &self.avatar_url {
87 obj.insert("avatar_url".into(), Value::String(avatar_url.clone()));
88 }
89
90 obj.insert("embeds".into(), Value::Array(vec![]));
91 for embed in &self.embeds {
92 if let Value::Array(ref mut embeds) = obj["embeds"] {
93 embeds.push(embed.build()?);
94 }
95 }
96
97 Ok(Value::Object(obj))
98 }
99
100 pub fn send(self) -> Result<Response, Error> {
101 let client = Client::new();
102 let req = client
103 .post(&self.url)
104 .header("Content-Type", "application/json")
105 .body(self.build()?.to_string());
106
107 match req.send() {
108 Ok(response) => Ok(response),
109 Err(error) => Err(Error::Request(error)),
110 }
111 }
112}