Skip to main content

EmbedBuilder

Struct EmbedBuilder 

Source
pub struct EmbedBuilder(/* private fields */);
Expand description

Builder for Embed. Chain methods and call .build() at the end.

use fluxer::prelude::*;

let embed = EmbedBuilder::new()
    .title("Hello")
    .description("World")
    .color(0x00FF00)
    .build();

Implementations§

Source§

impl EmbedBuilder

Source

pub fn new() -> Self

Examples found in repository?
examples/bot.rs (line 96)
28    async fn on_message(&self, ctx: Context, msg: Message) {
29        let user_cached = ctx.cache.user(&msg.author.id).await.is_some();
30        let ch_cached   = ctx.cache.channel(msg.channel_id.as_deref().unwrap_or("")).await.is_some();
31        let content_preview = msg.content.as_deref().unwrap_or("").chars().take(60).collect::<String>();
32        let attachments = msg.attachments.as_ref().map(|a| a.len()).unwrap_or(0);
33        let embeds = msg.embeds.as_ref().map(|e| e.len()).unwrap_or(0);
34        println!(
35            "[msg] author={}#{} channel={} guild={} | \"{}\" | attach={} embeds={} | cache: user={} ch={}",
36            msg.author.username,
37            msg.author.discriminator.as_deref().unwrap_or("0"),
38            msg.channel_id.as_deref().unwrap_or("?"),
39            msg.guild_id.as_deref().unwrap_or("DM"),
40            content_preview,
41            attachments,
42            embeds,
43            user_cached,
44            ch_cached,
45        );
46
47        if msg.author.bot.unwrap_or(false) {
48            return;
49        }
50
51        let content = match msg.content.as_deref() {
52            Some(c) => c,
53            None => return,
54        };
55
56        let channel_id = msg.channel_id.as_deref().unwrap_or_default();
57
58        let (cmd, args) = match parse_command(content) {
59            Some(v) => v,
60            None => return,
61        };
62
63        match cmd {
64            "ping" => {
65                let start = Instant::now();
66                let sent = ctx.http.send_message(channel_id, "Pong!").await;
67                let elapsed = start.elapsed().as_millis();
68
69                if let Ok(sent) = sent {
70                    let _ = ctx.http.edit_message(
71                        channel_id,
72                        &sent.id,
73                        &format!("Pong! {}ms", elapsed),
74                    ).await;
75                }
76            }
77
78            "say" => {
79                if args.is_empty() {
80                    let _ = ctx.http.send_message(channel_id, "Say what?").await;
81                    return;
82                }
83                let _ = ctx.http.delete_message(channel_id, &msg.id).await;
84                let _ = ctx.http.send_message(channel_id, args).await;
85            }
86
87            "embed" => {
88                let (title, desc) = match args.split_once('|') {
89                    Some((t, d)) => (t.trim(), d.trim()),
90                    None => {
91                        let _ = ctx.http.send_message(channel_id, "`!embed title | description`").await;
92                        return;
93                    }
94                };
95
96                let embed = EmbedBuilder::new()
97                    .title(title)
98                    .description(desc)
99                    .color(0x5865F2)
100                    .build();
101
102                let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
103            }
104
105            "react" => {
106                let _ = ctx.http.add_reaction(channel_id, &msg.id, "❤️").await;
107            }
108
109            "purge" => {
110                let count: u8 = args.parse().unwrap_or(0);
111                if count == 0 || count > 100 {
112                    let _ = ctx.http.send_message(channel_id, "1-100.").await;
113                    return;
114                }
115
116                let query = GetMessagesQuery {
117                    limit: Some(count),
118                    ..Default::default()
119                };
120
121                if let Ok(messages) = ctx.http.get_messages(channel_id, query).await {
122                    let ids: Vec<&str> = messages.iter().map(|m| m.id.as_str()).collect();
123                    let _ = ctx.http.bulk_delete_messages(channel_id, ids).await;
124                }
125            }
126
127            "serverinfo" => {
128                let guild_id = match &msg.guild_id {
129                    Some(id) => id.as_str(),
130                    None => return,
131                };
132
133                if let Ok(guild) = ctx.http.get_guild(guild_id).await {
134                    let name = guild.name.as_deref().unwrap_or("Unknown");
135
136                    let members = ctx.http.get_guild_members(guild_id, Some(1000), None).await
137                        .map(|m| m.len().to_string())
138                        .unwrap_or("?".into());
139
140                    let embed = EmbedBuilder::new()
141                        .title(name)
142                        .field("Members", &members, true)
143                        .color(0x5865F2)
144                        .build();
145
146                    let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
147                }
148            }
149
150            "attach" => {
151                if args.is_empty() {
152                    let _ = ctx.http.send_message(channel_id, "Usage: `!attach <file path>`").await;
153                    return;
154                }
155                let path = std::path::Path::new(args);
156                let filename = path
157                    .file_name()
158                    .and_then(|n| n.to_str())
159                    .unwrap_or("file")
160                    .to_string();
161                let content_type = match path.extension().and_then(|e| e.to_str()) {
162                    Some("mp3") => "audio/mpeg",
163                    Some("mp4") => "video/mp4",
164                    Some("mov") => "video/quicktime",
165                    Some("webm") => "video/webm",
166                    Some("png") => "image/png",
167                    Some("jpg") | Some("jpeg") => "image/jpeg",
168                    Some("gif") => "image/gif",
169                    Some("webp") => "image/webp",
170                    Some("txt") => "text/plain",
171                    Some("pdf") => "application/pdf",
172                    _ => "application/octet-stream",
173                };
174                match tokio::fs::read(path).await {
175                    Ok(data) => {
176                        let file = AttachmentFile {
177                            filename,
178                            data,
179                            content_type: Some(content_type.to_string()),
180                        };
181                        match ctx.http.send_files(channel_id, vec![file], None).await {
182                            Ok(msg) => println!("[attach] sent message {}", msg.id),
183                            Err(e) => eprintln!("[attach] error: {}", e),
184                        }
185                    }
186                    Err(e) => {
187                        eprintln!("[attach] failed to read file: {}", e);
188                        let _ = ctx.http.send_message(channel_id, &format!("Failed to read file: {}", e)).await;
189                    }
190                }
191            }
192
193            _ => {}
194        }
195    }
Source

