From b976591e7adf9bf4c60e0dc7905a5af9edba4592 Mon Sep 17 00:00:00 2001 From: Joey Pollack Date: Wed, 5 Jul 2023 19:28:20 -0400 Subject: [PATCH] Switched to Serenity instead of poise --- Cargo.toml | 4 +- src/main.rs | 103 +++++++++++++++++++++++++--------------------------- 2 files changed, 52 insertions(+), 55 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 520786f..3292731 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,5 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -poise = "0.5.5" -tokio = { version = "1.21.1", features = ["full"] } \ No newline at end of file +serenity = { version = "0.11.6", default-features = false, features = ["client", "gateway", "rustls_backend", "model"] } +tokio = { version = "1.21.1", features = ["full"] } diff --git a/src/main.rs b/src/main.rs index 93af13a..38ce376 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,49 +1,45 @@ -use poise::serenity_prelude as serenity; mod commands; mod data_loader; -pub struct Data {} // User data, which is stored and accessible in all command invocations -type Error = Box; -type Context<'a> = poise::Context<'a, Data, Error>; +use serenity::async_trait; +use serenity::model::channel::Message; +use serenity::model::gateway::Ready; +use serenity::prelude::*; -/// Displays your or another user's account creation date -#[poise::command(slash_command, prefix_command)] -async fn age(ctx: Context<'_>, #[description = "Selected user"] user: Option) -> Result<(), Error> -{ - let u = user.as_ref().unwrap_or_else(|| ctx.author()); - let response = format!("{}'s account was created at {}", u.name, u.created_at()); - ctx.say(response).await?; - Ok(()) -} +struct Handler; -/// A command with two subcommands: `child1` and `child2` -/// -/// Running this function directly, without any subcommand, is only supported in prefix commands. -/// Discord doesn't permit invoking the root command of a slash command if it has subcommands. -#[poise::command(prefix_command, slash_command, subcommands("child1", "child2"))] -pub async fn parent(ctx: Context<'_>) -> Result<(), Error> -{ - ctx.say("Hello there!").await?; - Ok(()) -} +#[async_trait] +impl EventHandler for Handler { + // Set a handler for the `message` event - so that whenever a new message + // is received - the closure (or function) passed will be called. + // + // Event handlers are dispatched through a threadpool, and so multiple + // events can be dispatched simultaneously. + async fn message(&self, ctx: Context, msg: Message) { + if msg.content == "!ping" { + // Sending a message can fail, due to a network error, an + // authentication error, or lack of permissions to post in the + // channel, so log to stdout when some error happens, with a + // description of it. + if let Err(why) = msg.channel_id.say(&ctx.http, "Pong!").await { + println!("Error sending message: {:?}", why); + } + } + } -/// A subcommand of `parent` -#[poise::command(prefix_command, slash_command)] -pub async fn child1(ctx: Context<'_>) -> Result<(), Error> -{ - ctx.say("You invoked the first child command!").await?; - Ok(()) + // Set a handler to be called on the `ready` event. This is called when a + // shard is booted, and a READY payload is sent by Discord. This payload + // contains data like the current user's guild Ids, current user data, + // private channels, and more. + // + // In this case, just print what the current user's username is. + async fn ready(&self, _: Context, ready: Ready) { + println!("{} is connected!", ready.user.name); + } } -/// Another subcommand of `parent` -#[poise::command(prefix_command, slash_command)] -pub async fn child2(ctx: Context<'_>) -> Result<(), Error> -{ - ctx.say("You invoked the second child command!").await?; - Ok(()) -} #[tokio::main] async fn main() @@ -55,22 +51,23 @@ async fn main() }; println!("Connecting..."); - - let framework = poise::Framework::builder() - .options(poise::FrameworkOptions { - commands: vec![age(), parent()], - ..Default::default() - }) - .token(token) - .intents(serenity::GatewayIntents::non_privileged()) - .setup(|ctx, _ready, framework| - { - Box::pin(async move - { - poise::builtins::register_globally(ctx, &framework.options().commands).await?; - Ok(Data {}) - }) - }); - framework.run().await.unwrap(); + let intents = GatewayIntents::GUILD_MESSAGES + | GatewayIntents::DIRECT_MESSAGES + | GatewayIntents::MESSAGE_CONTENT; + + // Create a new instance of the Client, logging in as a bot. This will + // automatically prepend your bot token with "Bot ", which is a requirement + // by Discord for bot users. + let mut client = Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client"); + + // Finally, start a single shard, and start listening to events. + // + // Shards will automatically attempt to reconnect, and will perform + // exponential backoff until it reconnects. + if let Err(why) = client.start().await + { + println!("Client error: {:?}", why); + } + }