use regex::Regex; use serenity::async_trait; use serenity::client::Client; use serenity::framework::standard::{ macros::{command, group}, CommandResult, StandardFramework, }; use serenity::model::channel::Message; use serenity::prelude::{Context, EventHandler, TypeMapKey}; use sqlx::sqlite::SqlitePool; use std::env; struct Handler { ah_regex: Regex, best_doctor_regex: Regex, } impl Default for Handler { fn default() -> Self { Self { ah_regex: Regex::new(r"A+H{5,}").unwrap(), best_doctor_regex: Regex::new(r"[iI].*(?:best|genius) doc").unwrap(), } } } #[async_trait] impl EventHandler for Handler { async fn message(&self, ctx: Context, message: Message) { let content = &message.content_safe(ctx.clone()).await; if self.ah_regex.is_match(content) { message .channel_id .say(ctx, "its ok ur gonna get a 6* someday") .await .unwrap(); } else if self.best_doctor_regex.is_match(content) { message .channel_id .say(ctx, "no, u is smol brain doctor...") .await .unwrap(); } } } struct DbConnPool { pool: sqlx::pool::Pool, } impl DbConnPool { async fn get_heck(&self) -> i32 { sqlx::query!("UPDATE Heck SET count = count + 1") .execute(&self.pool) .await .unwrap(); sqlx::query!("SELECT count FROM Heck") .fetch_one(&self.pool) .await .unwrap() .count } } impl TypeMapKey for DbConnPool { type Value = Self; } #[tokio::main] async fn main() -> Result<(), Box> { dotenv::dotenv().ok(); let framework = StandardFramework::new() .configure(|c| c.prefix("~")) .group(&GENERAL_GROUP); // Login with a bot token from the environment let mut client = Client::new_with_extras(&env::var("DISCORD_TOKEN").expect("token"), |extras| { extras .event_handler(Handler::default()) .framework(framework) }) .await .expect("Error creating client"); let pool = SqlitePool::builder() .build(&env::var("DATABASE_URL").unwrap()) .await?; init_pool(&pool).await; { let mut data = client.data.write().await; data.insert::(DbConnPool { pool }); } // start listening for events by starting a single shard if let Err(why) = client.start().await { println!("An error occurred while running the client: {:?}", why); } Ok(()) } async fn init_pool(pool: &sqlx::pool::Pool) { sqlx::query!( "CREATE TABLE IF NOT EXISTS Heck (id INTEGER PRIMARY KEY NOT NULL, count INTEGER NOT NULL)" ) .execute(pool) .await .unwrap(); if sqlx::query!("SELECT count FROM Heck") .fetch_all(pool) .await .unwrap() .is_empty() { sqlx::query!("INSERT INTO Heck VALUES (1, 0)") .execute(pool) .await .unwrap(); } } #[group] #[commands(heck)] struct General; #[command] async fn heck(ctx: &mut Context, msg: &Message) -> CommandResult { let db_pool = ctx.data.clone(); let mut db_pool = db_pool.write().await; let db_pool = db_pool.get_mut::().unwrap(); let value = db_pool.get_heck().await; msg.channel_id .say(ctx, format!("This command has been hecked {} times", value)) .await?; Ok(()) }