pub fn title(self, title: impl Into<String>) -> Self

Examples found in repository?
examples/bot.rs (line 97)
28    async fn on_message(&self, ctx: Context, msg: Message) {
29        let user_cached = ctx.cache.user(&msg.author.id).await.is_some();
30        let ch_cached   = ctx.cache.channel(msg.channel_id.as_deref().unwrap_or("")).await.is_some();
31        let content_preview = msg.content.as_deref().unwrap_or("").chars().take(60).collect::<String>();
32        let attachments = msg.attachments.as_ref().map(|a| a.len()).unwrap_or(0);
33        let embeds = msg.embeds.as_ref().map(|e| e.len()).unwrap_or(0);
34        println!(
35            "[msg] author={}#{} channel={} guild={} | \"{}\" | attach={} embeds={} | cache: user={} ch={}",
36            msg.author.username,
37            msg.author.discriminator.as_deref().unwrap_or("0"),
38            msg.channel_id.as_deref().unwrap_or("?"),
39            msg.guild_id.as_deref().unwrap_or("DM"),
40            content_preview,
41            attachments,
42            embeds,
43            user_cached,
44            ch_cached,
45        );
46
47        if msg.author.bot.unwrap_or(false) {
48            return;
49        }
50
51        let content = match msg.content.as_deref() {
52            Some(c) => c,
53            None => return,
54        };
55
56        let channel_id = msg.channel_id.as_deref().unwrap_or_default();
57
58        let (cmd, args) = match parse_command(content) {
59            Some(v) => v,
60            None => return,
61        };
62
63        match cmd {
64            "ping" => {
65                let start = Instant::now();
66                let sent = ctx.http.send_message(channel_id, "Pong!").await;
67                let elapsed = start.elapsed().as_millis();
68
69                if let Ok(sent) = sent {
70                    let _ = ctx.http.edit_message(
71                        channel_id,
72                        &sent.id,
73                        &format!("Pong! {}ms", elapsed),
74                    ).await;
75                }
76            }
77
78            "say" => {
79                if args.is_empty() {
80                    let _ = ctx.http.send_message(channel_id, "Say what?").await;
81                    return;
82                }
83                let _ = ctx.http.delete_message(channel_id, &msg.id).await;
84                let _ = ctx.http.send_message(channel_id, args).await;
85            }
86
87            "embed" => {
88                let (title, desc) = match args.split_once('|') {
89                    Some((t, d)) => (t.trim(), d.trim()),
90                    None => {
91                        let _ = ctx.http.send_message(channel_id, "`!embed title | description`").await;
92                        return;
93                    }
94                };
95
96                let embed = EmbedBuilder::new()
97                    .title(title)
98                    .description(desc)
99                    .color(0x5865F2)
100                    .build();
101
102                let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
103            }
104
105            "react" => {
106                let _ = ctx.http.add_reaction(channel_id, &msg.id, "❤️").await;
107            }
108
109            "purge" => {
110                let count: u8 = args.parse().unwrap_or(0);
111                if count == 0 || count > 100 {
112                    let _ = ctx.http.send_message(channel_id, "1-100.").await;
113                    return;
114                }
115
116                let query = GetMessagesQuery {
117                    limit: Some(count),
118                    ..Default::default()
119                };
120
121                if let Ok(messages) = ctx.http.get_messages(channel_id, query).await {
122                    let ids: Vec<&str> = messages.iter().map(|m| m.id.as_str()).collect();
123                    let _ = ctx.http.bulk_delete_messages(channel_id, ids).await;
124                }
125            }
126
127            "serverinfo" => {
128                let guild_id = match &msg.guild_id {
129                    Some(id) => id.as_str(),
130                    None => return,
131                };
132
133                if let Ok(guild) = ctx.http.get_guild(guild_id).await {
134                    let name = guild.name.as_deref().unwrap_or("Unknown");
135
136                    let members = ctx.http.get_guild_members(guild_id, Some(1000), None).await
137                        .map(|m| m.len().to_string())
138                        .unwrap_or("?".into());
139
140                    let embed = EmbedBuilder::new()
141                        .title(name)
142                        .field("Members", &members, true)
143                        .color(0x5865F2)
144                        .build();
145
146                    let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
147                }
148            }
149
150            "attach" => {
151                if args.is_empty() {
152                    let _ = ctx.http.send_message(channel_id, "Usage: `!attach <file path>`").await;
153                    return;
154                }
155                let path = std::path::Path::new(args);
156                let filename = path
157                    .file_name()
158                    .and_then(|n| n.to_str())
159                    .unwrap_or("file")
160                    .to_string();
161                let content_type = match path.extension().and_then(|e| e.to_str()) {
162                    Some("mp3") => "audio/mpeg",
163                    Some("mp4") => "video/mp4",
164                    Some("mov") => "video/quicktime",
165                    Some("webm") => "video/webm",
166                    Some("png") => "image/png",
167                    Some("jpg") | Some("jpeg") => "image/jpeg",
168                    Some("gif") => "image/gif",
169                    Some("webp") => "image/webp",
170                    Some("txt") => "text/plain",
171                    Some("pdf") => "application/pdf",
172                    _ => "application/octet-stream",
173                };
174                match tokio::fs::read(path).await {
175                    Ok(data) => {
176                        let file = AttachmentFile {
177                            filename,
178                            data,
179                            content_type: Some(content_type.to_string()),
180                        };
181                        match ctx.http.send_files(channel_id, vec![file], None).await {
182                            Ok(msg) => println!("[attach] sent message {}", msg.id),
183                            Err(e) => eprintln!("[attach] error: {}", e),
184                        }
185                    }
186                    Err(e) => {
187                        eprintln!("[attach] failed to read file: {}", e);
188                        let _ = ctx.http.send_message(channel_id, &format!("Failed to read file: {}", e)).await;
189                    }
190                }
191            }
192
193            _ => {}
194        }
195    }
Source

