mirror of
https://github.com/Noratrieb/discord-court-bot.git
synced 2026-01-17 03:15:01 +01:00
save category
This commit is contained in:
parent
ac13fa1676
commit
9c6f958f68
3 changed files with 133 additions and 76 deletions
151
src/handler.rs
151
src/handler.rs
|
|
@ -2,7 +2,6 @@ use color_eyre::eyre::{eyre, ContextCompat};
|
||||||
use serenity::{
|
use serenity::{
|
||||||
async_trait,
|
async_trait,
|
||||||
builder::CreateApplicationCommands,
|
builder::CreateApplicationCommands,
|
||||||
http::Http,
|
|
||||||
model::{
|
model::{
|
||||||
interactions::application_command::ApplicationCommandOptionType,
|
interactions::application_command::ApplicationCommandOptionType,
|
||||||
prelude::{application_command::*, *},
|
prelude::{application_command::*, *},
|
||||||
|
|
@ -84,6 +83,10 @@ pub struct Handler {
|
||||||
pub mongo: Mongo,
|
pub mongo: Mongo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Response {
|
||||||
|
Simple(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl EventHandler for Handler {
|
impl EventHandler for Handler {
|
||||||
async fn ready(&self, ctx: Context, ready: Ready) {
|
async fn ready(&self, ctx: Context, ready: Ready) {
|
||||||
|
|
@ -113,56 +116,70 @@ impl EventHandler for Handler {
|
||||||
|
|
||||||
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
||||||
if let Interaction::ApplicationCommand(command) = interaction {
|
if let Interaction::ApplicationCommand(command) = interaction {
|
||||||
debug!(name = %command.data.name, "Received command interaction");
|
if let Err(err) = self.handle_interaction(ctx, command).await {
|
||||||
|
error!(?err, "An error occurred");
|
||||||
let result = match command.data.name.as_str() {
|
|
||||||
"lawsuit" => {
|
|
||||||
let result = lawsuit_command_handler(&command, &ctx.http, &self.mongo).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("An error occurred")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.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");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Handler {
|
||||||
|
async fn handle_interaction(
|
||||||
|
&self,
|
||||||
|
ctx: Context,
|
||||||
|
command: ApplicationCommandInteraction,
|
||||||
|
) -> color_eyre::Result<()> {
|
||||||
|
debug!(name = %command.data.name, "Received command interaction");
|
||||||
|
|
||||||
|
let response = match command.data.name.as_str() {
|
||||||
|
"lawsuit" => lawsuit_command_handler(&command, &ctx, &self.mongo).await,
|
||||||
|
_ => Ok(Response::Simple("not implemented :(".to_owned())),
|
||||||
|
};
|
||||||
|
|
||||||
|
match response {
|
||||||
|
Ok(response) => self.send_response(ctx, command, response).await,
|
||||||
|
Err(err) => {
|
||||||
|
error!(?err, "Error during command execution");
|
||||||
|
self.send_response(
|
||||||
|
ctx,
|
||||||
|
command,
|
||||||
|
Response::Simple("An internal error occurred".to_owned()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_response(
|
||||||
|
&self,
|
||||||
|
ctx: Context,
|
||||||
|
command: ApplicationCommandInteraction,
|
||||||
|
response: Response,
|
||||||
|
) -> color_eyre::Result<()> {
|
||||||
|
command
|
||||||
|
.create_interaction_response(&ctx.http, |res| match response {
|
||||||
|
Response::Simple(content) => res
|
||||||
|
.kind(InteractionResponseType::ChannelMessageWithSource)
|
||||||
|
.interaction_response_data(|message| message.content(content)),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.wrap_err("sending response")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn lawsuit_command_handler(
|
async fn lawsuit_command_handler(
|
||||||
command: &ApplicationCommandInteraction,
|
command: &ApplicationCommandInteraction,
|
||||||
http: impl AsRef<Http>,
|
ctx: &Context,
|
||||||
mongo_client: &Mongo,
|
mongo_client: &Mongo,
|
||||||
) -> color_eyre::Result<()> {
|
) -> color_eyre::Result<Response> {
|
||||||
let options = &command.data.options;
|
let options = &command.data.options;
|
||||||
let subcomamnd = options.get(0).wrap_err("needs subcommand")?;
|
let subcommand = options.get(0).wrap_err("needs subcommand")?;
|
||||||
|
|
||||||
match subcomamnd.name.as_str() {
|
let options = &subcommand.options;
|
||||||
|
let guild_id = command.guild_id.wrap_err("guild_id not found")?.to_string();
|
||||||
|
|
||||||
|
match subcommand.name.as_str() {
|
||||||
"create" => {
|
"create" => {
|
||||||
let options = &subcomamnd.options;
|
|
||||||
let plaintiff = UserOption::get(options.get(0)).wrap_err("plaintiff")?;
|
let plaintiff = UserOption::get(options.get(0)).wrap_err("plaintiff")?;
|
||||||
let accused = UserOption::get(options.get(1)).wrap_err("accused")?;
|
let accused = UserOption::get(options.get(1)).wrap_err("accused")?;
|
||||||
let reason = StringOption::get(options.get(2)).wrap_err("reason")?;
|
let reason = StringOption::get(options.get(2)).wrap_err("reason")?;
|
||||||
|
|
@ -182,27 +199,34 @@ async fn lawsuit_command_handler(
|
||||||
};
|
};
|
||||||
|
|
||||||
lawsuit
|
lawsuit
|
||||||
.initialize(
|
.initialize(&guild_id, mongo_client)
|
||||||
command.guild_id.wrap_err("guild_id not found")?.to_string(),
|
|
||||||
mongo_client,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.wrap_err("initialize lawsuit")?;
|
.wrap_err("initialize lawsuit")?;
|
||||||
|
|
||||||
info!(?lawsuit, "Created lawsuit");
|
info!(?lawsuit, "Created lawsuit");
|
||||||
|
|
||||||
command
|
Ok(Response::Simple("hani erstellt, keis problem".to_owned()))
|
||||||
.create_interaction_response(http, |res| {
|
}
|
||||||
res.kind(InteractionResponseType::ChannelMessageWithSource)
|
"set_category" => {
|
||||||
.interaction_response_data(|message| {
|
let channel = ChannelOption::get(options.get(0))?;
|
||||||
message.content("hani erstellt, keis problem")
|
|
||||||
})
|
let channel = channel
|
||||||
})
|
.id
|
||||||
.await
|
.to_channel(&ctx.http)
|
||||||
.wrap_err("success reponse")?;
|
.await
|
||||||
Ok(())
|
.wrap_err("fetch category for set_category")?;
|
||||||
|
match channel.category() {
|
||||||
|
Some(category) => {
|
||||||
|
let id = category.id;
|
||||||
|
mongo_client
|
||||||
|
.set_court_category(&guild_id, &id.to_string())
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
None => return Ok(Response::Simple("Das ist keine Kategorie!".to_owned())),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Response::Simple("isch gsetzt".to_owned()))
|
||||||
}
|
}
|
||||||
"set_category" => Ok(()),
|
|
||||||
_ => Err(eyre!("Unknown subcommand")),
|
_ => Err(eyre!("Unknown subcommand")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -273,3 +297,20 @@ impl GetOption for StringOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ChannelOption;
|
||||||
|
|
||||||
|
#[nougat::gat]
|
||||||
|
impl GetOption for ChannelOption {
|
||||||
|
type Get<'a> = &'a PartialChannel;
|
||||||
|
|
||||||
|
fn extract(
|
||||||
|
command: &ApplicationCommandInteractionDataOptionValue,
|
||||||
|
) -> crate::Result<Self::Get<'_>> {
|
||||||
|
if let ApplicationCommandInteractionDataOptionValue::Channel(channel) = command {
|
||||||
|
Ok(channel)
|
||||||
|
} else {
|
||||||
|
Err(eyre!("Expected string!"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serenity::model::id::{ChannelId, UserId};
|
use serenity::model::id::{ChannelId, UserId};
|
||||||
use tracing::info;
|
|
||||||
|
|
||||||
use crate::Mongo;
|
use crate::Mongo;
|
||||||
|
|
||||||
|
|
@ -24,16 +23,8 @@ pub struct Lawsuit {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lawsuit {
|
impl Lawsuit {
|
||||||
pub async fn initialize(&mut self, guild_id: String, mongo_client: &Mongo) -> Result<()> {
|
pub async fn initialize(&mut self, guild_id: &str, mongo_client: &Mongo) -> Result<()> {
|
||||||
let state = mongo_client.find_state(&guild_id).await?;
|
let _state = mongo_client.find_or_insert_state(&guild_id).await?;
|
||||||
|
|
||||||
let state = match state {
|
|
||||||
Some(state) => state,
|
|
||||||
None => {
|
|
||||||
info!(%guild_id, "No state found for guild, creating new state");
|
|
||||||
mongo_client.new_state(guild_id).await?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
45
src/model.rs
45
src/model.rs
|
|
@ -2,9 +2,10 @@ use color_eyre::Result;
|
||||||
use mongodb::{
|
use mongodb::{
|
||||||
bson::doc,
|
bson::doc,
|
||||||
options::{ClientOptions, Credential},
|
options::{ClientOptions, Credential},
|
||||||
Client, Database,
|
Client, Collection, Database,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
use crate::{lawsuit::Lawsuit, WrapErr};
|
use crate::{lawsuit::Lawsuit, WrapErr};
|
||||||
|
|
||||||
|
|
@ -12,7 +13,7 @@ use crate::{lawsuit::Lawsuit, WrapErr};
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub guild_id: String,
|
pub guild_id: String,
|
||||||
pub lawsuits: Vec<Lawsuit>,
|
pub lawsuits: Vec<Lawsuit>,
|
||||||
pub justice_category: Option<String>,
|
pub court_category: Option<String>,
|
||||||
pub court_rooms: Vec<CourtRoom>,
|
pub court_rooms: Vec<CourtRoom>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,13 +51,21 @@ impl Mongo {
|
||||||
Ok(Self { db })
|
Ok(Self { db })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn find_state(&self, guild_id: &str) -> Result<Option<State>> {
|
pub async fn find_or_insert_state(&self, guild_id: &str) -> Result<State> {
|
||||||
let collection = self.db.collection("state");
|
let coll = self.state_coll();
|
||||||
let state = collection
|
let state = coll
|
||||||
.find_one(doc! {"guild_id": guild_id }, None)
|
.find_one(doc! {"guild_id": &guild_id }, None)
|
||||||
.await
|
.await
|
||||||
.wrap_err("find state")?;
|
.wrap_err("find state")?;
|
||||||
|
|
||||||
|
let state = match state {
|
||||||
|
Some(state) => state,
|
||||||
|
None => {
|
||||||
|
info!(%guild_id, "No state found for guild, creating new state");
|
||||||
|
self.new_state(guild_id.to_owned()).await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Ok(state)
|
Ok(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,15 +73,31 @@ impl Mongo {
|
||||||
let state = State {
|
let state = State {
|
||||||
guild_id,
|
guild_id,
|
||||||
lawsuits: vec![],
|
lawsuits: vec![],
|
||||||
justice_category: None,
|
court_category: None,
|
||||||
court_rooms: vec![],
|
court_rooms: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let collection = self.db.collection::<State>("state");
|
let coll = self.db.collection::<State>("state");
|
||||||
collection
|
coll.insert_one(&state, None)
|
||||||
.insert_one(&state, None)
|
|
||||||
.await
|
.await
|
||||||
.wrap_err("insert state")?;
|
.wrap_err("insert state")?;
|
||||||
Ok(state)
|
Ok(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn set_court_category(&self, guild_id: &str, category: &str) -> Result<()> {
|
||||||
|
let _ = self.find_or_insert_state(guild_id).await?;
|
||||||
|
let coll = self.state_coll();
|
||||||
|
coll.update_one(
|
||||||
|
doc! {"guild_id": &guild_id },
|
||||||
|
doc! {"$set": { "court_category": category }},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.wrap_err("update court category")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn state_coll(&self) -> Collection<State> {
|
||||||
|
self.db.collection("state")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue