| 38 | ) |
| 39 | |
| 40 | type DiscordChannel struct { |
| 41 | *channels.BaseChannel |
| 42 | bc *config.Channel |
| 43 | session *discordgo.Session |
| 44 | config *config.DiscordSettings |
| 45 | ctx context.Context |
| 46 | cancel context.CancelFunc |
| 47 | typingMu sync.Mutex |
| 48 | typingStop map[string]chan struct{} // chatID → stop signal |
| 49 | progress *channels.ToolFeedbackAnimator |
| 50 | botUserID string // stored for mention checking |
| 51 | bus *bus.MessageBus |
| 52 | tts tts.TTSProvider |
| 53 | playTTSFn func(context.Context, *discordgo.VoiceConnection, string, uint64) |
| 54 | ttsVoiceFn func(string) (*discordgo.VoiceConnection, bool) |
| 55 | voiceMu sync.RWMutex |
| 56 | voiceSSRC map[string]map[uint32]string // guildID -> ssrc -> userID |
| 57 | |
| 58 | // TTS interruption: cancel active playback when user speaks |
| 59 | ttsMu sync.Mutex |
| 60 | cancelTTS context.CancelFunc |
| 61 | ttsPlayID uint64 |
| 62 | } |
| 63 | |
| 64 | func NewDiscordChannel( |
| 65 | bc *config.Channel, |
nothing calls this directly
no outgoing calls
no test coverage detected