Skip to content

Commit 69bf639

Browse files
author
Kamran Mackey
committed
Added per-server prefix support.
Signed-off-by: Kamran Mackey <[email protected]>
1 parent afeee0e commit 69bf639

File tree

8 files changed

+199
-9
lines changed

8 files changed

+199
-9
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/target
2-
.env
2+
.env
3+
*.sqlite3

Cargo.lock

Lines changed: 52 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ellie"
3-
version = "0.1.9"
3+
version = "0.2.0"
44
authors = ["Kamran Mackey <[email protected]>"]
55
publish = false
66
build = "build.rs"
@@ -22,6 +22,7 @@ lastfm-rs = { git = "https://github.com/KamranMackey/lastfm-rs" }
2222
log = "0.4"
2323
pretty_env_logger = "0.3"
2424
reqwest = "0.10"
25+
rusqlite = { git = "https://github.com/KamranMackey/rusqlite", features = ["bundled"] }
2526
rspotify = { git = "https://github.com/KamranMackey/rspotify" }
2627
serenity = { git = "https://github.com/serenity-rs/serenity.git", branch = "current" }
2728
serde = "1.0"

src/commands/utils/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub mod help;
22
pub mod ping;
3+
pub mod prefix;
34
pub mod version;

src/commands/utils/prefix.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use crate::utilities::database;
2+
use crate::utilities::database::get_database;
3+
4+
use serenity::framework::standard::macros::command;
5+
use serenity::framework::standard::Args;
6+
use serenity::framework::standard::CommandError;
7+
use serenity::framework::standard::CommandResult;
8+
use serenity::model::prelude::Message;
9+
use serenity::prelude::Context;
10+
11+
#[command]
12+
#[description("Get or set the command prefix for the current server."
13+
)]
14+
#[sub_commands(get, set)]
15+
fn prefix(ctx: &mut Context, message: &Message) -> CommandResult {
16+
message
17+
.channel_id
18+
.send_message(&ctx, move |m| {
19+
m.embed(move |e| {
20+
e.title("Error: Invalid / No Subcommand Entered!");
21+
e.description("Please use subcommand get or set to use this command.");
22+
e
23+
})
24+
})
25+
.map_or_else(|e| Err(CommandError(e.to_string())), |_| Ok(()))
26+
}
27+
28+
#[command]
29+
#[only_in(guilds)]
30+
#[owners_only]
31+
#[description = "Retrieves the command prefix for the current server."]
32+
pub fn get(ctx: &mut Context, message: &Message) -> CommandResult {
33+
let prefix = database::get_prefix(&message.guild_id.unwrap()).unwrap().to_string();
34+
let guild = message.guild(&ctx.cache).unwrap();
35+
let guild_name = &guild.read().name;
36+
37+
return message
38+
.channel_id
39+
.say(&ctx.http, format!("The currently set command prefix for {} is {}.", guild_name, prefix))
40+
.map_or_else(|e| Err(CommandError(e.to_string())), |_| Ok(()));
41+
}
42+
43+
#[command]
44+
#[only_in(guilds)]
45+
#[owners_only]
46+
#[num_args(1)]
47+
#[description = "Sets the command prefix for the current server."]
48+
pub fn set(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
49+
let connection = match get_database() {
50+
Ok(connection) => connection,
51+
Err(_) => return Ok(()),
52+
};
53+
54+
let prefix = args.current().unwrap_or(";");
55+
let guild = message.guild(&ctx.cache).unwrap();
56+
let guild_id = guild.read().clone().id.as_u64().to_string();
57+
let guild_name = guild.read().clone().name;
58+
59+
let _ = connection.execute(
60+
"INSERT OR REPLACE INTO guild_settings (guild_id, guild_name, prefix) values (?1, ?2, ?3)",
61+
&[&guild_id, &guild_name, prefix],
62+
);
63+
64+
let _ = message
65+
.channel_id
66+
.say(&ctx.http, format!("The command prefix for {} has been set to {}.", guild_name, prefix));
67+
68+
Ok(())
69+
}

src/main.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Ellie is a bot for the Discord chat platform focused on giving users
44
//! a powerful set of features, while remaining quick to respond.
55
6-
pub mod utilities;
6+
mod utilities;
77
mod commands;
88
mod listeners;
99

@@ -12,6 +12,7 @@ use commands::info::user::*;
1212
use commands::music::lastfm::*;
1313
use commands::music::spotify::commands::spotify::*;
1414
use commands::utils::help::*;
15+
use commands::utils::prefix::*;
1516
use commands::utils::ping::*;
1617
use commands::utils::version::*;
1718

@@ -21,25 +22,28 @@ use log::error;
2122

2223
use listeners::handler::Handler;
2324

25+
use rspotify::spotify::client::Spotify;
26+
use rspotify::spotify::oauth2::SpotifyClientCredentials;
27+
2428
use serenity::client::Client;
2529
use serenity::framework::standard::macros::group;
2630
use serenity::framework::StandardFramework;
2731
use serenity::framework::standard::DispatchError;
2832

29-
use rspotify::spotify::client::Spotify;
30-
use rspotify::spotify::oauth2::SpotifyClientCredentials;
31-
3233
use std::collections::HashSet;
3334
use std::env;
3435

36+
use utilities::database::create_database;
37+
use utilities::database::get_prefix;
38+
3539
#[group]
3640
#[description = "Various informational commands."]
3741
#[commands(user, guild)]
3842
struct Information;
3943

4044
#[group]
4145
#[description = "Ellie's selection of utility commands."]
42-
#[commands(ping, version)]
46+
#[commands(ping, prefix, version)]
4347
struct Utilities;
4448

4549
#[group]
@@ -50,8 +54,9 @@ struct Music;
5054
pub fn main() {
5155
dotenv().expect("Unable to read / access the .env file!");
5256

57+
create_database();
58+
5359
let token: String = env::var("DISCORD_TOKEN").expect("Unable to read the bot token.");
54-
let prefix: String = env::var("DISCORD_PREFIX").expect("Unable to get the bot prefix.");
5560

5661
let mut client: Client = Client::new(&token, Handler).expect("Error creating client.");
5762

@@ -70,10 +75,21 @@ pub fn main() {
7075
StandardFramework::new()
7176
.configure(|c| {
7277
c.with_whitespace(true)
73-
.prefix(&prefix)
7478
.ignore_webhooks(false)
7579
.case_insensitivity(true)
7680
.owners(owners)
81+
.dynamic_prefix(|_, message| {
82+
let def_prefix: String = env::var("DISCORD_PREFIX").expect("Unable to get the bot prefix.");
83+
if message.is_private() {
84+
return Some(def_prefix.clone().to_string());
85+
}
86+
if let Some(guild_id) = message.guild_id {
87+
let prefix = get_prefix(&guild_id).map_or_else(|_| def_prefix.clone().to_string(), |prefix| prefix);
88+
return Some(prefix);
89+
} else {
90+
return Some(def_prefix.to_string())
91+
}
92+
})
7793
.on_mention(Some(bot_id))
7894
})
7995
.on_dispatch_error(|ctx, msg, err| match err {

src/utilities/database.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use log::error;
2+
3+
use rusqlite::Connection;
4+
use rusqlite::NO_PARAMS;
5+
6+
use serenity::model::prelude::GuildId;
7+
8+
use std::error::Error;
9+
use std::fs::File;
10+
use std::path::Path;
11+
12+
pub fn create_database() {
13+
let database = Path::new("database.sqlite3");
14+
if !database.exists() {
15+
match File::create(&database) {
16+
Ok(_) => (),
17+
Err(e) => error!("Failed to create database file: {}", e),
18+
}
19+
}
20+
if let Ok(connection) = Connection::open(&database) {
21+
match connection.execute(
22+
"CREATE TABLE IF NOT EXISTS guild_settings (
23+
guild_id TEXT PRIMARY KEY,
24+
guild_name TEXT NOT NULL,
25+
prefix TEXT NOT NULL
26+
);",
27+
NO_PARAMS,
28+
) {
29+
Ok(_) => (),
30+
Err(e) => {
31+
error!("{}", e);
32+
}
33+
}
34+
} else {
35+
error!("Could not open connection to database ({})", &database.to_string_lossy());
36+
}
37+
}
38+
39+
pub fn get_database() -> Result<Connection, Box<dyn Error>> {
40+
let db = Path::new("database.sqlite3");
41+
Ok(Connection::open(db)?)
42+
}
43+
44+
pub fn get_prefix(guildid: &GuildId) -> Result<String, Box<dyn Error>> {
45+
let conn = get_database()?;
46+
let mut statement = conn.prepare("SELECT prefix FROM guild_settings WHERE guild_id == ?1;")?;
47+
let mut rows = statement.query(&[&guildid.as_u64().to_string()])?;
48+
Ok(rows.next()?.ok_or("Guild not found.")?.get(0)?)
49+
}

src/utilities/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod built_info;
2+
pub mod database;
23
pub mod git_utils;
34

45
pub fn format_int(i: isize) -> String {

0 commit comments

Comments
 (0)