pub fn description(self, desc: impl Into<String>) -> Self

Examples found in repository?
examples/bot.rs (line 98)
28    async fn on_message(&self, ctx: Context, msg: Message) {
29        let user_cached = ctx.cache.user(&msg.author.id).await.is_some();
30        let ch_cached   = ctx.cache.channel(msg.channel_id.as_deref().unwrap_or("")).await.is_some();
31        let content_preview = msg.content.as_deref().unwrap_or("").chars().take(60).collect::<String>();
32        let attachments = msg.attachments.as_ref().map(|a| a.len()).unwrap_or(0);
33        let embeds = msg.embeds.as_ref().map(|e| e.len()).unwrap_or(0);
34        println!(
35            "[msg] author={}#{} channel={} guild={} | \"{}\" | attach={} embeds={} | cache: user={} ch={}",
36            msg.author.username,
37            msg.author.discriminator.as_deref().unwrap_or("0"),
38            msg.channel_id.as_deref().unwrap_or("?"),
39            msg.guild_id.as_deref().unwrap_or("DM"),
40            content_preview,
41            attachments,
42            embeds,
43            user_cached,
44            ch_cached,
45        );
46
47        if msg.author.bot.unwrap_or(false) {
48            return;
49        }
50
51        let content = match msg.content.as_deref() {
52            Some(c) => c,
53            None => return,
54        };
55
56        let channel_id = msg.channel_id.as_deref().unwrap_or_default();
57
58        let (cmd, args) = match parse_command(content) {
59            Some(v) => v,
60            None => return,
61        };
62
63        match cmd {
64            "ping" => {
65                let start = Instant::now();
66                let sent = ctx.http.send_message(channel_id, "Pong!").await;
67                let elapsed = start.elapsed().as_millis();
68
69                if let Ok(sent) = sent {
70                    let _ = ctx.http.edit_message(
71                        channel_id,
72                        &sent.id,
73                        &format!("Pong! {}ms", elapsed),
74                    ).await;
75                }
76            }
77
78            "say" => {
79                if args.is_empty() {
80                    let _ = ctx.http.send_message(channel_id, "Say what?").await;
81                    return;
82                }
83                let _ = ctx.http.delete_message(channel_id, &msg.id).await;
84                let _ = ctx.http.send_message(channel_id, args).await;
85            }
86
87            "embed" => {
88                let (title, desc) = match args.split_once('|') {
89                    Some((t, d)) => (t.trim(), d.trim()),
90                    None => {
91                        let _ = ctx.http.send_message(channel_id, "`!embed title | description`").await;
92                        return;
93                    }
94                };
95
96                let embed = EmbedBuilder::new()
97                    .title(title)
98                    .description(desc)
99                    .color(0x5865F2)
100                    .build();
101
102                let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
103            }
104
105            "react" => {
106                let _ = ctx.http.add_reaction(channel_id, &msg.id, "❤️").await;
107            }
108
109            "purge" => {
110                let count: u8 = args.parse().unwrap_or(0);
111                if count == 0 || count > 100 {
112                    let _ = ctx.http.send_message(channel_id, "1-100.").await;
113                    return;
114                }
115
116                let query = GetMessagesQuery {
117                    limit: Some(count),
118                    ..Default::default()
119                };
120
121                if let Ok(messages) = ctx.http.get_messages(channel_id, query).await {
122                    let ids: Vec<&str> = messages.iter().map(|m| m.id.as_str()).collect();
123                    let _ = ctx.http.bulk_delete_messages(channel_id, ids).await;
124                }
125            }
126
127            "serverinfo" => {
128                let guild_id = match &msg.guild_id {
129                    Some(id) => id.as_str(),
130                    None => return,
131                };
132
133                if let Ok(guild) = ctx.http.get_guild(guild_id).await {
134                    let name = guild.name.as_deref().unwrap_or("Unknown");
135
136                    let members = ctx.http.get_guild_members(guild_id, Some(1000), None).await
137                        .map(|m| m.len().to_string())
138                        .unwrap_or("?".into());
139
140                    let embed = EmbedBuilder::new()
141                        .title(name)
142                        .field("Members", &members, true)
143                        .color(0x5865F2)
144                        .build();
145
146                    let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
147                }
148            }
149
150            "attach" => {
151                if args.is_empty() {
152                    let _ = ctx.http.send_message(channel_id, "Usage: `!attach <file path>`").await;
153                    return;
154                }
155                let path = std::path::Path::new(args);
156                let filename = path
157                    .file_name()
158                    .and_then(|n| n.to_str())
159                    .unwrap_or("file")
160                    .to_string();
161                let content_type = match path.extension().and_then(|e| e.to_str()) {
162                    Some("mp3") => "audio/mpeg",
163                    Some("mp4") => "video/mp4",
164                    Some("mov") => "video/quicktime",
165                    Some("webm") => "video/webm",
166                    Some("png") => "image/png",
167                    Some("jpg") | Some("jpeg") => "image/jpeg",
168                    Some("gif") => "image/gif",
169                    Some("webp") => "image/webp",
170                    Some("txt") => "text/plain",
171                    Some("pdf") => "application/pdf",
172                    _ => "application/octet-stream",
173                };
174                match tokio::fs::read(path).await {
175                    Ok(data) => {
176                        let file = AttachmentFile {
177                            filename,
178                            data,
179                            content_type: Some(content_type.to_string()),
180                        };
181                        match ctx.http.send_files(channel_id, vec![file], None).await {
182                            Ok(msg) => println!("[attach] sent message {}", msg.id),
183                            Err(e) => eprintln!("[attach] error: {}", e),
184                        }
185                    }
186                    Err(e) => {
187                        eprintln!("[attach] failed to read file: {}", e);
188                        let _ = ctx.http.send_message(channel_id, &format!("Failed to read file: {}", e)).await;
189                    }
190                }
191            }
192
193            _ => {}
194        }
195    }
Source

