fix errors

This commit is contained in:
mii443
2025-04-03 02:04:17 +09:00
parent df46152a12
commit 5ee3c9b328
10 changed files with 238 additions and 297 deletions

View File

@ -1,7 +1,6 @@
use serenity::{
model::prelude::{
component::ButtonStyle,
interaction::{application_command::ApplicationCommandInteraction, MessageFlags},
all::{
ButtonStyle, CommandInteraction, CreateActionRow, CreateButton, CreateInteractionResponse, CreateInteractionResponseMessage, CreateSelectMenu, CreateSelectMenuKind, CreateSelectMenuOption, MessageFlags
},
prelude::Context,
};
@ -13,7 +12,7 @@ use crate::{
pub async fn config_command(
ctx: &Context,
command: &ApplicationCommandInteraction,
command: &CommandInteraction,
) -> Result<(), Box<dyn std::error::Error>> {
let data_read = ctx.data.read().await;
@ -24,7 +23,7 @@ pub async fn config_command(
.clone();
let mut database = database.lock().await;
database
.get_user_config_or_default(command.user.id.0)
.get_user_config_or_default(command.user.id.get())
.await
.unwrap()
.unwrap()
@ -39,77 +38,54 @@ pub async fn config_command(
let voicevox_speaker = config.voicevox_speaker.unwrap_or(1);
let tts_type = config.tts_type.unwrap_or(TTSType::GCP);
let engine_select = CreateActionRow::SelectMenu(
CreateSelectMenu::new("TTS_CONFIG_ENGINE", CreateSelectMenuKind::String { options: vec![
CreateSelectMenuOption::new("Google TTS", "TTS_CONFIG_ENGINE_SELECTED_GOOGLE")
.default_selection(tts_type == TTSType::GCP),
CreateSelectMenuOption::new("VOICEVOX", "TTS_CONFIG_ENGINE_SELECTED_VOICEVOX")
.default_selection(tts_type == TTSType::VOICEVOX)
] }).placeholder("読み上げAPIを選択")
);
let server_button = CreateActionRow::Buttons(vec![
CreateButton::new("TTS_CONFIG_SERVER")
.label("サーバー設定")
.style(ButtonStyle::Primary)
]);
let mut components = vec![engine_select, server_button];
for (index, speaker_chunk) in voicevox_speakers[0..24].chunks(25).enumerate() {
let mut options = Vec::new();
for (name, id) in speaker_chunk {
options.push(
CreateSelectMenuOption::new(
name,
format!("TTS_CONFIG_VOICEVOX_SPEAKER_SELECTED_{}", id)
).default_selection(*id == voicevox_speaker)
);
}
components.push(
CreateActionRow::SelectMenu(
CreateSelectMenu::new(
format!("TTS_CONFIG_VOICEVOX_SPEAKER_{}", index),
CreateSelectMenuKind::String { options }
).placeholder("VOICEVOX Speakerを指定")
)
);
}
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("読み上げ設定")
.components(|c| {
let mut c = c;
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_button(|f| {
f.label("サーバー設定")
.custom_id("TTS_CONFIG_SERVER")
.style(ButtonStyle::Primary)
})
});
for (index, speaker_chunk) in
voicevox_speakers[0..24].chunks(25).enumerate()
{
c = c.create_action_row(|a| {
let mut a = a;
a = a.create_select_menu(|m| {
m.custom_id(
"TTS_CONFIG_VOICEVOX_SPEAKER_".to_string()
+ &index.to_string(),
)
.options(|o| {
let mut o = o;
for (name, id) in speaker_chunk {
o = o.create_option(|co| {
co.label(name)
.value(format!(
"TTS_CONFIG_VOICEVOX_SPEAKER_SELECTED_{}",
id
))
.default_selection(*id == voicevox_speaker)
})
}
o
})
.placeholder("VOICEVOX Speakerを指定")
});
a
})
}
println!("{:?}", c);
c
})
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("読み上げ設定")
.components(components)
.ephemeral(true)
))
.await?;
Ok(())
}
}

View File

