diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..349c6d4 --- /dev/null +++ b/.env.sample @@ -0,0 +1,2 @@ +BOT_TOKEN= +SERVER_ID= \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9f97022..603e19d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -target/ \ No newline at end of file +target/ +.env + +.idea/ \ No newline at end of file diff --git a/README.md b/README.md index b72b810..f7c23c1 100644 --- a/README.md +++ b/README.md @@ -15,5 +15,7 @@ A Discord bot for the best Discord community out there, TriDev. Vertex comes jam 3. Create a new bot user 4. Generate the invite link. 5. Add the bot to your server with the link. -6. Use the bot token as an environment variable `BOT_TOKEN` to start the app +6. Use the bot token as an environment variable `BOT_TOKEN` to start the app. + * Create a copy of `.env.sample` and name it `.env`. In this file, you can set `BOT_TOKEN` or other + environment variables you may want to set. 7. Start the bot, profit! diff --git a/src/main.rs b/src/main.rs index 08df917..6c931bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ use discord::Discord; use clap::Parser; +use discord::model::{Event, ServerId}; use dotenv::dotenv; +use std::str::FromStr; +use std::{u64}; extern crate discord; @@ -13,7 +16,12 @@ const BOT_TOKEN_LENGTH: usize = 72; pub struct Config { /// Your bot token you got from Discord Developer portal. #[arg(short, long, env("BOT_TOKEN"))] - pub bot_token: String + pub bot_token: String, + + /// Your Discord Server ID that you want to interact with + /// TODO: This will probably change if/when this bot becomes more generic. + #[arg(short, long, env("SERVER_ID"))] + pub server_id: String, } impl Config { @@ -21,6 +29,14 @@ impl Config { dotenv().ok(); Self::parse() } + + /// Creates a new `Config` instance with default values. + pub fn new(bot_token: String, server_id: String) -> Self { + Self { + bot_token, + server_id, + } + } } fn get_discord(bot_token: &str) -> Discord { @@ -28,20 +44,57 @@ fn get_discord(bot_token: &str) -> Discord { panic!("invalid bot token"); } - return match Discord::from_bot_token(bot_token) { - Ok(discord) => discord, - Err(err) => panic!("error happened: {}", err) + return Discord::from_bot_token(bot_token).expect("Expected token"); +} + +fn bot_loop(discord: Discord) { + let (mut connection, _) = discord.connect().expect("connect failed"); + println!("Ready."); + + loop { + match connection.recv_event() { + Ok(Event::MessageCreate(message)) => { + println!("{} says: {}", message.author.name, message.content); + if message.content == "!test" { + let _ = discord.send_message( + message.channel_id, + "This is a reply to the test.", + "", + false, + ); + } else if message.content == "!quit" { + println!("Quitting."); + break; + } + } + Ok(_) => {} + Err(discord::Error::Closed(code, body)) => { + println!("Gateway closed on us with code {:?}: {}", code, body); + break; + } + Err(err) => println!("Receive error: {:?}", err), + } } } +/// Extracts the server id from the config +fn get_server_id(config: Config) -> u64 { + let num = u64::from_str(config.server_id.as_str()).unwrap(); + return num; +} + fn main() { let cfg = Config::from_env_and_args(); let discord = get_discord(cfg.bot_token.as_str()); + let server_id = ServerId(self::get_server_id(cfg)); + let server = discord.get_server(server_id).unwrap(); + println!("Connected to {}!", server.name); + bot_loop(discord); } #[cfg(test)] mod tests { - use crate::get_discord; + use crate::{Config, get_discord, get_server_id}; #[test] #[should_panic] @@ -54,4 +107,11 @@ mod tests { // Our only validation rule right now is length get_discord("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); } + + #[test] + fn test_get_server_id() { + let config = Config::new("123".to_string(), "456".to_string()); + let expected_result = 456; + assert_eq!(expected_result, get_server_id(config)); + } }