use descord::prelude::*; use models::attachment::AttachmentPayload; #[tokio::main] async fn main() { dotenvy::dotenv().ok(); env_logger::init(); let mut client = Client::new( "MTMwMzc0OTM3NDQ0NjQwNzc0MA.GBMvPz.maTRVVrlaV40E-XjQyHxWhbEmIOyMKHUbJ9Tzs", GatewayIntent::NON_PRIVILEGED // for message commands | GatewayIntent::MESSAGE_CONTENT, "!", ) .await; register_all!(client => []); client.login().await; } #[command(description = "Send a message with two attachments")] async fn send_attach(msg: Message) { msg.reply(CreateMessageData { content: "Test message with attachment!".to_string(), attachments: vec![ AttachmentPayload::new("test.png", "test.png", "image/png"), AttachmentPayload::new("test2.png", "test.png", "image/png"), ], ..Default::default() }) .await; } #[command(description = "A command which will invoke an internal error")] async fn test(msg: Message) { msg.send_in_channel("").await; } // Custom help message // #[command] // async fn help(msg: Message) { // msg.reply("No default help Hahahah!").await; // } #[slash(name = "greet", description = "Get channel info")] async fn ping( interaction: Interaction, /// The channel to get info about channel: Channel, /// The user to mention, optional user: Option, ) { if let Some(user) = user { interaction .reply( format!("Hello, {}! You are in {}", user.mention, channel.mention), false, ) .await; } else { interaction .reply(format!("You are in {}", channel.mention), false) .await; } } #[slash( name = "echo", description = "Echoes the input", permissions = "administrator" )] async fn echo_slash(interaction: Interaction, #[autocomplete = auto_cmp] message: String) { interaction.defer().await; interaction.followup(message).await; } async fn auto_cmp(value: String) -> Vec { let options = vec!["fireplank", "wizard"]; options .into_iter() .filter(|o| o.starts_with(&value)) .map(|o| o.to_string()) .collect() } #[slash(name = "whisper", description = "Respond with ephemeral message")] async fn whisper(interaction: Interaction) { interaction .reply("This is an ephemeral message", true) .await; } // without cache info #[event] async fn message_delete_raw(_: DeletedMessage) { println!("message deleted"); } #[command( permissions = "administrator", description = "Echoes the input, (requires admin for some reason)" )] async fn echo(msg: Message, stuff: String) { msg.reply(format!("Hello, {}", stuff)).await; } #[slash(description = "Get a user's avatar")] async fn avatar(interaction: Interaction, #[doc = "User to fetch avatar from"] user: Option) { let member = interaction.member.as_ref().unwrap(); let (username, avatar) = match user { Some(user) => ( &user.username, user.get_avatar_url(ImageFormat::WebP, None).unwrap(), ), None => ( member .nick .as_ref() .unwrap_or_else(|| &member.user.as_ref().unwrap().username), member.get_avatar_url(ImageFormat::WebP, None).unwrap(), ), }; let embed = EmbedBuilder::new() .color(Color::Blue) .title(&format!("{}'s avatar", username)) .image(avatar, None, None) .build(); interaction.reply(embed, false).await; } #[command(description = "Count up or down")] async fn counter(msg: Message) { let msg = msg.send_in_channel("Count: 0").await; msg.react("⬆").await; msg.react("⬇").await; } #[command(description = "React to the message with the given emoji")] async fn react(msg: Message, emoji: String) { println!("reacting"); msg.react(&emoji).await; } #[event] async fn ready(data: ReadyData) { println!( "Logged in as: {}#{}", data.user.username, data.user.discriminator ); } #[event] async fn reaction_add(reaction: Reaction) { if reaction.member.clone().unwrap().user.unwrap().bot { return; } let msg = reaction.get_message().await.unwrap(); let (counter_message, count) = msg.content.split_once(" ").unwrap(); let mut count = count.parse::().unwrap(); if reaction.emoji.name == "⬆" { count += 1; tokio::join!( reaction.remove_reaction(), msg.edit(format!("{counter_message} {count}")) ); } else if reaction.emoji.name == "⬇" { count -= 1; tokio::join!( reaction.remove_reaction(), msg.edit(format!("{counter_message} {count}")) ); } } #[component(id = "btn1")] async fn btn1(int: Interaction) { int.reply("You clicked me!", false).await; } #[component(id = "btn2")] async fn btn2(int: Interaction) { int.reply("I told you not to click me!", false).await; } #[command(description = "Send a message with components")] async fn components(message: Message) { let b1: Component = ComponentBuilder::button(ButtonObject { style: ButtonStyle::Primary as _, label: Some("Click me".to_string()), custom_id: Some("btn1".to_string()), ..Default::default() }) .unwrap(); let b2: Component = ComponentBuilder::button(ButtonObject { style: ButtonStyle::Secondary as _, label: Some("Don't click me".to_string()), custom_id: Some("btn2".to_string()), ..Default::default() }) .unwrap(); let b3: Component = ComponentBuilder::button(ButtonObject { style: ButtonStyle::Danger as _, label: Some("You can't click me".to_string()), custom_id: Some("btn3".to_string()), disabled: true, ..Default::default() }) .unwrap(); let select = ComponentBuilder::select(SelectObject { select_type: SelectMenuType::StringSelect, placeholder: Some(String::from("String Select example")), custom_id: String::from("select"), options: Some(vec![ SelectOption { label: "abc".to_string(), value: "abc".to_string(), ..Default::default() }, SelectOption { label: "def".to_string(), value: "def".to_string(), ..Default::default() }, ]), ..Default::default() }) .unwrap(); // Column> message .reply(vec![vec![b1], vec![b2, b3], vec![select]]) .await; } #[command(description = "Replies with a message after a specified delay (in seconds)")] async fn delay(msg: Message) { let delay = msg .content .split_once(' ') .unwrap() .1 .parse::() .unwrap(); msg.get_channel().await.unwrap().send_typing().await; tokio::time::sleep(tokio::time::Duration::from_secs(delay)).await; msg.reply("The quick brown fox jumps over the lazy dog!") .await; }