fishy/src/main.rs

152 lines
4.2 KiB
Rust

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(())
}