#slash-command #discord #discord-bot #create #user #interaction #serenity

slashies

Slashies 帮助减少为 Discord 机器人创建slash命令所需的样板代码

4 个版本

0.1.3 2022年7月17日
0.1.2 2022年7月17日
0.1.1 2022年7月17日
0.1.0 2022年7月17日

#1803 in Rust 模式


用于 slashies-macros

MIT 许可证

34KB
287

创建 Discord 机器人 slash 命令的简单方法

Slashies 帮助减少为 Discord 机器人创建 slash 命令所需的样板代码。它建立在 Serenity 之上。它专注于提供可以通过宏 crate 推导的特性,以便于大多数直接使用案例,但同时也提供了实现这些特性的逃生门,以便进行更复杂的操作。

请务必阅读 Discord 文档 中的 slash 命令部分,以了解交互等一般概念。

使用 Slashies,您可以通过以下四个简单步骤创建 slash 命令

// 1. Create a struct representing the arguments for the command and derive/implement the
// Command trait

/// Greet a user
#[derive(Debug, Command)]
#[name = "greet"]
struct HelloCommand {
    /// The user to greet
    user: UserInput,
}

// 2. Implement the ApplicationCommandInteractionHandler trait to define what happens when you
// call the command
#[async_trait]
impl ApplicationCommandInteractionHandler for HelloCommand {
   async fn invoke(
       &self,
       ctx: &Context,
       command: &ApplicationCommandInteraction,
   ) -> Result<(), InvocationError> {
       let nickname = self.user.member.as_ref().map(|pm| pm.nick.as_ref()).flatten();
       let greeting = if let Some(nick) = nickname {
           format!("Hello {} aka {}", self.user.user.name, nick)
       } else {
           format!("Hello {}", self.user.user.name)
       };
       command
           .create_interaction_response(&ctx.http, |response| {
               response
                   .kind(InteractionResponseType::ChannelMessageWithSource)
                   .interaction_response_data(|message| message.content(greeting))
           })
           .await
           .map_err(|_| InvocationError)
   }
}

// 3. Add the command to an enum that implements the Commands trait, representing all the
// commands for the bot
#[derive(Debug, Commands)]
enum BotCommands {
    Hello(HelloCommand),
}

// 4. Add the basic code to register the command via a macro and handle interactions
struct Handler;

#[async_trait]
impl EventHandler for Handler {
    async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
        match interaction {
            Interaction::ApplicationCommand(command_interaction) => {
                BotCommands::parse(&ctx, &command_interaction)
                    .expect("Failed to parse command")
                    .invoke(&ctx, &command_interaction)
                    .await
                    .expect("Failed to invoke command");
            }
            _ => (),
        }
    }

    async fn ready(&self, ctx: Context, ready: Ready) {
        register_commands!(&ctx, None, [HelloCommand])
            .expect("Unable to register commands");
    }
}

#[tokio::main]
async fn main() {
    let token = std::env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
    let application_id = std::env::var("DISCORD_USER_ID")
        .expect("Expected a user id in the environment")
        .parse::<u64>()
        .expect("Invalid user id");
    let mut client = Client::builder(&token, GatewayIntents::empty())
        .event_handler(Handler)
        .application_id(application_id)
        .await
        .expect("Err creating client");

    if let Err(why) = client.start().await {
        println!("Client error: {:?}", why);
    }
}

依赖项

~19–33MB
~615K SLoC