Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connects to Server, Reads Messages #10

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BOT_TOKEN=<YOUR_BOT_TOKEN>
SERVER_ID=<YOUR_SERVER_ID>
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
target/
target/
.env

.idea/
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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!
70 changes: 65 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -13,35 +16,85 @@ 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 {
pub fn from_env_and_args() -> Self {
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 {
if bot_token.len() < BOT_TOKEN_LENGTH {
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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we bring in a logging library here?

I'd prefer a structured logging approach that we can hook into various tracing/aggregation tools

if message.content == "!test" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np: I'd prefer a constant for these values

// At the top of file
static TEST_CMD: &str = "!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;
}
Comment on lines +81 to +84
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is pretty small, maybe just do this in main until we have more config values to extract?


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));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you add the function so that you could wrap the return with ServerId?

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]
Expand All @@ -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));
}
}