pub fn url(self, url: impl Into<String>) -> Self

Source

pub fn color(self, color: u64) -> Self

Examples found in repository?
examples/bot.rs (line 99)
28    async fn on_message(&self, ctx: Context, msg: Message) {
29        let user_cached = ctx.cache.user(&msg.author.id).await.is_some();
30        let ch_cached   = ctx.cache.channel(msg.channel_id.as_deref().unwrap_or("")).await.is_some();
31        let content_preview = msg.content.as_deref().unwrap_or("").chars().take(60).collect::<String>();
32        let attachments = msg.attachments.as_ref().map(|a| a.len()).unwrap_or(0);
33        let embeds = msg.embeds.as_ref().map(|e| e.len()).unwrap_or(0);
34        println!(
35            "[msg] author={}#{} channel={} guild={} | \"{}\" | attach={} embeds={} | cache: user={} ch={}",
36            msg.author.username,
37            msg.author.discriminator.as_deref().unwrap_or("0"),
38            msg.channel_id.as_deref().unwrap_or("?"),
39            msg.guild_id.as_deref().unwrap_or("DM"),
40            content_preview,
41            attachments,
42            embeds,
43            user_cached,
44            ch_cached,
45        );
46
47        if msg.author.bot.unwrap_or(false) {
48            return;
49        }
50
51        let content = match msg.content.as_deref() {
52            Some(c) => c,
53            None => return,
54        };
55
56        let channel_id = msg.channel_id.as_deref().unwrap_or_default();
57
58        let (cmd, args) = match parse_command(content) {
59            Some(v) => v,
60            None => return,
61        };
62
63        match cmd {
64            "ping" => {
65                let start = Instant::now();
66                let sent = ctx.http.send_message(channel_id, "Pong!").await;
67                let elapsed = start.elapsed().as_millis();
68
69                if let Ok(sent) = sent {
70                    let _ = ctx.http.edit_message(
71                        channel_id,
72                        &sent.id,
73                        &format!("Pong! {}ms", elapsed),
74                    ).await;
75                }
76            }
77
78            "say" => {
79                if args.is_empty() {
80                    let _ = ctx.http.send_message(channel_id, "Say what?").await;
81                    return;
82                }
83                let _ = ctx.http.delete_message(channel_id, &msg.id).await;
84                let _ = ctx.http.send_message(channel_id, args).await;
85            }
86
87            "embed" => {
88                let (title, desc) = match args.split_once('|') {
89                    Some((t, d)) => (t.trim(), d.trim()),
90                    None => {
91                        let _ = ctx.http.send_message(channel_id, "`!embed title | description`").await;
92                        return;
93                    }
94                };
95
96                let embed = EmbedBuilder::new()
97                    .title(title)
98                    .description(desc)
99                    .color(0x5865F2)
100                    .build();
101
102                let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
103            }
104
105            "react" => {
106                let _ = ctx.http.add_reaction(channel_id, &msg.id, "❤️").await;
107            }
108
109            "purge" => {
110                let count: u8 = args.parse().unwrap_or(0);
111                if count == 0 || count > 100 {
112                    let _ = ctx.http.send_message(channel_id, "1-100.").await;
113                    return;
114                }
115
116                let query = GetMessagesQuery {
117                    limit: Some(count),
118                    ..Default::default()
119                };
120
121                if let Ok(messages) = ctx.http.get_messages(channel_id, query).await {
122                    let ids: Vec<&str> = messages.iter().map(|m| m.id.as_str()).collect();
123                    let _ = ctx.http.bulk_delete_messages(channel_id, ids).await;
124                }
125            }
126
127            "serverinfo" => {
128                let guild_id = match &msg.guild_id {
129                    Some(id) => id.as_str(),
130                    None => return,
131                };
132
133                if let Ok(guild) = ctx.http.get_guild(guild_id).await {
134                    let name = guild.name.as_deref().unwrap_or("Unknown");
135
136                    let members = ctx.http.get_guild_members(guild_id, Some(1000), None).await
137                        .map(|m| m.len().to_string())
138                        .unwrap_or("?".into());
139
140                    let embed = EmbedBuilder::new()
141                        .title(name)
142                        .field("Members", &members, true)
143                        .color(0x5865F2)
144                        .build();
145
146                    let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
147                }
148            }
149
150            "attach" => {
151                if args.is_empty() {
152                    let _ = ctx.http.send_message(channel_id, "Usage: `!attach <file path>`").await;
153                    return;
154                }
155                let path = std::path::Path::new(args);
156                let filename = path
157                    .file_name()
158                    .and_then(|n| n.to_str())
159                    .unwrap_or("file")
160                    .to_string();
161                let content_type = match path.extension().and_then(|e| e.to_str()) {
162                    Some("mp3") => "audio/mpeg",
163                    Some("mp4") => "video/mp4",
164                    Some("mov") => "video/quicktime",
165                    Some("webm") => "video/webm",
166                    Some("png") => "image/png",
167                    Some("jpg") | Some("jpeg") => "image/jpeg",
168                    Some("gif") => "image/gif",
169                    Some("webp") => "image/webp",
170                    Some("txt") => "text/plain",
171                    Some("pdf") => "application/pdf",
172                    _ => "application/octet-stream",
173                };
174                match tokio::fs::read(path).await {
175                    Ok(data) => {
176                        let file = AttachmentFile {
177                            filename,
178                            data,
179                            content_type: Some(content_type.to_string()),
180                        };
181                        match ctx.http.send_files(channel_id, vec![file], None).await {
182                            Ok(msg) => println!("[attach] sent message {}", msg.id),
183                            Err(e) => eprintln!("[attach] error: {}", e),
184                        }
185                    }
186                    Err(e) => {
187                        eprintln!("[attach] failed to read file: {}", e);
188                        let _ = ctx.http.send_message(channel_id, &format!("Failed to read file: {}", e)).await;
189                    }
190                }
191            }
192
193            _ => {}
194        }
195    }
Source