@ -1,8 +1,8 @@
use serenity::{
model::prelude::{
interaction::{application_command::ApplicationCommandInteraction, MessageFlags},
UserId,
all::{
AutoArchiveDuration, CommandInteraction, CreateEmbed, CreateInteractionResponse, CreateInteractionResponseMessage, CreateMessage, CreateThread
},
model::prelude::UserId,
prelude::Context,
};
@ -13,49 +13,39 @@ use crate::{
pub async fn setup_command(
ctx: &Context,
command: &ApplicationCommandInteraction,
command: &CommandInteraction,
) -> Result<(), Box<dyn std::error::Error>> {
println!("Received event");
if let None = command.guild_id {
if command.guild_id.is_none() {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("このコマンドはサーバーでのみ使用可能です.")
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("このコマンドはサーバーでのみ使用可能です.")
.ephemeral(true)
))
.await?;
return Ok(());
}
println!("Fetching guild cache");
let guild = command.guild_id.unwrap().to_guild_cached(&ctx.cache);
if let None = guild {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("ギルドキャッシュを取得できませんでした.")
.flags(MessageFlags::EPHEMERAL)
})
})
.await?;
return Ok(());
}
let guild = guild.unwrap();
let guild_id = command.guild_id.unwrap();
let guild = guild_id.to_guild_cached(&ctx.cache).unwrap().clone();
let channel_id = guild
.voice_states
.get(&UserId(command.user.id.0))
.get(&UserId::from(command.user.id.get()))
.and_then(|state| state.channel_id);
if let None = channel_id {
if channel_id.is_none() {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("ボイスチャンネルに参加してから実行してください.")
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("ボイスチャンネルに参加してから実行してください.")
.ephemeral(true)
))
.await?;
return Ok(());
}
@ -79,39 +69,39 @@ pub async fn setup_command(
let mut storage = storage_lock.write().await;
if storage.contains_key(&guild.id) {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("すでにセットアップしています.")
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("すでにセットアップしています.")
.ephemeral(true)
))
.await?;
return Ok(());
}
let text_channel_id = {
if let Some(mode) = command.data.options.get(0) {
let mode = mode.clone();
let value = mode.value.unwrap();
let value = value.as_str().unwrap();
match value {
"TEXT_CHANNEL" => command.channel_id,
"NEW_THREAD" => {
let message = command
.channel_id
.send_message(&ctx.http, |f| f.content("TTS thread"))
.await
.unwrap();
command
.channel_id
.create_public_thread(&ctx.http, message, |f| {
f.name("TTS").auto_archive_duration(60)
})
.await
.unwrap()
.id
}
"VOICE_CHANNEL" => channel_id,
match &mode.value {
serenity::all::CommandDataOptionValue::String(value) => {
match value.as_str() {
"TEXT_CHANNEL" => command.channel_id,
"NEW_THREAD" => {
let message = command
.channel_id
.send_message(&ctx.http, CreateMessage::new().content("TTS thread"))
.await
.unwrap();
command
.channel_id
.create_thread(&ctx.http, CreateThread::new("TTS").auto_archive_duration(AutoArchiveDuration::OneHour).kind(serenity::all::ChannelType::PublicThread))
.await
.unwrap()
.id
}
"VOICE_CHANNEL" => channel_id,
_ => channel_id,
}
},
_ => channel_id,
}
} else {
@ -133,13 +123,22 @@ pub async fn setup_command(
};
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content(format!("TTS Channel: <#{}>{}", text_channel_id, if text_channel_id == channel_id { "\nボイスチャンネルを右クリックし `チャットを開く` を押して開くことが出来ます。" } else { "" }))
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content(format!(
"TTS Channel: <#{}>{}",
text_channel_id,
if text_channel_id == channel_id {
"\nボイスチャンネルを右クリックし `チャットを開く` を押して開くことが出来ます。"
} else {
""
}
))
))
.await?;
let _handler = manager.join(guild.id.0, channel_id.0).await;
let _handler = manager.join(guild.id, channel_id).await;
let tts_client = ctx
.data
@ -151,9 +150,10 @@ pub async fn setup_command(
let voicevox_speakers = tts_client.lock().await.1.get_speakers().await;
text_channel_id
.send_message(&ctx.http, |f| {
f.embed(|e| {
e.title("読み上げ (Serenity)")
.send_message(&ctx.http, CreateMessage::new()
.embed(
CreateEmbed::new()
.title("読み上げ (Serenity)")
.field(
"VOICEVOXクレジット",
format!("```\n{}\n```", voicevox_speakers.join("\n")),
@ -161,9 +161,8 @@ pub async fn setup_command(
)
.field("設定コマンド", "`/config`", false)
.field("フィードバック", "https://feedback.mii.codes/", false)
})
})
))
.await?;
Ok(())
}
}

View File

@ -1,8 +1,9 @@
use serenity::{
model::prelude::{
interaction::{application_command::ApplicationCommandInteraction, MessageFlags},
UserId,
all::{
CommandInteraction, CreateInteractionResponse, CreateInteractionResponseMessage,
MessageFlags
},
model::prelude::UserId,
prelude::Context,
};
@ -10,47 +11,36 @@ use crate::data::TTSData;
pub async fn skip_command(
ctx: &Context,
command: &ApplicationCommandInteraction,
command: &CommandInteraction,
) -> Result<(), Box<dyn std::error::Error>> {
if let None = command.guild_id {
if command.guild_id.is_none() {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("このコマンドはサーバーでのみ使用可能です.")
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("このコマンドはサーバーでのみ使用可能です.")
.ephemeral(true)
))
.await?;
return Ok(());
}
let guild = command.guild_id.unwrap().to_guild_cached(&ctx.cache);
if let None = guild {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("ギルドキャッシュを取得できませんでした.")
.flags(MessageFlags::EPHEMERAL)
})
})
.await?;
return Ok(());
}
let guild = guild.unwrap();
let guild_id = command.guild_id.unwrap();
let guild = guild_id.to_guild_cached(&ctx.cache).unwrap().clone();
let channel_id = guild
.voice_states
.get(&UserId(command.user.id.0))
.get(&UserId::from(command.user.id.get()))
.and_then(|state| state.channel_id);
if let None = channel_id {
if channel_id.is_none() {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("ボイスチャンネルに参加してから実行してください.")
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("ボイスチャンネルに参加してから実行してください.")
.ephemeral(true)
))
.await?;
return Ok(());
}
@ -67,24 +57,26 @@ pub async fn skip_command(
let mut storage = storage_lock.write().await;
if !storage.contains_key(&guild.id) {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("読み上げしていません")
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("読み上げしていません")
.ephemeral(true)
))
.await?;
return Ok(());
}
storage.get_mut(&guild.id).unwrap().skip(&ctx).await;
storage.get_mut(&guild.id).unwrap().skip(ctx).await;
}
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| d.content("スキップしました"))
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("スキップしました")
))
.await?;
Ok(())
}
}

