use serenity::client::Client; use serenity::framework::standard::{ StandardFramework, CommandResult, macros::{ command, group } }; use rusqlite::ToSql; use rusqlite::{Connection, NO_PARAMS}; group!({ name: "general", options: {}, commands: [hello, add], }); use std::env; use serenity::{ model::{channel::Message, gateway::Ready}, prelude::*, }; #[derive(Debug)] struct Question { // structure for questions id: i32, question: String, } struct Base { connection: Connection, } struct Handler; 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. 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!") { println!("Error sending message: {:?}", why); } } } // 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. fn ready(&self, _: Context, ready: Ready) { println!("{} is connected!", ready.user.name); } } fn main() { // get token from args let args: Vec<_> = env::args().collect(); if args.len() < 3 && args[1] != "create" { println!("Please enter a database and token"); std::process::exit(0); } if args[1] == "create" { println!("Creating table...\n\n"); println!("Connecting to database"); let base_path = &args[2]; let base = Base { connection: Connection::open(&base_path).expect("Failed to open in memory..."), }; base.connection.execute( "CREATE TABLE question ( id INTEGER PRIMARY KEY, question TEXT NOT NULL )", NO_PARAMS, ).expect("Failed to create table..."); println!("Done!"); std::process::exit(0); } let token = &args[2]; let mut client = Client::new(token, Handler) .expect("Error creating client"); client.with_framework(StandardFramework::new() .configure(|c| c.prefix("fishy ")) // set the bot's prefix .group(&GENERAL_GROUP)); println!("Starting client..."); // start listening for events by starting a single shard if let Err(why) = client.start() { println!("An error occurred while running the client: {:?}", why); } } #[command] fn hello(ctx: &mut Context, msg: &Message) -> CommandResult { println!("Executing command HELLO as \"{}\"", msg.content); msg.reply(ctx, "Hello!")?; Ok(()) } #[command] fn add(ctx: &mut Context, msg: &Message) -> CommandResult { println!("Executing command ADD as \"{}\"", msg.content); let split: Vec<&str> = msg.content.split(" ").collect(); if split.len() < 3 { msg.reply(ctx, "Please add a message!")?; return Ok(()); } let addition = format!("{}", &split[2..].join(" ")); let new = Question { id: 0, question: addition, }; let args: Vec<_> = env::args().collect(); let base_path = &args[1]; let base = Base { connection: Connection::open(&base_path).expect("Failed to open database..."), }; println!("\tOpened connection"); print!("\tExecuting insert..."); base.connection.execute( "INSERT INTO question VALUES (?1, ?2)", &[&new.id, &new.question as &ToSql], ).expect("Failed to insert values..."); println!("OK"); msg.reply(ctx, "Added question!")?; Ok(()) }