From 5ec2b625e89a98fc4c7cc0c8fc2901d99986335e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=94=A6=E5=BC=BA?= <1061669148@qq.com> Date: Wed, 2 Apr 2025 21:51:50 +0800 Subject: [PATCH] feat: add IFreeTime endpoint and response handling for TTS application --- internal/http/handlers/tts.go | 83 ++++++++++++++++++++++++++++++++++ internal/http/routes/routes.go | 1 + internal/models/tts.go | 41 +++++++++++++++++ 3 files changed, 125 insertions(+) diff --git a/internal/http/handlers/tts.go b/internal/http/handlers/tts.go index 8df234a..b370bfc 100644 --- a/internal/http/handlers/tts.go +++ b/internal/http/handlers/tts.go @@ -3,6 +3,7 @@ package handlers import ( "encoding/json" "fmt" + "github.com/google/uuid" "log" "net/http" "os" @@ -504,6 +505,88 @@ func (h *TTSHandler) HandleReader(context *gin.Context) { }) } +// HandleIFreeTime 处理IFreeTime应用请求 +func (h *TTSHandler) HandleIFreeTime(context *gin.Context) { + // 从URL参数获取 + req := models.TTSRequest{ + Text: context.Query("t"), + Voice: context.Query("v"), + Rate: context.Query("r"), + Pitch: context.Query("p"), + Style: context.Query("s"), + } + displayName := context.Query("n") + + // 获取基础URL + baseUrl := utils.GetBaseURL(context) + basePath, err := utils.JoinURL(baseUrl, cfg.Server.BasePath) + if err != nil { + context.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + // 构建URL + url := fmt.Sprintf("%s/tts", basePath) + + // 生成随机的唯一ID + ttsConfigID := uuid.New().String() + + // 构建声音列表 + var voiceList []models.IFreeTimeVoice + + // 构建请求参数 + params := map[string]string{ + "t": "%@", // %@ 是 IFreeTime 中的文本占位符 + "v": req.Voice, + "r": req.Rate, + "p": req.Pitch, + "s": req.Style, + } + + // 如果需要API密钥认证,添加到请求参数 + if h.config.TTS.ApiKey != "" { + params["api_key"] = h.config.TTS.ApiKey + } + + // 构建响应 + response := models.IFreeTimeResponse{ + LoginUrl: "", + MaxWordCount: "", + CustomRules: map[string]interface{}{}, + TtsConfigGroup: "Azure", + TTSName: displayName, + ClassName: "JxdAdvCustomTTS", + TTSConfigID: ttsConfigID, + HttpConfigs: models.IFreeTimeHttpConfig{ + UseCookies: 1, + Headers: map[string]interface{}{}, + }, + VoiceList: voiceList, + TtsHandles: []models.IFreeTimeTtsHandle{ + { + ParamsEx: "", + ProcessType: 1, + MaxPageCount: 1, + NextPageMethod: 1, + Method: 1, + RequestByWebView: 0, + Parser: map[string]interface{}{}, + NextPageParams: map[string]interface{}{}, + Url: url, + Params: params, + HttpConfigs: models.IFreeTimeHttpConfig{ + UseCookies: 1, + Headers: map[string]interface{}{}, + }, + }, + }, + } + + // 设置响应类型 + context.Header("Content-Type", "application/json") + context.JSON(http.StatusOK, response) +} + // splitTextBySentences 将文本按句子分割 func splitTextBySentences(text string) []string { // 如果文本过短,直接作为一个句子返回 diff --git a/internal/http/routes/routes.go b/internal/http/routes/routes.go index 301a328..16d8829 100644 --- a/internal/http/routes/routes.go +++ b/internal/http/routes/routes.go @@ -51,6 +51,7 @@ func SetupRoutes(cfg *config.Config, ttsService tts.Service) (*gin.Engine, error baseRouter.POST("/tts", middleware.TTSAuth(cfg.TTS.ApiKey), ttsHandler.HandleTTS) baseRouter.GET("/tts", middleware.TTSAuth(cfg.TTS.ApiKey), ttsHandler.HandleTTS) baseRouter.GET("/reader.json", middleware.TTSAuth(cfg.TTS.ApiKey), ttsHandler.HandleReader) + baseRouter.GET("ifreetime.json", middleware.TTSAuth(cfg.TTS.ApiKey), ttsHandler.HandleIFreeTime) // 设置语音列表API路由 baseRouter.GET("/voices", voicesHandler.HandleVoices) diff --git a/internal/models/tts.go b/internal/models/tts.go index 6b5b811..db0cb66 100644 --- a/internal/models/tts.go +++ b/internal/models/tts.go @@ -30,3 +30,44 @@ type ReaderResponse struct { Name string `json:"name"` Url string `json:"url"` } + +// IFreeTimeResponse IFreeTime应用配置响应 +type IFreeTimeResponse struct { + LoginUrl string `json:"loginUrl"` + MaxWordCount string `json:"maxWordCount"` + CustomRules map[string]interface{} `json:"customRules"` + TtsConfigGroup string `json:"ttsConfigGroup"` + TTSName string `json:"_TTSName"` + ClassName string `json:"_ClassName"` + TTSConfigID string `json:"_TTSConfigID"` + HttpConfigs IFreeTimeHttpConfig `json:"httpConfigs"` + VoiceList []IFreeTimeVoice `json:"voiceList"` + TtsHandles []IFreeTimeTtsHandle `json:"ttsHandles"` +} + +// IFreeTimeHttpConfig HTTP配置 +type IFreeTimeHttpConfig struct { + UseCookies int `json:"useCookies"` + Headers map[string]interface{} `json:"headers"` +} + +// IFreeTimeVoice 语音配置 +type IFreeTimeVoice struct { + Name string `json:"name"` + Display string `json:"display"` +} + +// IFreeTimeTtsHandle TTS处理配置 +type IFreeTimeTtsHandle struct { + ParamsEx string `json:"paramsEx"` + ProcessType int `json:"processType"` + MaxPageCount int `json:"maxPageCount"` + NextPageMethod int `json:"nextPageMethod"` + Method int `json:"method"` + RequestByWebView int `json:"requestByWebView"` + Parser map[string]interface{} `json:"parser"` + NextPageParams map[string]interface{} `json:"nextPageParams"` + Url string `json:"url"` + Params map[string]string `json:"params"` + HttpConfigs IFreeTimeHttpConfig `json:"httpConfigs"` +}