View File

@ -1,56 +1,46 @@
use serenity::{
model::prelude::{
interaction::{application_command::ApplicationCommandInteraction, MessageFlags},
UserId,
all::{
CommandInteraction, CreateInteractionResponse, CreateInteractionResponseMessage, EditThread, MessageFlags
},
prelude::Context,
model::prelude::UserId,
prelude::Context
};
use crate::data::TTSData;
pub async fn stop_command(
ctx: &Context,
command: &ApplicationCommandInteraction,
command: &CommandInteraction,
) -> Result<(), Box<dyn std::error::Error>> {
if let None = command.guild_id {
if command.guild_id.is_none() {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("このコマンドはサーバーでのみ使用可能です.")
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("このコマンドはサーバーでのみ使用可能です.")
.ephemeral(true)
))
.await?;
return Ok(());
}
let guild = command.guild_id.unwrap().to_guild_cached(&ctx.cache);
if let None = guild {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("ギルドキャッシュを取得できませんでした.")
.flags(MessageFlags::EPHEMERAL)
})
})
.await?;
return Ok(());
}
let guild = guild.unwrap();
let guild_id = command.guild_id.unwrap();
let guild = guild_id.to_guild_cached(&ctx.cache).unwrap().clone();
let channel_id = guild
.voice_states
.get(&UserId(command.user.id.0))
.get(&UserId::from(command.user.id.get()))
.and_then(|state| state.channel_id);
if let None = channel_id {
if channel_id.is_none() {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("ボイスチャンネルに参加してから実行してください.")
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("ボイスチャンネルに参加してから実行してください.")
.ephemeral(true)
))
.await?;
return Ok(());
}
@ -70,36 +60,37 @@ pub async fn stop_command(
let text_channel_id = {
let mut storage = storage_lock.write().await;
if !storage.contains_key(&guild.id) {
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| {
d.content("すでに停止しています")
.flags(MessageFlags::EPHEMERAL)
})
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("すでに停止しています")
.ephemeral(true)
))
.await?;
return Ok(());
}
let text_channel_id = storage.get(&guild.id).unwrap().text_channel;
storage.remove(&guild.id);
text_channel_id
};
let _handler = manager.remove(guild.id.0).await;
let _handler = manager.remove(guild.id).await;
command
.create_interaction_response(&ctx.http, |f| {
f.interaction_response_data(|d| d.content("停止しました"))
})
.create_response(&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("停止しました")
))
.await?;
let _ = text_channel_id
.edit_thread(&ctx.http, |f| f.archived(true))
.edit_thread(&ctx.http, EditThread::new().archived(true))
.await;
Ok(())
}
}

View File

@ -106,9 +106,9 @@ impl EventHandler for Handler {
if let Some(message_component) = interaction.message_component() {
match &*message_component.data.custom_id {
"TTS_CONFIG_SERVER_REMOVE_DICTIONARY_MENU" => {
let i = usize::from_str_radix(match message_component.data.kind {
ComponentInteractionDataKind::StringSelect { values, .. } => {
&values[0].clone()
let i = usize::from_str_radix(&match message_component.data.kind {
ComponentInteractionDataKind::StringSelect { ref values, .. } => {
values[0].clone()
}
_ => panic!("Cannot get index"),
}, 10).unwrap();
@ -180,8 +180,7 @@ impl EventHandler for Handler {
.iter()
.enumerate()
{
let option = CreateSelectMenuOption::new(rule.id.clone(), i.to_string());
option.description(format!(
let option = CreateSelectMenuOption::new(rule.id.clone(), i.to_string()).description(format!(
"{} -> {}",
rule.rule.clone(),
rule.to.clone()
@ -221,7 +220,7 @@ impl EventHandler for Handler {
.embed(CreateEmbed::new()
.title("辞書一覧")
.fields({
let fields = vec![];
let mut fields = vec![];
for rule in config.dictionary.rules {
let field = (
rule.id.clone(),
@ -275,7 +274,7 @@ impl EventHandler for Handler {
}
"SET_AUTOSTART_CHANNEL" => {
let autostart_channel_id = match message_component.data.kind {
ComponentInteractionDataKind::StringSelect { values, .. } => {
ComponentInteractionDataKind::StringSelect { ref values, .. } => {
if values.len() == 0 {
None
} else {
@ -397,8 +396,8 @@ impl EventHandler for Handler {
_ => {}
}
match message_component.data.kind {
ComponentInteractionDataKind::StringSelect { values, .. } if !values.is_empty() => {
let res = &values[0];
ComponentInteractionDataKind::StringSelect { ref values, .. } if !values.is_empty() => {
let res = &values[0].clone();
let data_read = ctx.data.read().await;
let mut config = {

View File

@ -31,7 +31,7 @@ pub async fn message(ctx: Context, message: Message) {
let instance = storage.get_mut(&guild_id).unwrap();
if instance.text_channel.0 != message.channel_id.0 {
if instance.text_channel != message.channel_id {
return;
}

View File

@ -1,32 +1,20 @@
use serenity::{
model::prelude::{command::Command, Ready},
prelude::Context,
all::{Command, CommandOptionType, CreateCommand, CreateCommandOption}, model::prelude::Ready, prelude::Context
};
pub async fn ready(ctx: Context, ready: Ready) {
println!("{} is connected!", ready.user.name);
let _ = Command::set_global_application_commands(&ctx.http, |commands| {
commands
.create_application_command(|command| command.name("stop").description("Stop tts"))
.create_application_command(|command| {
command
.name("setup")
.description("Setup tts")
.create_option(|o| {
o.name("mode")
.description("TTS channel")
.add_string_choice("Text Channel", "TEXT_CHANNEL")
.add_string_choice("New Thread", "NEW_THREAD")
.add_string_choice("Voice Channel", "VOICE_CHANNEL")
.kind(serenity::model::prelude::command::CommandOptionType::String)
.required(false)
})
})
.create_application_command(|command| command.name("config").description("Config"))
.create_application_command(|command| {
command.name("skip").description("skip tts message")
})
})
.await;
Command::set_global_commands(&ctx.http, vec![
CreateCommand::new("stop").description("Stop tts"),
CreateCommand::new("setup").description("Setup tts").set_options(vec![
CreateCommandOption::new(CommandOptionType::String, "mode", "TTS channel")
.add_string_choice("Text Channel", "TEXT_CHANNEL")
.add_string_choice("New Thread", "NEW_THREAD")
.add_string_choice("Voice Channel", "VOICE_CHANNEL")
.required(false)
]),
CreateCommand::new("config").description("Config"),
CreateCommand::new("skip").description("skip tts message"),
]).await.unwrap();
}

View File

@ -6,7 +6,7 @@ use crate::{
},
tts::{instance::TTSInstance, message::AnnounceMessage},
};
use serenity::{model::voice::VoiceState, prelude::Context};
use serenity::{all::{CreateEmbed, CreateMessage, EditThread}, model::voice::VoiceState, prelude::Context};
pub async fn voice_state_update(ctx: Context, old: Option<VoiceState>, new: VoiceState) {
if new.member.clone().unwrap().user.bot {
@ -39,7 +39,7 @@ pub async fn voice_state_update(ctx: Context, old: Option<VoiceState>, new: Voic
.clone();
let mut database = database.lock().await;
database
.get_server_config_or_default(guild_id.0)
.get_server_config_or_default(guild_id.get())
.await
.unwrap()
.unwrap()
@ -49,7 +49,7 @@ pub async fn voice_state_update(ctx: Context, old: Option<VoiceState>, new: Voic
let mut storage = storage_lock.write().await;
if !storage.contains_key(&guild_id) {
if let Some(new_channel) = new.channel_id {
if config.autostart_channel_id.unwrap_or(0) == new_channel.0 {
if config.autostart_channel_id.unwrap_or(0) == new_channel.get() {
let manager = songbird::get(&ctx)
.await
.expect("Cannot get songbird client.")
@ -64,7 +64,7 @@ pub async fn voice_state_update(ctx: Context, old: Option<VoiceState>, new: Voic
},
);
let _handler = manager.join(guild_id.0, new_channel.0).await;
let _handler = manager.join(guild_id, new_channel).await;
let tts_client = ctx
.data
.read()
@ -75,18 +75,15 @@ pub async fn voice_state_update(ctx: Context, old: Option<VoiceState>, new: Voic
let voicevox_speakers = tts_client.lock().await.1.get_speakers().await;
new_channel
.send_message(&ctx.http, |f| {
f.embed(|e| {
e.title("自動参加 読み上げ (Serenity)")
.field(
"VOICEVOXクレジット",
format!("```\n{}\n```", voicevox_speakers.join("\n")),
false,
)
.field("設定コマンド", "`/config`", false)
.field("フィードバック", "https://feedback.mii.codes/", false)
})
})
.send_message(&ctx.http,
CreateMessage::new()
.embed(
CreateEmbed::new()
.title("自動参加 読み上げSerenity")
.field("VOICEVOXクレジット", format!("```\n{}\n```", voicevox_speakers.join("\n")), false)
.field("設定コマンド", "`/config`", false)
.field("フィードバック", "https://feedback.mii.codes/", false))
)
.await
.unwrap();
}
@ -118,7 +115,7 @@ pub async fn voice_state_update(ctx: Context, old: Option<VoiceState>, new: Voic
let mut del_flag = false;
for channel in guild_id.channels(&ctx.http).await.unwrap() {
if channel.0 == instance.voice_channel {
del_flag = channel.1.members(&ctx.cache).await.unwrap().len() <= 1;
del_flag = channel.1.members(&ctx.cache).unwrap().len() <= 1;
}
}
@ -127,7 +124,7 @@ pub async fn voice_state_update(ctx: Context, old: Option<VoiceState>, new: Voic
.get(&guild_id)
.unwrap()
.text_channel
.edit_thread(&ctx.http, |f| f.archived(true))
.edit_thread(&ctx.http, EditThread::new().archived(true))
.await;
storage.remove(&guild_id);
@ -136,7 +133,7 @@ pub async fn voice_state_update(ctx: Context, old: Option<VoiceState>, new: Voic
.expect("Cannot get songbird client.")
.clone();
manager.remove(guild_id.0).await.unwrap();
manager.remove(guild_id).await.unwrap();
}
}
}

View File

@ -29,7 +29,7 @@ impl TTSMessage for Message {
.clone();
let mut database = database.lock().await;
database
.get_server_config_or_default(instance.guild.0)
.get_server_config_or_default(instance.guild.get())
.await
.unwrap()
.unwrap()
@ -95,7 +95,7 @@ impl TTSMessage for Message {
.clone();
let mut database = database.lock().await;
database
.get_user_config_or_default(self.author.id.0)
.get_user_config_or_default(self.author.id.get())
.await
.unwrap()
.unwrap()

View File

@ -5,6 +5,7 @@ use serenity::{
},
prelude::Context,
};
use songbird::input::File;
use crate::tts::message::TTSMessage;
@ -32,10 +33,8 @@ impl TTSInstance {
let manager = songbird::get(&ctx).await.unwrap();
let call = manager.get(self.guild).unwrap();
let mut call = call.lock().await;
let input = songbird::input::ffmpeg(path)
.await
.expect("File not found.");
call.enqueue_source(input);
let input = File::new(path);
call.enqueue(input.into());
}
}