feat(voice): voiceconfig 工具——语音配置一键入库(联调/无头环境免开 admin)

等价于 admin「语音设置」保存一次:读 VOLC_* 环境变量→AES 加密(复用 gateway
EncryptedForStore)→写 sundynix_setting。网关每请求现读,无需重启。凭证只走 env 不进 git。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-22 09:42:47 +08:00
parent 5b871bc363
commit b718bdbb21
2 changed files with 66 additions and 0 deletions
+66
View File
@@ -0,0 +1,66 @@
// voiceconfig 把火山语音配置写入数据库(等价于 admin「语音设置」页保存一次)。
// 供本地联调 / 无头环境快速配好语音,免开 admin 控制台。API Key 只走环境变量、加密入库,
// 绝不进代码/git;写库前复用 gateway 同一套 AES 加密(voice.Config.EncryptedForStore)。
//
// 用法:
//
// export POSTGRES_DSN="postgres://sundynix:sundynix@localhost:5432/sundynix?sslmode=disable"
// export VOLC_API_KEY=<你的APIKey>
// export VOLC_ASR_RESOURCE_ID=volc.seedasr.sauc.duration
// export VOLC_TTS_RESOURCE_ID=seed-tts-2.0
// export VOLC_TTS_VOICE=zh_male_m191_uranus_bigtts
// # SUNDYNIX_SECRET_KEY 须与 gateway 一致(都不设=同用开发默认)
// go run ./cmd/voiceconfig
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"github.com/sundynix/sundynix-gateway/internal/store"
"github.com/sundynix/sundynix-gateway/internal/voice"
)
const settingVoice = "voice_config" // 与 handler.SettingVoice 对齐
func main() {
dsn := os.Getenv("POSTGRES_DSN")
if dsn == "" {
fatal("缺 POSTGRES_DSN")
}
cfg := voice.Config{
APIKey: os.Getenv("VOLC_API_KEY"),
ASRResourceID: os.Getenv("VOLC_ASR_RESOURCE_ID"),
TTSResourceID: os.Getenv("VOLC_TTS_RESOURCE_ID"),
TTSVoiceType: os.Getenv("VOLC_TTS_VOICE"),
}
if cfg.APIKey == "" {
fatal("缺 VOLC_API_KEY")
}
db := store.OpenPostgres(dsn)
if !db.Enabled() {
fatal("连不上数据库(检查 POSTGRES_DSN / 容器是否起)")
}
stored, err := cfg.EncryptedForStore() // AES-256-GCM 加密 APIKey(同 gateway
if err != nil {
fatal("加密失败:" + err.Error())
}
raw, _ := json.Marshal(stored)
if err := db.SetSetting(context.Background(), settingVoice, string(raw)); err != nil {
fatal("写库失败:" + err.Error())
}
fmt.Printf("✅ 语音配置已入库(%s\n", settingVoice)
fmt.Printf(" ASR resource=%q 可用=%v\n", cfg.ASRResourceID, cfg.ASREnabled())
fmt.Printf(" TTS resource=%q 音色=%q 可用=%v\n", cfg.TTSResourceID, cfg.TTSVoiceType, cfg.TTSEnabled())
fmt.Println(" 网关每次请求现读,无需重启;刷新桌面端点麦克风即可。")
}
func fatal(msg string) {
fmt.Fprintln(os.Stderr, "❌ "+msg)
os.Exit(1)
}
BIN
View File
Binary file not shown.