pub fn timestamp(self, ts: impl Into<String>) -> Self

Source

pub fn footer(self, text: impl Into<String>, icon_url: Option<String>) -> Self

Source

pub fn image(self, url: impl Into<String>) -> Self

Source

pub fn thumbnail(self, url: impl Into<String>) -> Self

Source

pub fn author( self, name: impl Into<String>, url: Option<String>, icon_url: Option<String>, ) -> Self

Source

pub fn field( self, name: impl Into<String>, value: impl Into<String>, inline: bool, ) -> Self

Examples found in repository?
examples/bot.rs (line 142)
28    async fn on_message(&self, ctx: Context, msg: Message) {
29        let user_cached = ctx.cache.user(&msg.author.id).await.is_some();
30        let ch_cached   = ctx.cache.channel(msg.channel_id.as_deref().unwrap_or("")).await.is_some();
31        let content_preview = msg.content.as_deref().unwrap_or("").chars().take(60).collect::<String>();
32        let attachments = msg.attachments.as_ref().map(|a| a.len()).unwrap_or(0);
33        let embeds = msg.embeds.as_ref().map(|e| e.len()).unwrap_or(0);
34        println!(
35            "[msg] author={}#{} channel={} guild={} | \"{}\" | attach={} embeds={} | cache: user={} ch={}",
36            msg.author.username,
37            msg.author.discriminator.as_deref().unwrap_or("0"),
38            msg.channel_id.as_deref().unwrap_or("?"),
39            msg.guild_id.as_deref().unwrap_or("DM"),
40            content_preview,
41            attachments,
42            embeds,
43            user_cached,
44            ch_cached,
45        );
46
47        if msg.author.bot.unwrap_or(false) {
48            return;
49        }
50
51        let content = match msg.content.as_deref() {
52            Some(c) => c,
53            None => return,
54        };
55
56        let channel_id = msg.channel_id.as_deref().unwrap_or_default();
57
58        let (cmd, args) = match parse_command(content) {
59            Some(v) => v,
60            None => return,
61        };
62
63        match cmd {
64            "ping" => {
65                let start = Instant::now();
66                let sent = ctx.http.send_message(channel_id, "Pong!").await;
67                let elapsed = start.elapsed().as_millis();
68
69                if let Ok(sent) = sent {
70                    let _ = ctx.http.edit_message(
71                        channel_id,
72                        &sent.id,
73                        &format!("Pong! {}ms", elapsed),
74                    ).await;
75                }
76            }
77
78            "say" => {
79                if args.is_empty() {
80                    let _ = ctx.http.send_message(channel_id, "Say what?").await;
81                    return;
82                }
83                let _ = ctx.http.delete_message(channel_id, &msg.id).await;
84                let _ = ctx.http.send_message(channel_id, args).await;
85            }
86
87            "embed" => {
88                let (title, desc) = match args.split_once('|') {
89                    Some((t, d)) => (t.trim(), d.trim()),
90                    None => {
91                        let _ = ctx.http.send_message(channel_id, "`!embed title | description`").await;
92                        return;
93                    }
94                };
95
96                let embed = EmbedBuilder::new()
97                    .title(title)
98                    .description(desc)
99                    .color(0x5865F2)
100                    .build();
101
102                let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
103            }
104
105            "react" => {
106                let _ = ctx.http.add_reaction(channel_id, &msg.id, "❤️").await;
107            }
108
109            "purge" => {
110                let count: u8 = args.parse().unwrap_or(0);
111                if count == 0 || count > 100 {
112                    let _ = ctx.http.send_message(channel_id, "1-100.").await;
113                    return;
114                }
115
116                let query = GetMessagesQuery {
117                    limit: Some(count),
118                    ..Default::default()
119                };
120
121                if let Ok(messages) = ctx.http.get_messages(channel_id, query).await {
122                    let ids: Vec<&str> = messages.iter().map(|m| m.id.as_str()).collect();
123                    let _ = ctx.http.bulk_delete_messages(channel_id, ids).await;
124                }
125            }
126
127            "serverinfo" => {
128                let guild_id = match &msg.guild_id {
129                    Some(id) => id.as_str(),
130                    None => return,
131                };
132
133                if let Ok(guild) = ctx.http.get_guild(guild_id).await {
134                    let name = guild.name.as_deref().unwrap_or("Unknown");
135
136                    let members = ctx.http.get_guild_members(guild_id, Some(1000), None).await
137                        .map(|m| m.len().to_string())
138                        .unwrap_or("?".into());
139
140                    let embed = EmbedBuilder::new()
141                        .title(name)
142                        .field("Members", &members, true)
143                        .color(0x5865F2)
144                        .build();
145
146                    let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
147                }
148            }
149
150            "attach" => {
151                if args.is_empty() {
152                    let _ = ctx.http.send_message(channel_id, "Usage: `!attach <file path>`").await;
153                    return;
154                }
155                let path = std::path::Path::new(args);
156                let filename = path
157                    .file_name()
158                    .and_then(|n| n.to_str())
159                    .unwrap_or("file")
160                    .to_string();
161                let content_type = match path.extension().and_then(|e| e.to_str()) {
162                    Some("mp3") => "audio/mpeg",
163                    Some("mp4") => "video/mp4",
164                    Some("mov") => "video/quicktime",
165                    Some("webm") => "video/webm",
166                    Some("png") => "image/png",
167                    Some("jpg") | Some("jpeg") => "image/jpeg",
168                    Some("gif") => "image/gif",
169                    Some("webp") => "image/webp",
170                    Some("txt") => "text/plain",
171                    Some("pdf") => "application/pdf",
172                    _ => "application/octet-stream",
173                };
174                match tokio::fs::read(path).await {
175                    Ok(data) => {
176                        let file = AttachmentFile {
177                            filename,
178                            data,
179                            content_type: Some(content_type.to_string()),
180                        };
181                        match ctx.http.send_files(channel_id, vec![file], None).await {
182                            Ok(msg) => println!("[attach] sent message {}", msg.id),
183                            Err(e) => eprintln!("[attach] error: {}", e),
184                        }
185                    }
186                    Err(e) => {
187                        eprintln!("[attach] failed to read file: {}", e);
188                        let _ = ctx.http.send_message(channel_id, &format!("Failed to read file: {}", e)).await;
189                    }
190                }
191            }
192
193            _ => {}
194        }
195    }
Source

