add config command

This commit is contained in:
mii
2022-08-12 22:39:12 +09:00
parent 5ca5325fbd
commit c52429bce0
6 changed files with 144 additions and 6 deletions

56
src/commands/config.rs Normal file
View File

@ -0,0 +1,56 @@
use serenity::{prelude::Context, model::prelude::{application_command::ApplicationCommandInteraction, InteractionApplicationCommandCallbackDataFlags}};
use crate::{tts::{voicevox::voicevox::VOICEVOX, tts_type::TTSType}, data::DatabaseClientData};
pub async fn config_command(ctx: &Context, command: &ApplicationCommandInteraction) -> Result<(), Box<dyn std::error::Error>> {
let data_read = ctx.data.read().await;
let config = {
let database = data_read.get::<DatabaseClientData>().expect("Cannot get DatabaseClientData").clone();
let mut database = database.lock().await;
database.get_user_config_or_default(command.user.id.0).await.unwrap().unwrap()
};
let voicevox_speaker = config.voicevox_speaker.unwrap_or(1);
let tts_type = config.tts_type.unwrap_or(TTSType::GCP);
command.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("読み上げ設定")
.components(|c| {
c.create_action_row(|a| {
a.create_select_menu(|m| {
m.custom_id("TTS_CONFIG_ENGINE")
.options(|o| {
o.create_option(|co| {
co.label("Google TTS")
.value("TTS_CONFIG_ENGINE_SELECTED_GOOGLE")
.default_selection(tts_type == TTSType::GCP)
}).create_option(|co| {
co.label("VOICEVOX")
.value("TTS_CONFIG_ENGINE_SELECTED_VOICEVOX")
.default_selection(tts_type == TTSType::VOICEVOX)
})
}).placeholder("読み上げAPIを選択")
})
}).create_action_row(|a| {
a.create_select_menu(|m| {
m.custom_id("TTS_CONFIG_VOICEVOX_SPEAKER")
.options(|o| {
let mut o = o;
for (name, value) in VOICEVOX::get_speakers() {
o = o.create_option(|co| {
co.label(name)
.value(format!("TTS_CONFIG_VOICEVOX_SPEAKER_SELECTED_{}", value))
.default_selection(value == voicevox_speaker)
})
}
o
}).placeholder("VOICEVOX Speakerを指定")
})
})
}).flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL)
})
}).await?;
Ok(())
}

View File

@ -1,2 +1,3 @@
pub mod setup;
pub mod stop;
pub mod stop;
pub mod config;

View File

@ -69,7 +69,11 @@ pub async fn setup_command(ctx: &Context, command: &ApplicationCommandInteractio
command.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("セットアップ完了").flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL)
d.create_embed(|e| {
e.title("読み上げ (Serenity)")
.field("クレジット", "```\n四国めたん  ずんだもん\n春日部つむぎ 雨晴はう\n波音リツ   玄野武宏\n白上虎太郎  青山龍星\n冥鳴ひまり  九州そら\nモチノ・キョウコ```", false)
.field("設定コマンド", "`/config`", false)
})
})
}).await?;

View File

