mirror of
https://github.com/Noratrieb/discord-court-bot.git
synced 2026-01-14 18:05:02 +01:00
handle handlers
This commit is contained in:
parent
9014ff6eff
commit
724d7467c3
7 changed files with 350 additions and 208 deletions
73
Cargo.lock
generated
73
Cargo.lock
generated
|
|
@ -164,7 +164,6 @@ dependencies = [
|
|||
"libc",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"time 0.1.44",
|
||||
"winapi",
|
||||
]
|
||||
|
|
@ -196,17 +195,6 @@ dependencies = [
|
|||
"tracing-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "command_attr"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8862b532587a5efe6f20a750a0d01f390111f3570870581c13374024affc46dc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "court-bot"
|
||||
version = "0.1.0"
|
||||
|
|
@ -214,6 +202,7 @@ dependencies = [
|
|||
"color-eyre",
|
||||
"dotenv",
|
||||
"mongodb",
|
||||
"serde",
|
||||
"serenity",
|
||||
"tokio",
|
||||
"tracing",
|
||||
|
|
@ -717,12 +706,6 @@ version = "1.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "levenshtein"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
|
|
@ -769,6 +752,15 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||
dependencies = [
|
||||
"regex-automata",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
|
|
@ -1070,6 +1062,30 @@ dependencies = [
|
|||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.11"
|
||||
|
|
@ -1325,12 +1341,9 @@ dependencies = [
|
|||
"bitflags",
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"chrono",
|
||||
"command_attr",
|
||||
"dashmap",
|
||||
"flate2",
|
||||
"futures",
|
||||
"levenshtein",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"parking_lot",
|
||||
|
|
@ -1339,13 +1352,11 @@ dependencies = [
|
|||
"serde",
|
||||
"serde-value",
|
||||
"serde_json",
|
||||
"static_assertions",
|
||||
"time 0.3.9",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"typemap_rev",
|
||||
"url",
|
||||
"uwl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1416,12 +1427,6 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.2"
|
||||
|
|
@ -1659,9 +1664,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"lazy_static",
|
||||
"matchers",
|
||||
"regex",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
|
@ -1826,12 +1835,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uwl"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4bf03e0ca70d626ecc4ba6b0763b934b6f2976e8c744088bb3c1d646fbb1ad0"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,12 @@ edition = "2021"
|
|||
color-eyre = "0.6.1"
|
||||
dotenv = "0.15.0"
|
||||
mongodb = "2.2.2"
|
||||
serenity = { version = "0.11.2", features = ["collector"] }
|
||||
tokio = { version = "1.19.2", features = ["full"] }
|
||||
tracing = "0.1.35"
|
||||
tracing-subscriber = "0.3.11"
|
||||
tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
|
||||
serde = { version = "1.0.137", features = ["derive"] }
|
||||
|
||||
[dependencies.serenity]
|
||||
version = "0.11.2"
|
||||
default-features = false
|
||||
features = ["builder", "cache", "client", "gateway", "collector", "http", "rustls_backend", "tokio", "typemap_rev", "utils"]
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ DISCORD_TOKEN=token
|
|||
APPLICATION_ID=uwu
|
||||
RUST_LOG=DEBUG
|
||||
MONGO_URI=mongodb://localhost:27017
|
||||
DB_NAME=court_bot
|
||||
MONGO_INITDB_ROOT_USERNAME=root
|
||||
MONGO_INITDB_ROOT_PASSWORD=uwu
|
||||
DEV=
|
||||
# SET_GLOBAL=
|
||||
```
|
||||
|
||||
run mongodb
|
||||
|
|
|
|||
361
src/handler.rs
361
src/handler.rs
|
|
@ -1,185 +1,230 @@
|
|||
use serenity::{async_trait, framework::standard::Command, model::prelude::*, prelude::*};
|
||||
use tracing::debug;
|
||||
use color_eyre::eyre::{eyre, ContextCompat};
|
||||
use serenity::{
|
||||
async_trait,
|
||||
builder::CreateApplicationCommands,
|
||||
model::{
|
||||
interactions::application_command::ApplicationCommandOptionType,
|
||||
prelude::{application_command::*, *},
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
use crate::{
|
||||
lawsuit::{Lawsuit, LawsuitState},
|
||||
WrapErr,
|
||||
};
|
||||
|
||||
fn slash_commands(commands: &mut CreateApplicationCommands) -> &mut CreateApplicationCommands {
|
||||
commands.create_application_command(|command| {
|
||||
command
|
||||
.name("lawsuit")
|
||||
.description("Einen Gerichtsprozess starten")
|
||||
.create_option(|option| {
|
||||
option
|
||||
.name("create")
|
||||
.description("Einen neuen Gerichtsprozess anfangen")
|
||||
.kind(ApplicationCommandOptionType::SubCommand)
|
||||
.create_sub_option(|option| {
|
||||
option
|
||||
.name("plaintiff")
|
||||
.description("Der Kläger")
|
||||
.kind(ApplicationCommandOptionType::User)
|
||||
.required(true)
|
||||
})
|
||||
.create_sub_option(|option| {
|
||||
option
|
||||
.name("accused")
|
||||
.description("Der Angeklagte")
|
||||
.kind(ApplicationCommandOptionType::User)
|
||||
.required(true)
|
||||
})
|
||||
.create_sub_option(|option| {
|
||||
option
|
||||
.name("reason")
|
||||
.description("Der Grund für die Klage")
|
||||
.kind(ApplicationCommandOptionType::String)
|
||||
.required(true)
|
||||
})
|
||||
.create_sub_option(|option| {
|
||||
option
|
||||
.name("plaintiff_lawyer")
|
||||
.description("Der Anwalt des Klägers")
|
||||
.kind(ApplicationCommandOptionType::User)
|
||||
.required(false)
|
||||
})
|
||||
.create_sub_option(|option| {
|
||||
option
|
||||
.name("accused_lawyer")
|
||||
.description("Der Anwalt des Angeklagten")
|
||||
.kind(ApplicationCommandOptionType::User)
|
||||
.required(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub struct Handler {
|
||||
pub dev_guild_id: Option<GuildId>,
|
||||
pub set_global_commands: bool,
|
||||
pub mongo: Mongo,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn ready(&self, ctx: Context, ready: Ready) {
|
||||
println!("{} is connected!", ready.user.name);
|
||||
info!(name = %ready.user.name, "Bot is connected!");
|
||||
|
||||
if let Some(guild_id) = self.dev_guild_id {
|
||||
let commands = GuildId::set_application_commands(&guild_id, &ctx.http, |commands| {
|
||||
commands
|
||||
.create_application_command(|command| {
|
||||
command.name("ping").description("A ping command")
|
||||
})
|
||||
.create_application_command(|command| {
|
||||
command.name("id").description("Get a user id").create_option(|option| {
|
||||
option
|
||||
.name("id")
|
||||
.description("The user to lookup")
|
||||
.kind(CommandOptionType::User)
|
||||
.required(true)
|
||||
})
|
||||
})
|
||||
.create_application_command(|command| {
|
||||
command
|
||||
.name("welcome")
|
||||
.name_localized("de", "begrüßen")
|
||||
.description("Welcome a user")
|
||||
.description_localized("de", "Einen Nutzer begrüßen")
|
||||
.create_option(|option| {
|
||||
option
|
||||
.name("user")
|
||||
.name_localized("de", "nutzer")
|
||||
.description("The user to welcome")
|
||||
.description_localized("de", "Der zu begrüßende Nutzer")
|
||||
.kind(CommandOptionType::User)
|
||||
.required(true)
|
||||
})
|
||||
.create_option(|option| {
|
||||
option
|
||||
.name("message")
|
||||
.name_localized("de", "nachricht")
|
||||
.description("The message to send")
|
||||
.description_localized("de", "Die versendete Nachricht")
|
||||
.kind(CommandOptionType::String)
|
||||
.required(true)
|
||||
.add_string_choice_localized(
|
||||
"Welcome to our cool server! Ask me if you need help",
|
||||
"pizza",
|
||||
[("de", "Willkommen auf unserem coolen Server! Frag mich, falls du Hilfe brauchst")]
|
||||
)
|
||||
.add_string_choice_localized(
|
||||
"Hey, do you want a coffee?",
|
||||
"coffee",
|
||||
[("de", "Hey, willst du einen Kaffee?")],
|
||||
)
|
||||
.add_string_choice_localized(
|
||||
"Welcome to the club, you're now a good person. Well, I hope.",
|
||||
"club",
|
||||
[("de", "Willkommen im Club, du bist jetzt ein guter Mensch. Naja, hoffentlich.")],
|
||||
)
|
||||
.add_string_choice_localized(
|
||||
"I hope that you brought a controller to play together!",
|
||||
"game",
|
||||
[("de", "Ich hoffe du hast einen Controller zum Spielen mitgebracht!")],
|
||||
)
|
||||
})
|
||||
})
|
||||
.create_application_command(|command| {
|
||||
command
|
||||
.name("numberinput")
|
||||
.description("Test command for number input")
|
||||
.create_option(|option| {
|
||||
option
|
||||
.name("int")
|
||||
.description("An integer from 5 to 10")
|
||||
.kind(CommandOptionType::Integer)
|
||||
.min_int_value(5)
|
||||
.max_int_value(10)
|
||||
.required(true)
|
||||
})
|
||||
.create_option(|option| {
|
||||
option
|
||||
.name("number")
|
||||
.description("A float from -3.3 to 234.5")
|
||||
.kind(CommandOptionType::Number)
|
||||
.min_number_value(-3.3)
|
||||
.max_number_value(234.5)
|
||||
.required(true)
|
||||
})
|
||||
})
|
||||
.create_application_command(|command| {
|
||||
command
|
||||
.name("attachmentinput")
|
||||
.description("Test command for attachment input")
|
||||
.create_option(|option| {
|
||||
option
|
||||
.name("attachment")
|
||||
.description("A file")
|
||||
.kind(CommandOptionType::Attachment)
|
||||
.required(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
.await;
|
||||
let guild_commands =
|
||||
GuildId::set_application_commands(&guild_id, &ctx.http, slash_commands).await;
|
||||
|
||||
debug!(?commands, "I now have the following guild slash commands",);
|
||||
match guild_commands {
|
||||
Ok(_) => info!("Installed guild slash commands"),
|
||||
Err(error) => error!(?error, "Failed to create global commands"),
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
let guild_command = Command::create_global_application_command(&ctx.http, |command| {
|
||||
command
|
||||
.name("wonderful_command")
|
||||
.description("An amazing command")
|
||||
})
|
||||
.await;
|
||||
*/
|
||||
|
||||
println!(
|
||||
"I created the following global slash command: {:#?}",
|
||||
guild_command
|
||||
);
|
||||
if self.set_global_commands {
|
||||
todo!()
|
||||
// let guild_commands =
|
||||
// ApplicationCommand::create_global_application_command(&ctx.http, slash_commands)
|
||||
// .await;
|
||||
// match guild_commands {
|
||||
// Ok(commands) => info!(?commands, "Created global commands"),
|
||||
// Err(error) => error!(?error, "Failed to create global commands"),
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
||||
if let Interaction::ApplicationCommand(command) = interaction {
|
||||
println!("Received command interaction: {:#?}", command);
|
||||
debug!(name = %command.data.name, "Received command interaction");
|
||||
|
||||
let content = match command.data.name.as_str() {
|
||||
"ping" => "Hey, I'm alive!".to_string(),
|
||||
"id" => {
|
||||
let options = command
|
||||
.data
|
||||
.options
|
||||
.get(0)
|
||||
.expect("Expected user option")
|
||||
.resolved
|
||||
.as_ref()
|
||||
.expect("Expected user object");
|
||||
|
||||
if let CommandDataOptionValue::User(user, _member) = options {
|
||||
format!("{}'s id is {}", user.tag(), user.id)
|
||||
} else {
|
||||
"Please provide a valid user".to_string()
|
||||
}
|
||||
}
|
||||
"attachmentinput" => {
|
||||
let options = command
|
||||
.data
|
||||
.options
|
||||
.get(0)
|
||||
.expect("Expected attachment option")
|
||||
.resolved
|
||||
.as_ref()
|
||||
.expect("Expected attachment object");
|
||||
|
||||
if let CommandDataOptionValue::Attachment(attachment) = options {
|
||||
format!(
|
||||
"Attachment name: {}, attachment size: {}",
|
||||
attachment.filename, attachment.size
|
||||
)
|
||||
} else {
|
||||
"Please provide a valid attachment".to_string()
|
||||
}
|
||||
}
|
||||
_ => "not implemented :(".to_string(),
|
||||
};
|
||||
|
||||
if let Err(why) = command
|
||||
let result = match command.data.name.as_str() {
|
||||
"lawsuit" => {
|
||||
let result = lawsuit_command_handler(&command).await;
|
||||
if let Err(err) = result {
|
||||
error!(?err, "Error processing response");
|
||||
command
|
||||
.create_interaction_response(&ctx.http, |response| {
|
||||
response
|
||||
.kind(InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|message| message.content(content))
|
||||
.interaction_response_data(|message| {
|
||||
message.content("An error occurred")
|
||||
})
|
||||
})
|
||||
.await
|
||||
{
|
||||
println!("Cannot respond to slash command: {}", why);
|
||||
.wrap_err("error response")
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
_ => command
|
||||
.create_interaction_response(&ctx.http, |response| {
|
||||
response
|
||||
.kind(InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|message| {
|
||||
message.content("not implemented :(")
|
||||
})
|
||||
})
|
||||
.await
|
||||
.wrap_err("not implemented response"),
|
||||
};
|
||||
if let Err(err) = result {
|
||||
error!(?err, "Error sending response");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn lawsuit_command_handler(
|
||||
command: &ApplicationCommandInteraction,
|
||||
) -> color_eyre::Result<()> {
|
||||
let options = &command.data.options;
|
||||
let subcomamnd = options.get(0).wrap_err("needs subcommand")?;
|
||||
|
||||
match subcomamnd.name.as_str() {
|
||||
"create" => {
|
||||
let options = &subcomamnd.options;
|
||||
let plaintiff = get_user(options.get(0)).wrap_err("plaintiff")?;
|
||||
let accused = get_user(options.get(1)).wrap_err("accused")?;
|
||||
let reason = get_string(options.get(2)).wrap_err("reason")?;
|
||||
let plaintiff_layer = get_user_optional(options.get(3)).wrap_err("plaintiff_layer")?;
|
||||
let accused_layer = get_user_optional(options.get(4)).wrap_err("accused_layer")?;
|
||||
|
||||
let lawsuit = Lawsuit {
|
||||
plaintiff: plaintiff.0.id,
|
||||
accused: accused.0.id,
|
||||
plaintiff_layer: plaintiff_layer.map(|l| l.0.id),
|
||||
accused_layer: accused_layer.map(|l| l.0.id),
|
||||
reason: reason.to_owned(),
|
||||
state: LawsuitState::Initial,
|
||||
court_room: Default::default(),
|
||||
};
|
||||
|
||||
info!(?lawsuit, "Created lawsuit");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(eyre!("Unknown subcommand")),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_user(
|
||||
option: Option<&ApplicationCommandInteractionDataOption>,
|
||||
) -> color_eyre::Result<(&User, &Option<PartialMember>)> {
|
||||
let option = get_user_optional(option);
|
||||
match option {
|
||||
Ok(Some(t)) => Ok(t),
|
||||
Ok(None) => Err(eyre!("Expected value!")),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_user_optional(
|
||||
option: Option<&ApplicationCommandInteractionDataOption>,
|
||||
) -> color_eyre::Result<Option<(&User, &Option<PartialMember>)>> {
|
||||
if let Some(option) = option {
|
||||
if let Some(command) = option.resolved.as_ref() {
|
||||
if let ApplicationCommandInteractionDataOptionValue::User(user, member) = command {
|
||||
Ok(Some((user, member)))
|
||||
} else {
|
||||
Err(eyre!("Expected user!"))
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_string(
|
||||
option: Option<&ApplicationCommandInteractionDataOption>,
|
||||
) -> color_eyre::Result<&str> {
|
||||
let option = get_string_optional(option);
|
||||
match option {
|
||||
Ok(Some(t)) => Ok(t),
|
||||
Ok(None) => Err(eyre!("Expected value!")),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_string_optional(
|
||||
option: Option<&ApplicationCommandInteractionDataOption>,
|
||||
) -> color_eyre::Result<Option<&str>> {
|
||||
if let Some(option) = option {
|
||||
if let Some(command) = option.resolved.as_ref() {
|
||||
if let ApplicationCommandInteractionDataOptionValue::String(str) = command {
|
||||
Ok(Some(str))
|
||||
} else {
|
||||
Err(eyre!("Expected string!"))
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
src/lawsuit.rs
Normal file
20
src/lawsuit.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serenity::model::id::{ChannelId, UserId};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum LawsuitState {
|
||||
Initial,
|
||||
InProgress,
|
||||
Completed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Lawsuit {
|
||||
pub plaintiff: UserId,
|
||||
pub accused: UserId,
|
||||
pub plaintiff_layer: Option<UserId>,
|
||||
pub accused_layer: Option<UserId>,
|
||||
pub reason: String,
|
||||
pub state: LawsuitState,
|
||||
pub court_room: ChannelId,
|
||||
}
|
||||
38
src/main.rs
38
src/main.rs
|
|
@ -1,31 +1,55 @@
|
|||
mod handler;
|
||||
mod lawsuit;
|
||||
mod model;
|
||||
|
||||
use std::env;
|
||||
|
||||
use color_eyre::{eyre::WrapErr, Result};
|
||||
use serenity::{model::prelude::*, prelude::*};
|
||||
use tracing::info;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
use crate::handler::Handler;
|
||||
use crate::{handler::Handler, model::Mongo};
|
||||
|
||||
#[tokio::main]
|
||||
fn main() -> Result<()> {
|
||||
async fn main() -> Result<()> {
|
||||
color_eyre::install()?;
|
||||
|
||||
let _ = dotenv::dotenv();
|
||||
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.init();
|
||||
|
||||
info!("Starting up...");
|
||||
|
||||
let mongo_uri = env::var("MONGO_URI").wrap_err("MONGO_URI not found in the environment")?;
|
||||
let db_name = env::var("DB_NAME").unwrap_or_else(|_| "court-bot".to_string());
|
||||
|
||||
let mongo = Mongo::connect(&mongo_uri, &db_name).await?;
|
||||
|
||||
info!("Connected to mongodb");
|
||||
|
||||
let token = env::var("DISCORD_TOKEN").wrap_err("DISCORD_TOKEN not found in environment")?;
|
||||
let guild_id = if let Ok(_) = env::var("DEV") {
|
||||
SOme( GuildId(
|
||||
let dev_guild_id = if env::var("DEV").is_ok() {
|
||||
Some(GuildId(
|
||||
env::var("GUILD_ID")
|
||||
.wrap_err("GUILD_ID not found in environment, must be set when DEV is set")?
|
||||
.parse()
|
||||
.wrap_err("GUILD_ID must be an integer")?,
|
||||
))
|
||||
})
|
||||
} else {None};
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let set_global_commands = env::var("SET_GLOBAL").is_ok();
|
||||
|
||||
let mut client = Client::builder(token, GatewayIntents::empty())
|
||||
.event_handler(Handler { dev_guild_id })
|
||||
.event_handler(Handler {
|
||||
dev_guild_id,
|
||||
set_global_commands,
|
||||
mongo,
|
||||
})
|
||||
.await
|
||||
.wrap_err("failed to create discord client")?;
|
||||
|
||||
|
|
|
|||
43
src/model.rs
Normal file
43
src/model.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
use color_eyre::Result;
|
||||
use mongodb::{options::ClientOptions, Client, Database};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serenity::model::id::{ChannelId, GuildId};
|
||||
|
||||
use crate::{lawsuit::Lawsuit, WrapErr};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct State {
|
||||
pub guild_id: GuildId,
|
||||
pub lawsuits: Vec<Lawsuit>,
|
||||
pub justice_category: ChannelId,
|
||||
pub court_rooms: Vec<CourtRoom>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CourtRoom {
|
||||
pub channel_id: ChannelId,
|
||||
pub ongoing_lawsuit: bool,
|
||||
}
|
||||
|
||||
pub struct Mongo {
|
||||
client: Client,
|
||||
db: Database,
|
||||
}
|
||||
|
||||
impl Mongo {
|
||||
pub async fn connect(uri: &str, db_name: &str) -> Result<Self> {
|
||||
let mut client_options = ClientOptions::parse(uri)
|
||||
.await
|
||||
.wrap_err("failed to create client options")?;
|
||||
|
||||
client_options.app_name = Some("Discord Court Bot".to_owned());
|
||||
|
||||
let client = Client::with_options(client_options).wrap_err("failed to create client")?;
|
||||
|
||||
let db = client.database(db_name);
|
||||
|
||||
Ok(Self { client, db })
|
||||
}
|
||||
|
||||
pub fn insert_lawsuit(lawsuit: &Lawsuit) {}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue