From 91e57a4c694cd425fd60ff494a202212bc749f64 Mon Sep 17 00:00:00 2001 From: Xyfacai Date: Tue, 16 Sep 2025 16:28:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20jimeng=20kling=20=E6=94=AF=E6=8C=81new?= =?UTF-8?q?=20api=20=E5=B5=8C=E5=A5=97=E4=B8=AD=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller/channel.go | 14 +++++++--- relay/channel/task/jimeng/adaptor.go | 38 ++++++++++++++++++++-------- relay/channel/task/kling/adaptor.go | 19 +++++++++++++- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/controller/channel.go b/controller/channel.go index 403eb04cc..17154ab0f 100644 --- a/controller/channel.go +++ b/controller/channel.go @@ -501,9 +501,10 @@ func validateChannel(channel *model.Channel, isAdd bool) error { } type AddChannelRequest struct { - Mode string `json:"mode"` - MultiKeyMode constant.MultiKeyMode `json:"multi_key_mode"` - Channel *model.Channel `json:"channel"` + Mode string `json:"mode"` + MultiKeyMode constant.MultiKeyMode `json:"multi_key_mode"` + BatchAddSetKeyPrefix2Name bool `json:"batch_add_set_key_prefix_2_name"` + Channel *model.Channel `json:"channel"` } func getVertexArrayKeys(keys string) ([]string, error) { @@ -616,6 +617,13 @@ func AddChannel(c *gin.Context) { } localChannel := addChannelRequest.Channel localChannel.Key = key + if addChannelRequest.BatchAddSetKeyPrefix2Name && len(keys) > 1 { + keyPrefix := localChannel.Key + if len(localChannel.Key) > 8 { + keyPrefix = localChannel.Key[:8] + } + localChannel.Name = fmt.Sprintf("%s %s", localChannel.Name, keyPrefix) + } channels = append(channels, *localChannel) } err = model.BatchInsertChannels(channels) diff --git a/relay/channel/task/jimeng/adaptor.go b/relay/channel/task/jimeng/adaptor.go index 2bc45c547..95f3cb269 100644 --- a/relay/channel/task/jimeng/adaptor.go +++ b/relay/channel/task/jimeng/adaptor.go @@ -93,6 +93,9 @@ func (a *TaskAdaptor) ValidateRequestAndSetAction(c *gin.Context, info *relaycom // BuildRequestURL constructs the upstream URL. func (a *TaskAdaptor) BuildRequestURL(info *relaycommon.RelayInfo) (string, error) { + if isNewAPIRelay(info.ApiKey) { + return fmt.Sprintf("%s/jimeng/?Action=CVSync2AsyncSubmitTask&Version=2022-08-31", a.baseURL), nil + } return fmt.Sprintf("%s/?Action=CVSync2AsyncSubmitTask&Version=2022-08-31", a.baseURL), nil } @@ -100,7 +103,12 @@ func (a *TaskAdaptor) BuildRequestURL(info *relaycommon.RelayInfo) (string, erro func (a *TaskAdaptor) BuildRequestHeader(c *gin.Context, req *http.Request, info *relaycommon.RelayInfo) error { req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "application/json") - return a.signRequest(req, a.accessKey, a.secretKey) + if isNewAPIRelay(info.ApiKey) { + req.Header.Set("Authorization", "Bearer "+info.ApiKey) + } else { + return a.signRequest(req, a.accessKey, a.secretKey) + } + return nil } // BuildRequestBody converts request into Jimeng specific format. @@ -160,6 +168,9 @@ func (a *TaskAdaptor) FetchTask(baseUrl, key string, body map[string]any) (*http } uri := fmt.Sprintf("%s/?Action=CVSync2AsyncGetResult&Version=2022-08-31", baseUrl) + if isNewAPIRelay(key) { + uri = fmt.Sprintf("%s/jimeng/?Action=CVSync2AsyncGetResult&Version=2022-08-31", a.baseURL) + } payload := map[string]string{ "req_key": "jimeng_vgfm_t2v_l20", // This is fixed value from doc: https://www.volcengine.com/docs/85621/1544774 "task_id": taskID, @@ -177,17 +188,20 @@ func (a *TaskAdaptor) FetchTask(baseUrl, key string, body map[string]any) (*http req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") - keyParts := strings.Split(key, "|") - if len(keyParts) != 2 { - return nil, fmt.Errorf("invalid api key format for jimeng: expected 'ak|sk'") - } - accessKey := strings.TrimSpace(keyParts[0]) - secretKey := strings.TrimSpace(keyParts[1]) + if isNewAPIRelay(key) { + req.Header.Set("Authorization", "Bearer "+key) + } else { + keyParts := strings.Split(key, "|") + if len(keyParts) != 2 { + return nil, fmt.Errorf("invalid api key format for jimeng: expected 'ak|sk'") + } + accessKey := strings.TrimSpace(keyParts[0]) + secretKey := strings.TrimSpace(keyParts[1]) - if err := a.signRequest(req, accessKey, secretKey); err != nil { - return nil, errors.Wrap(err, "sign request failed") + if err := a.signRequest(req, accessKey, secretKey); err != nil { + return nil, errors.Wrap(err, "sign request failed") + } } - return service.GetHttpClient().Do(req) } @@ -362,3 +376,7 @@ func (a *TaskAdaptor) ParseTaskResult(respBody []byte) (*relaycommon.TaskInfo, e taskResult.Url = resTask.Data.VideoUrl return &taskResult, nil } + +func isNewAPIRelay(apiKey string) bool { + return strings.HasPrefix(apiKey, "sk-") +} diff --git a/relay/channel/task/kling/adaptor.go b/relay/channel/task/kling/adaptor.go index 13f2af972..fec3396ae 100644 --- a/relay/channel/task/kling/adaptor.go +++ b/relay/channel/task/kling/adaptor.go @@ -117,6 +117,11 @@ func (a *TaskAdaptor) ValidateRequestAndSetAction(c *gin.Context, info *relaycom // BuildRequestURL constructs the upstream URL. func (a *TaskAdaptor) BuildRequestURL(info *relaycommon.RelayInfo) (string, error) { path := lo.Ternary(info.Action == constant.TaskActionGenerate, "/v1/videos/image2video", "/v1/videos/text2video") + + if isNewAPIRelay(info.ApiKey) { + return fmt.Sprintf("%s/kling%s", a.baseURL, path), nil + } + return fmt.Sprintf("%s%s", a.baseURL, path), nil } @@ -199,6 +204,9 @@ func (a *TaskAdaptor) FetchTask(baseUrl, key string, body map[string]any) (*http } path := lo.Ternary(action == constant.TaskActionGenerate, "/v1/videos/image2video", "/v1/videos/text2video") url := fmt.Sprintf("%s%s/%s", baseUrl, path, taskID) + if isNewAPIRelay(key) { + url = fmt.Sprintf("%s/kling%s/%s", baseUrl, path, taskID) + } req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { @@ -304,8 +312,13 @@ func (a *TaskAdaptor) createJWTToken() (string, error) { //} func (a *TaskAdaptor) createJWTTokenWithKey(apiKey string) (string, error) { - + if isNewAPIRelay(apiKey) { + return apiKey, nil // new api relay + } keyParts := strings.Split(apiKey, "|") + if len(keyParts) != 2 { + return "", errors.New("invalid api_key, required format is accessKey|secretKey") + } accessKey := strings.TrimSpace(keyParts[0]) if len(keyParts) == 1 { return accessKey, nil @@ -352,3 +365,7 @@ func (a *TaskAdaptor) ParseTaskResult(respBody []byte) (*relaycommon.TaskInfo, e } return taskInfo, nil } + +func isNewAPIRelay(apiKey string) bool { + return strings.HasPrefix(apiKey, "sk-") +}