@ -1,5 +1,5 @@
use serenity::{client::{EventHandler, Context}, async_trait, model::{gateway::Ready, interactions::Interaction, id::GuildId, channel::Message, voice::VoiceState}};
use crate::{events, commands::{setup::setup_command, stop::stop_command}};
use serenity::{client::{EventHandler, Context}, async_trait, model::{gateway::Ready, interactions::Interaction, id::GuildId, channel::Message, voice::VoiceState, prelude::InteractionApplicationCommandCallbackDataFlags}};
use crate::{events, commands::{setup::setup_command, stop::stop_command, config::config_command}, data::DatabaseClientData, tts::tts_type::TTSType};
pub struct Handler;
@ -15,14 +15,58 @@ impl EventHandler for Handler {
}
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
if let Interaction::ApplicationCommand(command) = interaction {
if let Interaction::ApplicationCommand(command) = interaction.clone() {
let name = &*command.data.name;
match name {
"setup" => setup_command(&ctx, &command).await.unwrap(),
"stop" => stop_command(&ctx, &command).await.unwrap(),
"config" => config_command(&ctx, &command).await.unwrap(),
_ => {}
}
}
if let Some(message_component) = interaction.message_component() {
if let Some(v) = message_component.data.values.get(0) {
let data_read = ctx.data.read().await;
let mut config = {
let database = data_read.get::<DatabaseClientData>().expect("Cannot get DatabaseClientData").clone();
let mut database = database.lock().await;
database.get_user_config_or_default(message_component.user.id.0).await.unwrap().unwrap()
};
let res = (*v).clone();
let mut config_changed = false;
match &*res {
"TTS_CONFIG_ENGINE_SELECTED_GOOGLE" => {
config.tts_type = Some(TTSType::GCP);
config_changed = true;
}
"TTS_CONFIG_ENGINE_SELECTED_VOICEVOX" => {
config.tts_type = Some(TTSType::VOICEVOX);
config_changed = true;
}
_ => {
if res.starts_with("TTS_CONFIG_VOICEVOX_SPEAKER_SELECTED_") {
config.voicevox_speaker = Some(i64::from_str_radix(&res.replace("TTS_CONFIG_VOICEVOX_SPEAKER_SELECTED_", ""), 10).unwrap());
config_changed = true;
}
}
}
if config_changed {
let database = data_read.get::<DatabaseClientData>().expect("Cannot get DatabaseClientData").clone();
let mut database = database.lock().await;
database.set_user_config(message_component.user.id.0, config).await.unwrap();
message_component.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("設定しました")
.flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL)
})
}).await.unwrap();
}
}
}
}
async fn voice_state_update(

View File

@ -1,4 +1,4 @@
use serenity::{prelude::Context, model::prelude::{Ready, application_command::ApplicationCommand}};
use serenity::{prelude::Context, model::prelude::{Ready, application_command::ApplicationCommand, GuildId}};
pub async fn ready(ctx: Context, ready: Ready) {
println!("{} is connected!", ready.user.name);
@ -17,4 +17,11 @@ pub async fn ready(ctx: Context, ready: Ready) {
.description("Config")
})
}).await;
GuildId(949296300099268668).set_application_commands(&ctx.http, |f| {
f.create_application_command(|command| {
command.name("config")
.description("Config")
})
}).await.unwrap();
}

View File

@ -6,6 +6,32 @@ pub struct VOICEVOX {
}
impl VOICEVOX {
pub fn get_speakers() -> Vec<(String, i64)> {
vec![
("四国めたん - ノーマル".to_string(), 2),
("四国めたん - あまあま".to_string(), 0),
("四国めたん - ツンツン".to_string(), 6),
("四国めたん - セクシー".to_string(), 4),
("ずんだもん - ノーマル".to_string(), 3),
("ずんだもん - あまあま".to_string(), 1),
("ずんだもん - ツンツン".to_string(), 7),
("ずんだもん - セクシー".to_string(), 5),
("春日部つむぎ - ノーマル".to_string(), 8),
("雨晴はう - ノーマル".to_string(), 10),
("波音リツ - ノーマル".to_string(), 9),
("玄野武宏 - ノーマル".to_string(), 11),
("白上虎太郎 - ノーマル".to_string(), 12),
("青山龍星 - ノーマル".to_string(), 13),
("冥鳴ひまり - ノーマル".to_string(), 14),
("九州そら - ノーマル".to_string(), 16),
("九州そら - あまあま".to_string(), 15),
("九州そら - ツンツン".to_string(), 18),
("九州そら - セクシー".to_string(), 17),
("九州そら - ささやき".to_string(), 19),
("モチノ・キョウコ - ノーマル".to_string(), 20),
]
}
pub fn new(key: String) -> Self {
Self {
key