feat: Added quest answers
- Added field pending_answers to DiscordConfig - discord: added /answer
This commit is contained in:
parent
520992187d
commit
3f7e6313b0
6 changed files with 82 additions and 13 deletions
68
discord/src/commands/answer.rs
Normal file
68
discord/src/commands/answer.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
use poise::serenity_prelude::{Attachment, CreateAttachment, CreateMessage, Mentionable};
|
||||
|
||||
use crate::{Context, Error};
|
||||
|
||||
#[poise::command(
|
||||
prefix_command,
|
||||
slash_command,
|
||||
guild_only,
|
||||
)]
|
||||
pub async fn answer(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Identifier of the quest to answer to"]
|
||||
quest_id: u16,
|
||||
#[description = "Text answer to the quest"]
|
||||
text: Option<String>,
|
||||
#[description = "Attachment answer to the quest"]
|
||||
files: Vec<Attachment>,
|
||||
) -> Result<(), Error> {
|
||||
let quests = ctx.data().config.load_quests();
|
||||
let Some(quest) = quests.iter().find(|q| q.id == quest_id) else {
|
||||
let reply_string = format!("Quest #{quest_id} not found.");
|
||||
ctx.reply(reply_string).await?;
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if text.is_none() && files.len() == 0 {
|
||||
let reply_string = "Please specify text or at least one attachment.".to_string();
|
||||
ctx.reply(reply_string).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let text_ans = match text {
|
||||
Some(text) => format!("\n### Passed answer:\n{text}"),
|
||||
None => String::new(),
|
||||
};
|
||||
|
||||
let attachment_notice = if files.len() == 0 { String::new() } else {
|
||||
"\nPassed answer has attachments.".to_string()
|
||||
};
|
||||
|
||||
let content = format!("# From: {user}\n\
|
||||
### Quest #{quest_id}: {quest_name}\n\
|
||||
### Expected answer:\n\
|
||||
||{quest_answer}||{text_ans}{attachment_notice}",
|
||||
user = ctx.author().mention(),
|
||||
quest_name = quest.name,
|
||||
quest_answer = quest.answer,
|
||||
);
|
||||
|
||||
let mut attachments: Vec<CreateAttachment> = Vec::new();
|
||||
|
||||
for file in files {
|
||||
let attachment = CreateAttachment::url(ctx, &file.url).await?;
|
||||
attachments.push(attachment);
|
||||
}
|
||||
|
||||
let ans_channel = ctx.data().discord.answers_channel;
|
||||
let message = CreateMessage::new()
|
||||
.content(content)
|
||||
.files(attachments);
|
||||
|
||||
ans_channel.send_message(ctx, message).await?;
|
||||
|
||||
let reply_string = "Your answer has been posted.".to_string();
|
||||
ctx.reply(reply_string).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ pub async fn init(
|
|||
dc.guild = guild;
|
||||
let path = &ctx.data().config.full_impl_path().unwrap();
|
||||
let reply_string = match dc.save(path.parent().unwrap_or(Path::new("")).to_owned()) {
|
||||
Ok(_) => "Please restart bot to apply changes".to_string(),
|
||||
Ok(_) => "Settings updated, please restart bot to apply changes.".to_string(),
|
||||
Err(error) => {
|
||||
eprintln!("{error}");
|
||||
ERROR_MSG.to_string()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use crate::{Context, Error};
|
|||
|
||||
pub mod quest;
|
||||
pub mod init;
|
||||
pub mod answer;
|
||||
|
||||
pub const ERROR_MSG: &str = "Server error :(";
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@ use std::str::FromStr;
|
|||
|
||||
use squad_quest::{SquadObject, quest::{Quest, QuestDifficulty}};
|
||||
use toml::value::Date;
|
||||
use crate::{Context, Error};
|
||||
|
||||
const ERROR_MSG: &str = "Server error :(";
|
||||
use crate::{Context, Error, commands::ERROR_MSG};
|
||||
|
||||
#[poise::command(
|
||||
prefix_command,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,15 @@ use poise::serenity_prelude::{ChannelId, GuildId, MessageId};
|
|||
use serde::{Serialize, Deserialize};
|
||||
use squad_quest::{SquadObject, config::Config, error::Error};
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Clone)]
|
||||
pub struct DiscordConfig {
|
||||
pub guild: GuildId,
|
||||
pub quests_channel: ChannelId,
|
||||
pub answers_channel: ChannelId,
|
||||
pub quests_messages: Vec<MessageId>,
|
||||
pub pending_answers: Vec<MessageId>,
|
||||
}
|
||||
|
||||
pub trait ConfigImpl {
|
||||
fn discord_impl(&self) -> Result<DiscordConfig, Error>;
|
||||
fn init_impl(&self) -> Result<(), Error>;
|
||||
|
|
@ -25,14 +34,6 @@ impl ConfigImpl for Config {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Clone)]
|
||||
pub struct DiscordConfig {
|
||||
pub guild: GuildId,
|
||||
pub quests_channel: ChannelId,
|
||||
pub answers_channel: ChannelId,
|
||||
pub quests_messages: Vec<MessageId>,
|
||||
}
|
||||
|
||||
impl SquadObject for DiscordConfig {
|
||||
fn load(path: PathBuf) -> Result<Self, squad_quest::error::Error> {
|
||||
match std::fs::read_to_string(path) {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ async fn main() {
|
|||
commands: vec![
|
||||
commands::quest::quest(),
|
||||
commands::register(),
|
||||
commands::init::init()
|
||||
commands::init::init(),
|
||||
commands::answer::answer(),
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue