From 5ddfc1b4cfcab8220382f2982d6e9cf4871796c2 Mon Sep 17 00:00:00 2001 From: xqdoo00o Date: Tue, 16 Apr 2024 19:52:05 +0800 Subject: [PATCH 1/8] add file expire check --- typings/chatgpt/request.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/typings/chatgpt/request.go b/typings/chatgpt/request.go index e50aba5..762e4f7 100644 --- a/typings/chatgpt/request.go +++ b/typings/chatgpt/request.go @@ -15,6 +15,7 @@ import ( "path" "strconv" "strings" + "time" // 确保导入以下包以支持常见的图像格式 _ "image/gif" @@ -85,6 +86,8 @@ type FileResult struct { Filesize int Isimage bool Bounds [2]int + // Current file max-age 1 year + Upload int64 } type ImgPart struct { @@ -251,7 +254,7 @@ func processUrl(urlstr string, account string, secret *tokens.Secret, deviceId s hasher := sha1.New() hasher.Write(binary) hash := account + hex.EncodeToString(hasher.Sum(nil)) - if fileHashPool[hash] != nil { + if fileHashPool[hash] != nil && time.Now().Unix() < fileHashPool[hash].Upload+31536000 { return fileHashPool[hash] } isImg := strings.HasPrefix(mimeType, "image") @@ -267,7 +270,7 @@ func processUrl(urlstr string, account string, secret *tokens.Secret, deviceId s if fileid == "" { return nil } else { - result := FileResult{Mime: mimeType, Filename: fileName, Filesize: len(binary), Fileid: fileid, Isimage: isImg, Bounds: bounds} + result := FileResult{Mime: mimeType, Filename: fileName, Filesize: len(binary), Fileid: fileid, Isimage: isImg, Bounds: bounds, Upload: time.Now().Unix()} fileHashPool[hash] = &result return &result } @@ -281,7 +284,7 @@ func processDataUrl(data string, account string, secret *tokens.Secret, deviceId hasher := sha1.New() hasher.Write(binary) hash := account + hex.EncodeToString(hasher.Sum(nil)) - if fileHashPool[hash] != nil { + if fileHashPool[hash] != nil && time.Now().Unix() < fileHashPool[hash].Upload+31536000 { return fileHashPool[hash] } startIdx := strings.Index(data, ":") @@ -308,7 +311,7 @@ func processDataUrl(data string, account string, secret *tokens.Secret, deviceId if fileid == "" { return nil } else { - result := FileResult{Mime: mimeType, Filename: fileName, Filesize: len(binary), Fileid: fileid, Isimage: isImg, Bounds: bounds} + result := FileResult{Mime: mimeType, Filename: fileName, Filesize: len(binary), Fileid: fileid, Isimage: isImg, Bounds: bounds, Upload: time.Now().Unix()} fileHashPool[hash] = &result return &result } From d433c5f03147c4ca9d22d5947fe75bb2f8d3f2d5 Mon Sep 17 00:00:00 2001 From: xqdoo00o Date: Fri, 19 Apr 2024 11:15:35 +0800 Subject: [PATCH 2/8] unnecessory proof --- handlers.go | 9 ++++-- internal/chatgpt/request.go | 58 +++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/handlers.go b/handlers.go index 0957bf9..1f560c6 100644 --- a/handlers.go +++ b/handlers.go @@ -143,10 +143,15 @@ func nightmare(c *gin.Context) { c.JSON(500, gin.H{"error": "unable to check chat requirement"}) return } + var proofToken string + // current proof not necessary... + if false && chat_require.Proof.Required { + proofToken = chatgpt.CalcProofToken(chat_require.Proof.Seed, chat_require.Proof.Difficulty) + } // Convert the chat request to a ChatGPT request translated_request := chatgpt_request_converter.ConvertAPIRequest(original_request, account, &secret, deviceId, chat_require.Arkose.Required, chat_require.Arkose.DX, proxy_url) - response, err := chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, proxy_url) + response, err := chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, proofToken, proxy_url) if err != nil { c.JSON(500, gin.H{ "error": "error sending request", @@ -174,7 +179,7 @@ func nightmare(c *gin.Context) { if chat_require.Arkose.Required { chatgpt_request_converter.RenewTokenForRequest(&translated_request, secret.PUID, chat_require.Arkose.DX, proxy_url) } - response, err = chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, proxy_url) + response, err = chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, proofToken, proxy_url) if err != nil { c.JSON(500, gin.H{ "error": "error sending request", diff --git a/internal/chatgpt/request.go b/internal/chatgpt/request.go index 287e172..d6c80b9 100644 --- a/internal/chatgpt/request.go +++ b/internal/chatgpt/request.go @@ -5,11 +5,13 @@ import ( "bytes" "context" "encoding/base64" + "encoding/hex" "encoding/json" "freechatgpt/internal/tokens" "freechatgpt/typings" chatgpt_types "freechatgpt/typings/chatgpt" "io" + "math/rand" "net/url" "os" "strconv" @@ -18,6 +20,7 @@ import ( "time" "github.com/gorilla/websocket" + "golang.org/x/crypto/sha3" http "github.com/bogdanfinn/fhttp" tls_client "github.com/bogdanfinn/tls-client" @@ -47,6 +50,11 @@ var ( FILES_REVERSE_PROXY = os.Getenv("FILES_REVERSE_PROXY") connPool = map[string][]*connInfo{} userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" + answers = map[string]string{} + cores = []int{8, 12, 16, 24} + screens = []int{3000, 4000, 6000} + timeLocation, _ = time.LoadLocation("Asia/Shanghai") + timeLayout = "Mon Jan 2 2006 15:04:05" ) func getWSURL(token string, deviceId string, retry int) (string, error) { @@ -199,8 +207,51 @@ func SetOAICookie(uuid string) { }}) } +type ProofWork struct { + Difficulty string `json:"difficulty,omitempty"` + Required bool `json:"required"` + Seed string `json:"seed,omitempty"` +} + +func getParseTime() string { + now := time.Now() + now = now.In(timeLocation) + return now.Format(timeLayout) + " GMT+0800 (中国标准时间)" +} +func getConfig() []interface{} { + rand.New(rand.NewSource(time.Now().UnixNano())) + core := cores[rand.Intn(4)] + rand.New(rand.NewSource(time.Now().UnixNano())) + screen := screens[rand.Intn(3)] + rand.New(rand.NewSource(time.Now().UnixNano())) + return []interface{}{core + screen, getParseTime(), 4295000000 + rand.Intn(2000001) - 1000000, 0, userAgent} + +} +func CalcProofToken(seed string, diff string) string { + if answers[seed] != "" { + return answers[seed] + } + config := getConfig() + diffLen := len(diff) / 2 + hasher := sha3.New512() + for i := 0; i < 100000; i++ { + config[3] = i + json, _ := json.Marshal(config) + base := base64.StdEncoding.EncodeToString(json) + hasher.Write([]byte(seed + base)) + hash := hasher.Sum(nil) + hasher.Reset() + if hex.EncodeToString(hash[:diffLen]) <= diff { + answers[seed] = "gAAAAAB" + base + return answers[seed] + } + } + return "gAAAAABwQ8Lk5FbGpA2NcR9dShT6gYjU7VxZ4D" + base64.StdEncoding.EncodeToString([]byte(`"`+seed+`"`)) +} + type ChatRequire struct { - Token string `json:"token"` + Token string `json:"token"` + Proof ProofWork `json:"proofofwork,omitempty"` Arkose struct { Required bool `json:"required"` DX string `json:"dx,omitempty"` @@ -285,7 +336,7 @@ func getURLAttribution(secret *tokens.Secret, deviceId string, url string) strin return attr.Attribution } -func POSTconversation(message chatgpt_types.ChatGPTRequest, secret *tokens.Secret, deviceId string, chat_token string, proxy string) (*http.Response, error) { +func POSTconversation(message chatgpt_types.ChatGPTRequest, secret *tokens.Secret, deviceId string, chat_token string, proofToken string, proxy string) (*http.Response, error) { if proxy != "" { client.SetProxy(proxy) } @@ -322,6 +373,9 @@ func POSTconversation(message chatgpt_types.ChatGPTRequest, secret *tokens.Secre if chat_token != "" { request.Header.Set("Openai-Sentinel-Chat-Requirements-Token", chat_token) } + if proofToken != "" { + request.Header.Set("Openai-Sentinel-Proof-Token", proofToken) + } if secret.Token != "" { request.Header.Set("Authorization", "Bearer "+secret.Token) } From 596c3ddcbede4e97705f5fdf143dc792592d4335 Mon Sep 17 00:00:00 2001 From: xqdoo00o Date: Fri, 19 Apr 2024 11:23:04 +0800 Subject: [PATCH 3/8] gpt-4 may need proof --- handlers.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/handlers.go b/handlers.go index 1f560c6..7ca90b7 100644 --- a/handlers.go +++ b/handlers.go @@ -144,8 +144,7 @@ func nightmare(c *gin.Context) { return } var proofToken string - // current proof not necessary... - if false && chat_require.Proof.Required { + if chat_require.Proof.Required { proofToken = chatgpt.CalcProofToken(chat_require.Proof.Seed, chat_require.Proof.Difficulty) } // Convert the chat request to a ChatGPT request From 0a7512dc92408fa65a9ff2e6140424250144dcd1 Mon Sep 17 00:00:00 2001 From: xqdoo00o Date: Fri, 19 Apr 2024 11:35:22 +0800 Subject: [PATCH 4/8] fix proof type err --- internal/chatgpt/request.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/chatgpt/request.go b/internal/chatgpt/request.go index d6c80b9..c059b83 100644 --- a/internal/chatgpt/request.go +++ b/internal/chatgpt/request.go @@ -223,8 +223,7 @@ func getConfig() []interface{} { core := cores[rand.Intn(4)] rand.New(rand.NewSource(time.Now().UnixNano())) screen := screens[rand.Intn(3)] - rand.New(rand.NewSource(time.Now().UnixNano())) - return []interface{}{core + screen, getParseTime(), 4295000000 + rand.Intn(2000001) - 1000000, 0, userAgent} + return []interface{}{core + screen, getParseTime(), int64(4294705152), 0, userAgent} } func CalcProofToken(seed string, diff string) string { From b1ec8502fbd54245f40a9bf55044b152fe4b2792 Mon Sep 17 00:00:00 2001 From: xqdoo00o Date: Sun, 21 Apr 2024 02:49:41 +0800 Subject: [PATCH 5/8] add teams and account priority --- auth.go | 103 ++++++++++++++++++++++++------------ go.mod | 4 +- go.sum | 27 +++------- internal/chatgpt/request.go | 16 +++--- internal/tokens/tokens.go | 9 ++-- 5 files changed, 91 insertions(+), 68 deletions(-) diff --git a/auth.go b/auth.go index 9348e3b..af2dc58 100644 --- a/auth.go +++ b/auth.go @@ -16,15 +16,15 @@ import ( "github.com/xqdoo00o/OpenAIAuth/auth" ) -var accounts []Account +var accounts map[string]AccountInfo var validAccounts []string const interval = time.Hour * 24 -type Account struct { - Email string `json:"username"` +type AccountInfo struct { Password string `json:"password"` + Times []int `json:"times"` } type TokenExp struct { @@ -57,11 +57,28 @@ func AppendIfNone(slice []string, i string) []string { return append(slice, i) } +var TimesCounter int + func getSecret() (string, tokens.Secret) { if len(validAccounts) != 0 { account := validAccounts[0] - validAccounts = append(validAccounts[1:], account) - return account, ACCESS_TOKENS.GetSecret(account) + secret := ACCESS_TOKENS.GetSecret(account) + if TimesCounter == 0 { + TimesCounter = accounts[account].Times[0] + if secret.TeamUserID != "" && len(accounts[account].Times) == 2 { + TimesCounter += accounts[account].Times[1] + } + } + TimesCounter-- + if TimesCounter == 0 { + validAccounts = append(validAccounts[1:], account) + } + if secret.TeamUserID != "" { + if TimesCounter < accounts[account].Times[0] { + secret.TeamUserID = "" + } + } + return account, secret } else { return "", tokens.Secret{} } @@ -69,7 +86,7 @@ func getSecret() (string, tokens.Secret) { // Read accounts.txt and create a list of accounts func readAccounts() { - accounts = []Account{} + accounts = map[string]AccountInfo{} // Read accounts.txt and create a list of accounts if _, err := os.Stat("accounts.txt"); err == nil { // Each line is a proxy, put in proxies array @@ -79,23 +96,38 @@ func readAccounts() { for scanner.Scan() { // Split by : line := strings.Split(scanner.Text(), ":") - if len(line) < 2 { + length := len(line) + if length < 2 { continue } + var times []int + if length == 2 { + times = append(times, 1) + } else { + timeStrs := strings.Split(line[2], "/") + for i := 0; i < len(timeStrs); i++ { + time, err := strconv.Atoi(timeStrs[i]) + if i == 2 || err != nil || time < 1 { + break + } + times = append(times, time) + } + if len(times) == 0 { + times = append(times, 1) + } + } // Create an account - account := Account{ - Email: line[0], + accounts[line[0]] = AccountInfo{ Password: line[1], + Times: times, } - // Append to accounts - accounts = append(accounts, account) } } } -func newTimeFunc(account Account, token_list map[string]tokens.Secret, cron bool) func() { +func newTimeFunc(email string, password string, token_list map[string]tokens.Secret, cron bool) func() { return func() { - updateSingleToken(account, token_list, cron) + updateSingleToken(email, password, token_list, cron) } } @@ -127,28 +159,28 @@ func scheduleTokenPUID() { } else { ACCESS_TOKENS = tokens.NewAccessToken(token_list) validAccounts = []string{} - for _, account := range accounts { - token := token_list[account.Email].Token + for account, info := range accounts { + token := token_list[account].Token if token == "" { - updateSingleToken(account, nil, true) + updateSingleToken(account, info.Password, nil, true) } else { var toPUIDExpire time.Duration var puidTime time.Time var toExpire time.Duration - if token_list[account.Email].PUID != "" { + if token_list[account].PUID != "" { re := regexp.MustCompile(`\d{10,}`) - puidIat := re.FindString(token_list[account.Email].PUID) + puidIat := re.FindString(token_list[account].PUID) if puidIat != "" { puidIatInt, _ := strconv.ParseInt(puidIat, 10, 64) puidTime = time.Unix(puidIatInt, 0) toPUIDExpire = interval - time.Since(puidTime) if toPUIDExpire < 0 { - updateSingleToken(account, nil, false) + updateSingleToken(account, info.Password, nil, false) } } } tokenProcess: - token = ACCESS_TOKENS.GetSecret(account.Email).Token + token = ACCESS_TOKENS.GetSecret(account).Token expireTime, err := getTokenExpire(token) nowTime := time.Now() if err != nil { @@ -162,17 +194,17 @@ func scheduleTokenPUID() { if toPUIDExpire > 0 { toPUIDExpire = interval - nowTime.Sub(puidTime) if toExpire-toPUIDExpire > 2e9 { - updateSingleToken(account, nil, false) + updateSingleToken(account, info.Password, nil, false) toPUIDExpire = 0 goto tokenProcess } } if toExpire > 0 { - validAccounts = AppendIfNone(validAccounts, account.Email) - f := newTimeFunc(account, nil, true) + validAccounts = AppendIfNone(validAccounts, account) + f := newTimeFunc(account, info.Password, nil, true) time.AfterFunc(toExpire+time.Second, f) } else { - updateSingleToken(account, nil, true) + updateSingleToken(account, info.Password, nil, true) } } } @@ -180,14 +212,14 @@ func scheduleTokenPUID() { } } -func updateSingleToken(account Account, token_list map[string]tokens.Secret, cron bool) { +func updateSingleToken(email string, password string, token_list map[string]tokens.Secret, cron bool) { if os.Getenv("CF_PROXY") != "" { // exec warp-cli disconnect and connect exec.Command("warp-cli", "disconnect").Run() exec.Command("warp-cli", "connect").Run() time.Sleep(5 * time.Second) } - println("Updating access token for " + account.Email) + println("Updating access token for " + email) var proxy_url string if len(proxies) == 0 { proxy_url = "" @@ -196,16 +228,16 @@ func updateSingleToken(account Account, token_list map[string]tokens.Secret, cro // Push used proxy to the back of the list proxies = append(proxies[1:], proxies[0]) } - authenticator := auth.NewAuthenticator(account.Email, account.Password, proxy_url) + authenticator := auth.NewAuthenticator(email, password, proxy_url) err := authenticator.RenewWithCookies() if err != nil { authenticator.ResetCookies() err := authenticator.Begin() if err != nil { if token_list == nil { - ACCESS_TOKENS.Delete(account.Email) + ACCESS_TOKENS.Delete(email) for i, v := range validAccounts { - if v == account.Email { + if v == email { validAccounts = append(validAccounts[:i], validAccounts[i+1:]...) break } @@ -219,20 +251,21 @@ func updateSingleToken(account Account, token_list map[string]tokens.Secret, cro } access_token := authenticator.GetAccessToken() puid, _ := authenticator.GetPUID() + teamUserID, _ := authenticator.GetTeamUserID() if token_list != nil { - token_list[account.Email] = tokens.Secret{Token: access_token, PUID: puid} + token_list[email] = tokens.Secret{Token: access_token, PUID: puid, TeamUserID: teamUserID} } else { - ACCESS_TOKENS.Set(account.Email, access_token, puid) + ACCESS_TOKENS.Set(email, access_token, puid, teamUserID) ACCESS_TOKENS.Save() } - validAccounts = AppendIfNone(validAccounts, account.Email) + validAccounts = AppendIfNone(validAccounts, email) println("Success!") err = authenticator.SaveCookies() if err != nil { println(err.Details) } if cron { - f := newTimeFunc(account, token_list, cron) + f := newTimeFunc(email, password, token_list, cron) time.AfterFunc(interval+time.Second, f) } } @@ -241,8 +274,8 @@ func updateToken() { token_list := map[string]tokens.Secret{} validAccounts = []string{} // Loop through each account - for _, account := range accounts { - updateSingleToken(account, token_list, false) + for account, info := range accounts { + updateSingleToken(account, info.Password, token_list, false) } // Append access token to access_tokens.json ACCESS_TOKENS = tokens.NewAccessToken(token_list) diff --git a/go.mod b/go.mod index 5e86664..b60bc9b 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,9 @@ require ( github.com/gorilla/websocket v1.5.1 github.com/joho/godotenv v1.5.1 github.com/tidwall/gjson v1.17.1 - github.com/xqdoo00o/OpenAIAuth v0.0.0-20240403091529-7ef147706fc4 + github.com/xqdoo00o/OpenAIAuth v0.0.0-20240420184134-706a5d60f6c1 github.com/xqdoo00o/funcaptcha v0.0.0-20240403090732-1b604d808f6c + golang.org/x/crypto v0.22.0 golang.org/x/image v0.15.0 k8s.io/apimachinery v0.29.3 ) @@ -48,7 +49,6 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect golang.org/x/arch v0.7.0 // indirect - golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/sys v0.19.0 // indirect diff --git a/go.sum b/go.sum index bf50662..e68a09d 100644 --- a/go.sum +++ b/go.sum @@ -31,9 +31,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -42,17 +41,14 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4= github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= -github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA= github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -83,12 +79,10 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= -github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= -github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg= github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -111,13 +105,10 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 h1:YqAladjX7xpA6BM04leXMWAEjS0mTZ5kUU9KRBriQJc= github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5/go.mod h1:2JjD2zLQYH5HO74y5+aE3remJQvl6q4Sn6aWA2wD1Ng= -github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= -github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -125,8 +116,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/xqdoo00o/OpenAIAuth v0.0.0-20240403091529-7ef147706fc4 h1:Goj6yoMgADshscKkfhRpDeMxyGm2wdcHCUPj0YQ+B3c= -github.com/xqdoo00o/OpenAIAuth v0.0.0-20240403091529-7ef147706fc4/go.mod h1:XHxG7wI3Erk4nS0rwjXVF3FllYW5QxsRynnJ0GqAMCQ= +github.com/xqdoo00o/OpenAIAuth v0.0.0-20240420184134-706a5d60f6c1 h1:pSzLMgRZ8G9f6qytVm/OL97hD+qSTvhceSzDhW7SRbY= +github.com/xqdoo00o/OpenAIAuth v0.0.0-20240420184134-706a5d60f6c1/go.mod h1:XHxG7wI3Erk4nS0rwjXVF3FllYW5QxsRynnJ0GqAMCQ= github.com/xqdoo00o/funcaptcha v0.0.0-20240403090732-1b604d808f6c h1:nj17XsSTwprsZUDXLldOUZmqz7VlHsLCeXXFOE6Q+Mk= github.com/xqdoo00o/funcaptcha v0.0.0-20240403090732-1b604d808f6c/go.mod h1:7aCyoW5MHDUsoooMVLqKe0F7W9HMPUvDG3bXqw++8XA= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -147,7 +138,6 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= @@ -160,7 +150,6 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -179,12 +168,12 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -201,8 +190,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg= -k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/internal/chatgpt/request.go b/internal/chatgpt/request.go index c059b83..31938d6 100644 --- a/internal/chatgpt/request.go +++ b/internal/chatgpt/request.go @@ -357,15 +357,20 @@ func POSTconversation(message chatgpt_types.ChatGPTRequest, secret *tokens.Secre if err != nil { return &http.Response{}, err } - // Clear cookies - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } request.Header.Set("Content-Type", "application/json") request.Header.Set("User-Agent", userAgent) request.Header.Set("Accept", "text/event-stream") request.Header.Set("Oai-Device-Id", deviceId) request.Header.Set("Oai-Language", "en-US") + if secret.Token != "" { + request.Header.Set("Authorization", "Bearer "+secret.Token) + } + if secret.PUID != "" { + request.Header.Set("Cookie", "_puid="+secret.PUID+";") + } + if secret.TeamUserID != "" { + request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) + } if arkoseToken != "" { request.Header.Set("Openai-Sentinel-Arkose-Token", arkoseToken) } @@ -375,9 +380,6 @@ func POSTconversation(message chatgpt_types.ChatGPTRequest, secret *tokens.Secre if proofToken != "" { request.Header.Set("Openai-Sentinel-Proof-Token", proofToken) } - if secret.Token != "" { - request.Header.Set("Authorization", "Bearer "+secret.Token) - } if err != nil { return &http.Response{}, err } diff --git a/internal/tokens/tokens.go b/internal/tokens/tokens.go index de7307f..e956bbd 100644 --- a/internal/tokens/tokens.go +++ b/internal/tokens/tokens.go @@ -7,8 +7,9 @@ import ( ) type Secret struct { - Token string `json:"token"` - PUID string `json:"puid"` + Token string `json:"token"` + PUID string `json:"puid"` + TeamUserID string `json:"team_uid,omitempty"` } type AccessToken struct { tokens map[string]Secret @@ -21,8 +22,8 @@ func NewAccessToken(tokens map[string]Secret) AccessToken { } } -func (a *AccessToken) Set(name string, token string, puid string) { - a.tokens[name] = Secret{Token: token, PUID: puid} +func (a *AccessToken) Set(name string, token string, puid string, tuid string) { + a.tokens[name] = Secret{Token: token, PUID: puid, TeamUserID: tuid} } func (a *AccessToken) GetKeys() []string { From f50aab0cb729f35ffa4aae0f39307d836702864a Mon Sep 17 00:00:00 2001 From: xqdoo00o Date: Sun, 21 Apr 2024 14:03:29 +0800 Subject: [PATCH 6/8] add gpts and fix teams upload --- conversion/requests/chatgpt/convert.go | 12 ++++-- handlers.go | 2 +- internal/chatgpt/request.go | 53 ++++++++++++++++---------- typings/chatgpt/request.go | 25 ++++++++---- typings/official/request.go | 7 ++-- 5 files changed, 63 insertions(+), 36 deletions(-) diff --git a/conversion/requests/chatgpt/convert.go b/conversion/requests/chatgpt/convert.go index 342f39e..a0a67dc 100644 --- a/conversion/requests/chatgpt/convert.go +++ b/conversion/requests/chatgpt/convert.go @@ -22,6 +22,14 @@ func ConvertAPIRequest(api_request official_types.APIRequest, account string, se } else if strings.HasPrefix(api_request.Model, "gpt-4") { api_version = 4 chatgpt_request.Model = "gpt-4" + if len(api_request.Model) > 12 { + key := api_request.Model[6:11] + if key == "gizmo" { + val := api_request.Model[12:] + chatgpt_request.ConversationMode.Kind = "gizmo_interaction" + chatgpt_request.ConversationMode.GizmoId = val + } + } } if requireArk { token, err := arkose.GetOpenAIToken(api_version, secret.PUID, dx, proxy) @@ -31,10 +39,6 @@ func ConvertAPIRequest(api_request official_types.APIRequest, account string, se fmt.Println("Error getting Arkose token: ", err) } } - if api_request.PluginIDs != nil { - chatgpt_request.PluginIDs = api_request.PluginIDs - chatgpt_request.Model = "gpt-4-plugins" - } ifMultimodel := api_version == 4 for _, api_message := range api_request.Messages { if api_message.Role == "system" { diff --git a/handlers.go b/handlers.go index 7ca90b7..2d3acb4 100644 --- a/handlers.go +++ b/handlers.go @@ -127,7 +127,7 @@ func nightmare(c *gin.Context) { wg.Add(2) go func() { defer wg.Done() - err = chatgpt.InitWSConn(secret.Token, deviceId, uid, proxy_url) + err = chatgpt.InitWSConn(&secret, deviceId, uid, proxy_url) }() } go func() { diff --git a/internal/chatgpt/request.go b/internal/chatgpt/request.go index 31938d6..acb723c 100644 --- a/internal/chatgpt/request.go +++ b/internal/chatgpt/request.go @@ -57,7 +57,7 @@ var ( timeLayout = "Mon Jan 2 2006 15:04:05" ) -func getWSURL(token string, deviceId string, retry int) (string, error) { +func getWSURL(secret *tokens.Secret, deviceId string, retry int) (string, error) { request, err := http.NewRequest(http.MethodPost, "https://chat.openai.com/backend-api/register-websocket", nil) if err != nil { return "", err @@ -66,8 +66,14 @@ func getWSURL(token string, deviceId string, retry int) (string, error) { request.Header.Set("Accept", "*/*") request.Header.Set("Oai-Device-Id", deviceId) request.Header.Set("Oai-Language", "en-US") - if token != "" { - request.Header.Set("Authorization", "Bearer "+token) + if secret.Token != "" { + request.Header.Set("Authorization", "Bearer "+secret.Token) + } + if secret.PUID != "" { + request.Header.Set("Cookie", "_puid="+secret.PUID+";") + } + if secret.TeamUserID != "" { + request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) } response, err := client.Do(request) if err != nil { @@ -75,7 +81,7 @@ func getWSURL(token string, deviceId string, retry int) (string, error) { return "", err } time.Sleep(time.Second) // wait 1s to get ws url - return getWSURL(token, deviceId, retry+1) + return getWSURL(secret, deviceId, retry+1) } defer response.Body.Close() var WSSResp chatgpt_types.ChatGPTWSSResponse @@ -143,7 +149,8 @@ func UnlockSpecConn(token string, uuid string) { } } } -func InitWSConn(token string, deviceId string, uuid string, proxy string) error { +func InitWSConn(secret *tokens.Secret, deviceId string, uuid string, proxy string) error { + token := secret.Token + secret.TeamUserID connInfo := findAvailConn(token, uuid) conn := connInfo.conn isExpired := connInfo.expire.IsZero() || time.Now().After(connInfo.expire) @@ -156,7 +163,7 @@ func InitWSConn(token string, deviceId string, uuid string, proxy string) error conn.Close() connInfo.conn = nil } - wssURL, err := getWSURL(token, deviceId, 0) + wssURL, err := getWSURL(secret, deviceId, 0) if err != nil { return err } @@ -188,7 +195,7 @@ func InitWSConn(token string, deviceId string, uuid string, proxy string) error conn.Close() connInfo.conn = nil connInfo.lock = false - return InitWSConn(token, deviceId, uuid, proxy) + return InitWSConn(secret, deviceId, uuid, proxy) case context.DeadlineExceeded: return nil default: @@ -261,22 +268,17 @@ func CheckRequire(secret *tokens.Secret, deviceId string, proxy string) *ChatReq if proxy != "" { client.SetProxy(proxy) } - var body *bytes.Buffer + body := bytes.NewBuffer([]byte(`{}`)) var apiUrl string if secret.Token == "" { - body = bytes.NewBuffer([]byte(`{}`)) apiUrl = "https://chat.openai.com/backend-anon/sentinel/chat-requirements" } else { - body = bytes.NewBuffer([]byte(`{"conversation_mode_kind":"primary_assistant"}`)) apiUrl = "https://chat.openai.com/backend-api/sentinel/chat-requirements" } request, err := http.NewRequest(http.MethodPost, apiUrl, body) if err != nil { return nil } - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } request.Header.Set("Content-Type", "application/json") request.Header.Set("User-Agent", userAgent) request.Header.Set("Oai-Device-Id", deviceId) @@ -284,6 +286,12 @@ func CheckRequire(secret *tokens.Secret, deviceId string, proxy string) *ChatReq if secret.Token != "" { request.Header.Set("Authorization", "Bearer "+secret.Token) } + if secret.PUID != "" { + request.Header.Set("Cookie", "_puid="+secret.PUID+";") + } + if secret.TeamUserID != "" { + request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) + } response, err := client.Do(request) if err != nil { return nil @@ -309,9 +317,6 @@ func getURLAttribution(secret *tokens.Secret, deviceId string, url string) strin if err != nil { return "" } - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } request.Header.Set("Content-Type", "application/json") request.Header.Set("User-Agent", userAgent) request.Header.Set("Oai-Device-Id", deviceId) @@ -319,6 +324,12 @@ func getURLAttribution(secret *tokens.Secret, deviceId string, url string) strin if secret.Token != "" { request.Header.Set("Authorization", "Bearer "+secret.Token) } + if secret.PUID != "" { + request.Header.Set("Cookie", "_puid="+secret.PUID+";") + } + if secret.TeamUserID != "" { + request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) + } if err != nil { return "" } @@ -432,10 +443,6 @@ func GetImageSource(wg *sync.WaitGroup, url string, prompt string, secret *token if err != nil { return } - // Clear cookies - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } request.Header.Set("User-Agent", userAgent) request.Header.Set("Accept", "*/*") request.Header.Set("Oai-Device-Id", deviceId) @@ -443,6 +450,12 @@ func GetImageSource(wg *sync.WaitGroup, url string, prompt string, secret *token if secret.Token != "" { request.Header.Set("Authorization", "Bearer "+secret.Token) } + if secret.PUID != "" { + request.Header.Set("Cookie", "_puid="+secret.PUID+";") + } + if secret.TeamUserID != "" { + request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) + } response, err := client.Do(request) if err != nil { return diff --git a/typings/chatgpt/request.go b/typings/chatgpt/request.go index 762e4f7..62423c7 100644 --- a/typings/chatgpt/request.go +++ b/typings/chatgpt/request.go @@ -59,15 +59,19 @@ type Original_multimodel struct { Image Image_url `json:"image_url,omitempty"` } +type ChatGPTConvMode struct { + Kind string `json:"kind"` + GizmoId string `json:"gizmo_id,omitempty"` +} type ChatGPTRequest struct { Action string `json:"action"` + ConversationMode ChatGPTConvMode `json:"conversation_mode"` Messages []chatgpt_message `json:"messages,omitempty"` ParentMessageID string `json:"parent_message_id,omitempty"` ConversationID string `json:"conversation_id,omitempty"` Model string `json:"model"` HistoryAndTrainingDisabled bool `json:"history_and_training_disabled"` ArkoseToken string `json:"arkose_token,omitempty"` - PluginIDs []string `json:"plugin_ids,omitempty"` } type FileResp struct { File_id string `json:"file_id"` @@ -225,6 +229,7 @@ func NewChatGPTRequest() ChatGPTRequest { ParentMessageID: uuid.NewString(), Model: "text-davinci-002-render-sha", HistoryAndTrainingDisabled: disable_history, + ConversationMode: ChatGPTConvMode{Kind: "primary_assistant"}, } } func processUrl(urlstr string, account string, secret *tokens.Secret, deviceId string, proxy string) *FileResult { @@ -253,7 +258,7 @@ func processUrl(urlstr string, account string, secret *tokens.Secret, deviceId s } hasher := sha1.New() hasher.Write(binary) - hash := account + hex.EncodeToString(hasher.Sum(nil)) + hash := account + secret.TeamUserID + hex.EncodeToString(hasher.Sum(nil)) if fileHashPool[hash] != nil && time.Now().Unix() < fileHashPool[hash].Upload+31536000 { return fileHashPool[hash] } @@ -283,7 +288,7 @@ func processDataUrl(data string, account string, secret *tokens.Secret, deviceId } hasher := sha1.New() hasher.Write(binary) - hash := account + hex.EncodeToString(hasher.Sum(nil)) + hash := account + secret.TeamUserID + hex.EncodeToString(hasher.Sum(nil)) if fileHashPool[hash] != nil && time.Now().Unix() < fileHashPool[hash].Upload+31536000 { return fileHashPool[hash] } @@ -328,11 +333,14 @@ func uploadBinary(data []byte, mime string, name string, isImg bool, secret *tok } dataLen := strconv.Itoa(len(data)) request, err := http.NewRequest(http.MethodPost, "https://chat.openai.com/backend-api/files", bytes.NewBuffer([]byte(`{"file_name":"`+name+`","file_size":`+dataLen+`,"use_case":"`+fileCase+`"}`))) + if secret.Token != "" { + request.Header.Set("Authorization", "Bearer "+secret.Token) + } if secret.PUID != "" { request.Header.Set("Cookie", "_puid="+secret.PUID+";") } - if secret.Token != "" { - request.Header.Set("Authorization", "Bearer "+secret.Token) + if secret.TeamUserID != "" { + request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) } request.Header.Set("User-Agent", userAgent) request.Header.Set("Accept", "*/*") @@ -369,11 +377,14 @@ func uploadBinary(data []byte, mime string, name string, isImg bool, secret *tok return "" } request, err = http.NewRequest(http.MethodPost, "https://chat.openai.com/backend-api/files/"+fileResp.File_id+"/uploaded", bytes.NewBuffer([]byte(`{}`))) + if secret.Token != "" { + request.Header.Set("Authorization", "Bearer "+secret.Token) + } if secret.PUID != "" { request.Header.Set("Cookie", "_puid="+secret.PUID+";") } - if secret.Token != "" { - request.Header.Set("Authorization", "Bearer "+secret.Token) + if secret.TeamUserID != "" { + request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) } request.Header.Set("User-Agent", userAgent) request.Header.Set("Accept", "*/*") diff --git a/typings/official/request.go b/typings/official/request.go index 377db56..f17ab20 100644 --- a/typings/official/request.go +++ b/typings/official/request.go @@ -1,10 +1,9 @@ package official type APIRequest struct { - Messages []api_message `json:"messages"` - Stream bool `json:"stream"` - Model string `json:"model"` - PluginIDs []string `json:"plugin_ids"` + Messages []api_message `json:"messages"` + Stream bool `json:"stream"` + Model string `json:"model"` } type api_message struct { From a2bee55333ca90c1bcd331b9ae9bd5071f325eab Mon Sep 17 00:00:00 2001 From: xqdoo00o Date: Sun, 21 Apr 2024 15:16:55 +0800 Subject: [PATCH 7/8] fix docker tzdata --- internal/chatgpt/request.go | 74 +++++++++---------------------------- typings/chatgpt/request.go | 52 ++++++++++++-------------- 2 files changed, 41 insertions(+), 85 deletions(-) diff --git a/internal/chatgpt/request.go b/internal/chatgpt/request.go index acb723c..9ba8324 100644 --- a/internal/chatgpt/request.go +++ b/internal/chatgpt/request.go @@ -19,6 +19,8 @@ import ( "sync" "time" + _ "time/tzdata" + "github.com/gorilla/websocket" "golang.org/x/crypto/sha3" @@ -57,10 +59,10 @@ var ( timeLayout = "Mon Jan 2 2006 15:04:05" ) -func getWSURL(secret *tokens.Secret, deviceId string, retry int) (string, error) { - request, err := http.NewRequest(http.MethodPost, "https://chat.openai.com/backend-api/register-websocket", nil) +func newRequest(method string, url string, body io.Reader, secret *tokens.Secret, deviceId string) (*http.Request, error) { + request, err := http.NewRequest(method, url, body) if err != nil { - return "", err + return &http.Request{}, err } request.Header.Set("User-Agent", userAgent) request.Header.Set("Accept", "*/*") @@ -75,6 +77,14 @@ func getWSURL(secret *tokens.Secret, deviceId string, retry int) (string, error) if secret.TeamUserID != "" { request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) } + return request, nil +} + +func getWSURL(secret *tokens.Secret, deviceId string, retry int) (string, error) { + request, err := newRequest(http.MethodPost, "https://chat.openai.com/backend-api/register-websocket", nil, secret, deviceId) + if err != nil { + return "", err + } response, err := client.Do(request) if err != nil { if retry > 3 { @@ -275,23 +285,11 @@ func CheckRequire(secret *tokens.Secret, deviceId string, proxy string) *ChatReq } else { apiUrl = "https://chat.openai.com/backend-api/sentinel/chat-requirements" } - request, err := http.NewRequest(http.MethodPost, apiUrl, body) + request, err := newRequest(http.MethodPost, apiUrl, body, secret, deviceId) if err != nil { return nil } request.Header.Set("Content-Type", "application/json") - request.Header.Set("User-Agent", userAgent) - request.Header.Set("Oai-Device-Id", deviceId) - request.Header.Set("Oai-Language", "en-US") - if secret.Token != "" { - request.Header.Set("Authorization", "Bearer "+secret.Token) - } - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } - if secret.TeamUserID != "" { - request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) - } response, err := client.Do(request) if err != nil { return nil @@ -313,23 +311,11 @@ type urlAttr struct { } func getURLAttribution(secret *tokens.Secret, deviceId string, url string) string { - request, err := http.NewRequest(http.MethodPost, "https://chat.openai.com/backend-api/attributions", bytes.NewBuffer([]byte(`{"urls":["`+url+`"]}`))) + request, err := newRequest(http.MethodPost, "https://chat.openai.com/backend-api/attributions", bytes.NewBuffer([]byte(`{"urls":["`+url+`"]}`)), secret, deviceId) if err != nil { return "" } request.Header.Set("Content-Type", "application/json") - request.Header.Set("User-Agent", userAgent) - request.Header.Set("Oai-Device-Id", deviceId) - request.Header.Set("Oai-Language", "en-US") - if secret.Token != "" { - request.Header.Set("Authorization", "Bearer "+secret.Token) - } - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } - if secret.TeamUserID != "" { - request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) - } if err != nil { return "" } @@ -364,24 +350,11 @@ func POSTconversation(message chatgpt_types.ChatGPTRequest, secret *tokens.Secre return &http.Response{}, err } - request, err := http.NewRequest(http.MethodPost, apiUrl, bytes.NewBuffer(body_json)) + request, err := newRequest(http.MethodPost, apiUrl, bytes.NewReader(body_json), secret, deviceId) if err != nil { return &http.Response{}, err } request.Header.Set("Content-Type", "application/json") - request.Header.Set("User-Agent", userAgent) - request.Header.Set("Accept", "text/event-stream") - request.Header.Set("Oai-Device-Id", deviceId) - request.Header.Set("Oai-Language", "en-US") - if secret.Token != "" { - request.Header.Set("Authorization", "Bearer "+secret.Token) - } - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } - if secret.TeamUserID != "" { - request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) - } if arkoseToken != "" { request.Header.Set("Openai-Sentinel-Arkose-Token", arkoseToken) } @@ -439,23 +412,10 @@ type fileInfo struct { func GetImageSource(wg *sync.WaitGroup, url string, prompt string, secret *tokens.Secret, deviceId string, idx int, imgSource []string) { defer wg.Done() - request, err := http.NewRequest(http.MethodGet, url, nil) + request, err := newRequest(http.MethodGet, url, nil, secret, deviceId) if err != nil { return } - request.Header.Set("User-Agent", userAgent) - request.Header.Set("Accept", "*/*") - request.Header.Set("Oai-Device-Id", deviceId) - request.Header.Set("Oai-Language", "en-US") - if secret.Token != "" { - request.Header.Set("Authorization", "Bearer "+secret.Token) - } - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } - if secret.TeamUserID != "" { - request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) - } response, err := client.Do(request) if err != nil { return diff --git a/typings/chatgpt/request.go b/typings/chatgpt/request.go index 62423c7..727ae16 100644 --- a/typings/chatgpt/request.go +++ b/typings/chatgpt/request.go @@ -232,6 +232,28 @@ func NewChatGPTRequest() ChatGPTRequest { ConversationMode: ChatGPTConvMode{Kind: "primary_assistant"}, } } + +func newRequest(method string, url string, body io.Reader, secret *tokens.Secret, deviceId string) (*http.Request, error) { + request, err := http.NewRequest(method, url, body) + if err != nil { + return &http.Request{}, err + } + request.Header.Set("User-Agent", userAgent) + request.Header.Set("Accept", "*/*") + request.Header.Set("Oai-Device-Id", deviceId) + request.Header.Set("Oai-Language", "en-US") + if secret.Token != "" { + request.Header.Set("Authorization", "Bearer "+secret.Token) + } + if secret.PUID != "" { + request.Header.Set("Cookie", "_puid="+secret.PUID+";") + } + if secret.TeamUserID != "" { + request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) + } + return request, nil +} + func processUrl(urlstr string, account string, secret *tokens.Secret, deviceId string, proxy string) *FileResult { if proxy != "" { client.SetProxy(proxy) @@ -332,20 +354,7 @@ func uploadBinary(data []byte, mime string, name string, isImg bool, secret *tok fileCase = "ace_upload" } dataLen := strconv.Itoa(len(data)) - request, err := http.NewRequest(http.MethodPost, "https://chat.openai.com/backend-api/files", bytes.NewBuffer([]byte(`{"file_name":"`+name+`","file_size":`+dataLen+`,"use_case":"`+fileCase+`"}`))) - if secret.Token != "" { - request.Header.Set("Authorization", "Bearer "+secret.Token) - } - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } - if secret.TeamUserID != "" { - request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) - } - request.Header.Set("User-Agent", userAgent) - request.Header.Set("Accept", "*/*") - request.Header.Set("Oai-Device-Id", deviceId) - request.Header.Set("Oai-Language", "en-US") + request, err := newRequest(http.MethodPost, "https://chat.openai.com/backend-api/files", bytes.NewBuffer([]byte(`{"file_name":"`+name+`","file_size":`+dataLen+`,"use_case":"`+fileCase+`"}`)), secret, deviceId) if err != nil { return "" } @@ -376,20 +385,7 @@ func uploadBinary(data []byte, mime string, name string, isImg bool, secret *tok if response.StatusCode != 201 { return "" } - request, err = http.NewRequest(http.MethodPost, "https://chat.openai.com/backend-api/files/"+fileResp.File_id+"/uploaded", bytes.NewBuffer([]byte(`{}`))) - if secret.Token != "" { - request.Header.Set("Authorization", "Bearer "+secret.Token) - } - if secret.PUID != "" { - request.Header.Set("Cookie", "_puid="+secret.PUID+";") - } - if secret.TeamUserID != "" { - request.Header.Set("Chatgpt-Account-Id", secret.TeamUserID) - } - request.Header.Set("User-Agent", userAgent) - request.Header.Set("Accept", "*/*") - request.Header.Set("Oai-Device-Id", deviceId) - request.Header.Set("Oai-Language", "en-US") + request, err = newRequest(http.MethodPost, "https://chat.openai.com/backend-api/files/"+fileResp.File_id+"/uploaded", bytes.NewBuffer([]byte(`{}`)), secret, deviceId) if err != nil { return "" } From 5b123d30fb703353a2716c28b281d86519c0bc3b Mon Sep 17 00:00:00 2001 From: bi1101 Date: Wed, 24 Apr 2024 02:18:07 +0700 Subject: [PATCH 8/8] up dep --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 6192adb..129269b 100644 --- a/go.mod +++ b/go.mod @@ -19,8 +19,8 @@ require ( github.com/tidwall/gjson v1.17.1 github.com/xqdoo00o/OpenAIAuth v0.0.0-20240420184134-706a5d60f6c1 github.com/xqdoo00o/funcaptcha v0.0.0-20240403090732-1b604d808f6c - golang.org/x/crypto v0.22.0 github.com/zhu327/gemini-openai-proxy v0.0.0-20240328042054-d2c6c4cdff01 + golang.org/x/crypto v0.22.0 golang.org/x/image v0.15.0 google.golang.org/api v0.172.0 k8s.io/apimachinery v0.29.3