pub fn build(self) -> Embed

Examples found in repository?
examples/bot.rs (line 100)
28    async fn on_message(&self, ctx: Context, msg: Message) {
29        let user_cached = ctx.cache.user(&msg.author.id).await.is_some();
30        let ch_cached   = ctx.cache.channel(msg.channel_id.as_deref().unwrap_or("")).await.is_some();
31        let content_preview = msg.content.as_deref().unwrap_or("").chars().take(60).collect::<String>();
32        let attachments = msg.attachments.as_ref().map(|a| a.len()).unwrap_or(0);
33        let embeds = msg.embeds.as_ref().map(|e| e.len()).unwrap_or(0);
34        println!(
35            "[msg] author={}#{} channel={} guild={} | \"{}\" | attach={} embeds={} | cache: user={} ch={}",
36            msg.author.username,
37            msg.author.discriminator.as_deref().unwrap_or("0"),
38            msg.channel_id.as_deref().unwrap_or("?"),
39            msg.guild_id.as_deref().unwrap_or("DM"),
40            content_preview,
41            attachments,
42            embeds,
43            user_cached,
44            ch_cached,
45        );
46
47        if msg.author.bot.unwrap_or(false) {
48            return;
49        }
50
51        let content = match msg.content.as_deref() {
52            Some(c) => c,
53            None => return,
54        };
55
56        let channel_id = msg.channel_id.as_deref().unwrap_or_default();
57
58        let (cmd, args) = match parse_command(content) {
59            Some(v) => v,
60            None => return,
61        };
62
63        match cmd {
64            "ping" => {
65                let start = Instant::now();
66                let sent = ctx.http.send_message(channel_id, "Pong!").await;
67                let elapsed = start.elapsed().as_millis();
68
69                if let Ok(sent) = sent {
70                    let _ = ctx.http.edit_message(
71                        channel_id,
72                        &sent.id,
73                        &format!("Pong! {}ms", elapsed),
74                    ).await;
75                }
76            }
77
78            "say" => {
79                if args.is_empty() {
80                    let _ = ctx.http.send_message(channel_id, "Say what?").await;
81                    return;
82                }
83                let _ = ctx.http.delete_message(channel_id, &msg.id).await;
84                let _ = ctx.http.send_message(channel_id, args).await;
85            }
86
87            "embed" => {
88                let (title, desc) = match args.split_once('|') {
89                    Some((t, d)) => (t.trim(), d.trim()),
90                    None => {
91                        let _ = ctx.http.send_message(channel_id, "`!embed title | description`").await;
92                        return;
93                    }
94                };
95
96                let embed = EmbedBuilder::new()
97                    .title(title)
98                    .description(desc)
99                    .color(0x5865F2)
100                    .build();
101
102                let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
103            }
104
105            "react" => {
106                let _ = ctx.http.add_reaction(channel_id, &msg.id, "❤️").await;
107            }
108
109            "purge" => {
110                let count: u8 = args.parse().unwrap_or(0);
111                if count == 0 || count > 100 {
112                    let _ = ctx.http.send_message(channel_id, "1-100.").await;
113                    return;
114                }
115
116                let query = GetMessagesQuery {
117                    limit: Some(count),
118                    ..Default::default()
119                };
120
121                if let Ok(messages) = ctx.http.get_messages(channel_id, query).await {
122                    let ids: Vec<&str> = messages.iter().map(|m| m.id.as_str()).collect();
123                    let _ = ctx.http.bulk_delete_messages(channel_id, ids).await;
124                }
125            }
126
127            "serverinfo" => {
128                let guild_id = match &msg.guild_id {
129                    Some(id) => id.as_str(),
130                    None => return,
131                };
132
133                if let Ok(guild) = ctx.http.get_guild(guild_id).await {
134                    let name = guild.name.as_deref().unwrap_or("Unknown");
135
136                    let members = ctx.http.get_guild_members(guild_id, Some(1000), None).await
137                        .map(|m| m.len().to_string())
138                        .unwrap_or("?".into());
139
140                    let embed = EmbedBuilder::new()
141                        .title(name)
142                        .field("Members", &members, true)
143                        .color(0x5865F2)
144                        .build();
145
146                    let _ = ctx.http.send_embed(channel_id, None, vec![embed]).await;
147                }
148            }
149
150            "attach" => {
151                if args.is_empty() {
152                    let _ = ctx.http.send_message(channel_id, "Usage: `!attach <file path>`").await;
153                    return;
154                }
155                let path = std::path::Path::new(args);
156                let filename = path
157                    .file_name()
158                    .and_then(|n| n.to_str())
159                    .unwrap_or("file")
160                    .to_string();
161                let content_type = match path.extension().and_then(|e| e.to_str()) {
162                    Some("mp3") => "audio/mpeg",
163                    Some("mp4") => "video/mp4",
164                    Some("mov") => "video/quicktime",
165                    Some("webm") => "video/webm",
166                    Some("png") => "image/png",
167                    Some("jpg") | Some("jpeg") => "image/jpeg",
168                    Some("gif") => "image/gif",
169                    Some("webp") => "image/webp",
170                    Some("txt") => "text/plain",
171                    Some("pdf") => "application/pdf",
172                    _ => "application/octet-stream",
173                };
174                match tokio::fs::read(path).await {
175                    Ok(data) => {
176                        let file = AttachmentFile {
177                            filename,
178                            data,
179                            content_type: Some(content_type.to_string()),
180                        };
181                        match ctx.http.send_files(channel_id, vec![file], None).await {
182                            Ok(msg) => println!("[attach] sent message {}", msg.id),
183                            Err(e) => eprintln!("[attach] error: {}", e),
184                        }
185                    }
186                    Err(e) => {
187                        eprintln!("[attach] failed to read file: {}", e);
188                        let _ = ctx.http.send_message(channel_id, &format!("Failed to read file: {}", e)).await;
189                    }
190                }
191            }
192
193            _ => {}
194        }
195    }

Trait Implementations§

Source§

impl Debug for EmbedBuilder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for EmbedBuilder

Source§

fn default() -> EmbedBuilder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more