Files
sundynix-agentix/sundynix-gateway/internal/voice/config.go
T
Blizzard d6c1a787f4 fix(voice): 改用火山「新版控制台」API Key 鉴权(ASR 握手真机验通)
一直误用旧版 5 头方案(X-Api-App-Key+Access-Key+App-ID),火山始终 401 grant not found。
用户提供官方文档「新版本控制台」证实:新版只需**单个 X-Api-Key** 头。改对后真机联调:

- frame.go setVolcAuthHeaders: X-Api-Key + X-Api-Resource-Id + X-Api-Request-Id + X-Api-Sequence:-1
  (删旧 App-Key/Access-Key/App-ID/Connect-Id;去 appID 参数)
- asr/tts 调用点同步;config.go 删 Config.AppID;voicecheck/voiceconfig 删 VOLC_APP_ID
- 删临时诊断工具 voiceprobe

真机结果:ASR 握手(volc.bigasr.sauc.duration 有效);TTS 用 seed-tts-2.0 会话正常建立
(不再 resource mismatch),但暂无音频返回→双向 TTS 事件/payload 待调(下一步)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 10:42:36 +08:00

48 lines
1.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package voice
import "github.com/sundynix/sundynix-shared/secrets"
// Config 是语音交互(火山引擎豆包语音)所需配置。APIKey 加密入库、后台明文回显(同微信配置)。
//
// 用**新版 API Key 鉴权**(非旧版 appid+access_token):WS 握手只带两个 header——
// AuthorizationBearer <APIKey>+ X-Api-Resource-Id(区分服务,ASR 与双向 TTS 各一个)。
// 端点/音频格式(PCM 16k 单声道等)由代码固定,不入用户配置。
type Config struct {
APIKey string `json:"api_key"` // 新版控制台 API KeyX-Api-Key,密文入库)
ASRResourceID string `json:"asr_resource_id"` // 流式语音识别 X-Api-Resource-Id
TTSResourceID string `json:"tts_resource_id"` // 双向流式 TTS X-Api-Resource-Id
TTSVoiceType string `json:"tts_voice_type"` // 音色(如 zh_male_… / BV700_streaming
}
// ASREnabled / TTSEnabled 分别报告耳朵、嘴是否配齐(共用同一 API Key,各自还需对应 resource-id)。
func (c Config) ASREnabled() bool { return c.APIKey != "" && c.ASRResourceID != "" }
func (c Config) TTSEnabled() bool {
return c.APIKey != "" && c.TTSResourceID != "" && c.TTSVoiceType != ""
}
// Enabled 报告语音整体是否可用(耳朵 + 嘴都配齐)。
func (c Config) Enabled() bool { return c.ASREnabled() && c.TTSEnabled() }
// EncryptedForStore 返回 APIKey 已加密的副本,用于落库。
func (c Config) EncryptedForStore() (Config, error) {
if c.APIKey == "" {
return c, nil
}
enc, err := secrets.Encrypt(c.APIKey)
if err != nil {
return c, err
}
c.APIKey = enc
return c, nil
}
// DecryptFromStore 把库内密文 APIKey 还原为明文。
func (c Config) DecryptFromStore() Config {
if c.APIKey != "" {
if plain, err := secrets.Decrypt(c.APIKey); err == nil {
c.APIKey = plain
}
}
return c
}