Skip to content

Conversation

@ibuki-hum4
Copy link
Member

Overview

ttsにspeedサブコマンド追加
/tts speed <value>

  • <value> : 最低50-最高200、初期値(デフォ値)100

issue

#212

Copilot AI review requested due to automatic review settings January 29, 2026 14:56
@ibuki-hum4 ibuki-hum4 requested a review from a team as a code owner January 29, 2026 14:56
@ibuki-hum4 ibuki-hum4 requested a review from yuito-it January 29, 2026 14:56
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a speaker speed setting feature for the TTS system, allowing users to adjust the playback speed of text-to-speech audio. The feature adds a new /tts speed <value> command that accepts values from 50 to 200 (representing 0.5x to 2.0x speed), with a default of 100 (1.0x speed).

Changes:

  • Added SpeedScale field to TTSPersonalSetting model to store per-user speed preferences
  • Extended the VoiceVox API client's Synthesize method to accept and apply speed scale parameter
  • Implemented new /tts speed subcommand with validation and user feedback
  • Updated help documentation to include the new speed command

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/internal/model/tts_personal_setting.go Added SpeedScale field (int64) with default value of 100 to store speed preference
src/internal/repository/tts_personal_setting.go Updated default TTS personal setting to include SpeedScale: 100
src/internal/api/voicevox/client.go Added speedScale parameter to Synthesize method and applied it to the query
src/internal/bot/voice/player.go Updated worker to pass speed scale value (converted to float64) to synthesizer
src/internal/bot/command/general/tts/speed.go New command handler implementing speed setting functionality with validation
src/internal/bot/command/general/tts.go Registered new speed subcommand in TTS command handler map
src/internal/bot/command/general/help/help-commands.go Added documentation for /tts skip and /tts speed commands
src/internal/bot/command/general/help.go Added "TTS Speed" choice to help command options

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 68 to 76
setting = &repository.DefaultTTSPersonalSetting
setting.MemberID = memberID
}
setting.SpeedScale = speed
err = repo.Update(setting)
if err != nil {
log.Println("Error updating TTS personal setting:", err)
return
}
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical bug: This code takes a pointer to the global DefaultTTSPersonalSetting and then modifies it (lines 69 and 71). This will corrupt the shared default value, affecting all future uses of DefaultTTSPersonalSetting across the application.

Instead, create a new instance by copying the default values. The correct pattern should be:

  • Create a new TTSPersonalSetting instance with values from DefaultTTSPersonalSetting
  • Set the MemberID and SpeedScale on the new instance
  • Use repo.Create() instead of repo.Update() for new records

You can see the correct pattern in src/internal/bot/command/general/tts/join.go:178-187 where it checks if the record is nil and uses Create for new records and Update for existing records.

Suggested change
setting = &repository.DefaultTTSPersonalSetting
setting.MemberID = memberID
}
setting.SpeedScale = speed
err = repo.Update(setting)
if err != nil {
log.Println("Error updating TTS personal setting:", err)
return
}
// Create a new setting based on the default values without mutating the global default
defaultSetting := repository.DefaultTTSPersonalSetting
setting = &defaultSetting
setting.MemberID = memberID
setting.SpeedScale = speed
err = repo.Create(setting)
if err != nil {
log.Println("Error creating TTS personal setting:", err)
return
}
} else {
setting.SpeedScale = speed
err = repo.Update(setting)
if err != nil {
log.Println("Error updating TTS personal setting:", err)
return
}
}

Copilot uses AI. Check for mistakes.
Comment on lines 63 to 76
if err != nil {
log.Println("Error fetching TTS personal setting:", err)
return
}
if setting == nil {
setting = &repository.DefaultTTSPersonalSetting
setting.MemberID = memberID
}
setting.SpeedScale = speed
err = repo.Update(setting)
if err != nil {
log.Println("Error updating TTS personal setting:", err)
return
}
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When database operations fail (lines 64-65 and 74-75), the function only logs the error and returns without responding to the user's interaction. This leaves the user without feedback about whether their command succeeded or failed.

Add error responses to inform the user when database operations fail, similar to how other commands handle errors (see skip.go:21-39 for an example pattern).

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +55
// バリデーション
if speed < 50 || speed > 200 {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{
{
Title: "エラー",
Description: "速度は50-200の範囲で指定してください。",
Color: ctx.Config.Colors.Error,
Footer: &discordgo.MessageEmbedFooter{
Text: "Requested by " + i.Member.DisplayName(),
IconURL: i.Member.AvatarURL(""),
},
},
},
Flags: discordgo.MessageFlagsEphemeral,
},
})
return
}

Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validation check at lines 35-54 is redundant because Discord already enforces these constraints through the MinValue and MaxValue options defined at lines 23-24. This validation will never trigger unless Discord's validation fails.

Consider removing this redundant validation or at least documenting why it's needed as a defensive check.

Suggested change
// バリデーション
if speed < 50 || speed > 200 {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{
{
Title: "エラー",
Description: "速度は50-200の範囲で指定してください。",
Color: ctx.Config.Colors.Error,
Footer: &discordgo.MessageEmbedFooter{
Text: "Requested by " + i.Member.DisplayName(),
IconURL: i.Member.AvatarURL(""),
},
},
},
Flags: discordgo.MessageFlagsEphemeral,
},
})
return
}

Copilot uses AI. Check for mistakes.
@ibuki-hum4 ibuki-hum4 linked an issue Jan 29, 2026 that may be closed by this pull request
@yuito-it yuito-it added this to the v9 - Go Edition milestone Jan 29, 2026
Copy link
Member

@yuito-it yuito-it left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

カラムが重複してます...

@ibuki-hum4 ibuki-hum4 requested a review from yuito-it January 29, 2026 15:46
@yuito-it yuito-it added kind/feature 新機能のリクエスト priority/mid 優先度: 中 labels Jan 29, 2026
@yuito-it yuito-it force-pushed the ibuki-hum4/issue212 branch from 5a0c2ae to b086d28 Compare January 29, 2026 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/feature 新機能のリクエスト priority/mid 優先度: 中

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v9] スピーカースピード設定

3 participants