Skip to content

Commit

Permalink
Merge branch 'pr/27' into Add-Gemini
Browse files Browse the repository at this point in the history
  • Loading branch information
bi1101 committed Jul 20, 2024
1 parent 2839043 commit 1299e39
Show file tree
Hide file tree
Showing 10 changed files with 490 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.20'
go-version: '1.22'

- name: Build
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
go-version: 1.22

- name: Build
run: go build -o bin/ .
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Use the official Golang image as the builder
FROM golang:1.22 as builder
FROM golang:alpine AS builder

# Enable CGO to use C libraries (set to 0 to disable it)
# We set it to 0 to build a fully static binary for our final image
Expand Down
19 changes: 11 additions & 8 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,20 @@ func scheduleTokenPUID() {
}
}
tokenProcess:
token = ACCESS_TOKENS.GetSecret(account).Token
expireTime, err := getTokenExpire(token)
nowTime := time.Now()
if err != nil {
toExpire = interval - nowTime.Sub(stat.ModTime())
} else {
toExpire = expireTime.Sub(nowTime)
if toExpire > 0 {
toExpire = toExpire % interval
token = ACCESS_TOKENS.GetSecret(account).Token
if token != "" {
expireTime, err := getTokenExpire(token)
if err == nil {
toExpire = expireTime.Sub(nowTime)
if toExpire > 0 {
toExpire = toExpire % interval
}
}
}
if toExpire == 0 {
toExpire = interval - nowTime.Sub(stat.ModTime())
}
if toPUIDExpire > 0 {
toPUIDExpire = interval - nowTime.Sub(puidTime)
if toExpire-toPUIDExpire > 2e9 {
Expand Down
9 changes: 4 additions & 5 deletions conversion/requests/chatgpt/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ var gptsRegexp = regexp.MustCompile(`-gizmo-g-(\w+)`)

func ConvertAPIRequest(api_request official_types.APIRequest, account string, secret *tokens.Secret, deviceId string, proxy string) chatgpt_types.ChatGPTRequest {
chatgpt_request := chatgpt_types.NewChatGPTRequest()
if strings.HasPrefix(api_request.Model, "gpt-3.5") {
chatgpt_request.Model = "text-davinci-002-render-sha"
if strings.HasPrefix(api_request.Model, "gpt-4o-mini") || strings.HasPrefix(api_request.Model, "gpt-3.5") {
chatgpt_request.Model = "gpt-4o-mini"
} else if strings.HasPrefix(api_request.Model, "gpt-4o") {
chatgpt_request.Model = "gpt-4o"
} else if strings.HasPrefix(api_request.Model, "gpt-4") {
chatgpt_request.Model = "gpt-4"
if strings.HasPrefix(api_request.Model, "gpt-4o") {
chatgpt_request.Model = "gpt-4o"
}
}
matches := gptsRegexp.FindStringSubmatch(api_request.Model)
if len(matches) == 2 {
Expand Down
8 changes: 3 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
module freechatgpt

go 1.21.1

toolchain go1.22.0
go 1.22

require (
github.com/PuerkitoBio/goquery v1.9.2
Expand All @@ -17,8 +15,8 @@ require (
github.com/joho/godotenv v1.5.1
github.com/sashabaranov/go-openai v1.25.0
github.com/tidwall/gjson v1.17.1
github.com/xqdoo00o/OpenAIAuth v0.0.0-20240617101336-7c21c3eb80ad
github.com/xqdoo00o/funcaptcha v0.0.0-20240507071758-6c32cfc34bdc
github.com/xqdoo00o/OpenAIAuth v0.0.0-20240701110453-a742f7a5ea18
github.com/xqdoo00o/funcaptcha v0.0.0-20240701110249-093b35d56d32
github.com/zhu327/gemini-openai-proxy v0.0.0-20240614084250-9d1fbf627a52
golang.org/x/crypto v0.24.0
golang.org/x/image v0.15.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,10 @@ 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-20240617101336-7c21c3eb80ad h1:tVSKDuoBYy26TbeAK42hiicm+TdHVrC19GWnpHl10YY=
github.com/xqdoo00o/OpenAIAuth v0.0.0-20240617101336-7c21c3eb80ad/go.mod h1:TOXe2RBzDx5/w2RYzP7C1WNfNJx1wEVOSkCBcGSaNrM=
github.com/xqdoo00o/funcaptcha v0.0.0-20240507071758-6c32cfc34bdc h1:GA82q8G/mh5LLaBAo3UWw4zvxk/BlarGSuonyK4tz3Y=
github.com/xqdoo00o/funcaptcha v0.0.0-20240507071758-6c32cfc34bdc/go.mod h1:MmsYdzgYjO6NQYNS8vtecBWUFWwD4TApVzMp8iwKiR0=
github.com/xqdoo00o/OpenAIAuth v0.0.0-20240701110453-a742f7a5ea18 h1:4Q+83OuwbY25gGtFK2fv5O+AIVmn7WI0NPH79u0HH0M=
github.com/xqdoo00o/OpenAIAuth v0.0.0-20240701110453-a742f7a5ea18/go.mod h1:fwYwpN94kChGIoana10/wD+ytALJbG2I8JQvwMhOVKE=
github.com/xqdoo00o/funcaptcha v0.0.0-20240701110249-093b35d56d32 h1:6QUL4meBfwSu1CRqrsYVPQxBTa0yt/9NKl8sUt14FEo=
github.com/xqdoo00o/funcaptcha v0.0.0-20240701110249-093b35d56d32/go.mod h1:MmsYdzgYjO6NQYNS8vtecBWUFWwD4TApVzMp8iwKiR0=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zhu327/gemini-openai-proxy v0.0.0-20240516031111-9277c7e72421 h1:GIoH93Ylc9IiCVoKiniHBctTNCAvzllDg4iA+27k3Zo=
github.com/zhu327/gemini-openai-proxy v0.0.0-20240516031111-9277c7e72421/go.mod h1:np6NnsU7xC3JTdGlOAOvWSudER6P43EnDhEvYrEL1Vc=
Expand Down
43 changes: 33 additions & 10 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ func simulateModel(c *gin.Context) {
"created": 1688888888,
"owned_by": "chatgpt-to-api",
},
{
"id": "gpt-4o",
"object": "model",
"created": 1688888888,
"owned_by": "chatgpt-to-api",
},
{
"id": "gpt-4o-mini",
"object": "model",
"created": 1688888888,
"owned_by": "chatgpt-to-api",
},
{
"id": "gemini-pro",
"object": "model",
Expand All @@ -98,6 +110,7 @@ func generateUUID(name string) string {
}
func nightmare(c *gin.Context) {
var original_request official_types.APIRequest
var err error
if c.Request.ContentLength == 0 {
c.Status(http.StatusBadRequest)
return
Expand Down Expand Up @@ -146,8 +159,7 @@ func nightmare(c *gin.Context) {
deviceId = generateUUID(account)
chatgpt.SetOAICookie(deviceId)
}
chat_require := chatgpt.CheckRequire(&secret, deviceId, proxy_url)
var err error
chat_require, p := chatgpt.CheckRequire(&secret, deviceId, proxy_url)
if chat_require == nil {
c.JSON(500, gin.H{"error": "unable to check chat requirement"})
return
Expand All @@ -160,13 +172,17 @@ func nightmare(c *gin.Context) {
if chat_require.Arkose.Required {
arkoseToken, err = arkose.GetOpenAIToken(4, secret.PUID, chat_require.Arkose.DX, proxy_url)
if err != nil {
println("Error getting Arkose token: ", err)
println("Error getting Arkose token: ", err.Error())
}
}
var turnstileToken string
if chat_require.Turnstile.Required {
turnstileToken = chatgpt.ProcessTurnstile(chat_require.Turnstile.DX, p)
}
// Convert the chat request to a ChatGPT request
translated_request := chatgpt_request_converter.ConvertAPIRequest(original_request, account, &secret, deviceId, proxy_url)

response, err := chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, arkoseToken, proofToken, proxy_url)
response, err := chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, arkoseToken, proofToken, turnstileToken, proxy_url)
if err != nil {
c.JSON(500, gin.H{
"error": "error sending request",
Expand All @@ -191,17 +207,20 @@ func nightmare(c *gin.Context) {
translated_request.Action = "continue"
translated_request.ConversationID = continue_info.ConversationID
translated_request.ParentMessageID = continue_info.ParentID
chat_require = chatgpt.CheckRequire(&secret, deviceId, proxy_url)
chat_require, _ = chatgpt.CheckRequire(&secret, deviceId, proxy_url)
if chat_require.Proof.Required {
proofToken = chatgpt.CalcProofToken(chat_require, proxy_url)
}
if chat_require.Arkose.Required {
arkoseToken, err = arkose.GetOpenAIToken(4, secret.PUID, chat_require.Arkose.DX, proxy_url)
if err != nil {
println("Error getting Arkose token: ", err)
println("Error getting Arkose token: ", err.Error())
}
}
response, err = chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, arkoseToken, proofToken, proxy_url)
if chat_require.Turnstile.Required {
turnstileToken = chatgpt.ProcessTurnstile(chat_require.Turnstile.DX, p)
}
response, err = chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, arkoseToken, proofToken, turnstileToken, proxy_url)
if err != nil {
c.JSON(500, gin.H{
"error": "error sending request",
Expand Down Expand Up @@ -275,7 +294,7 @@ func tts(c *gin.Context) {
}
var deviceId = generateUUID(account)
chatgpt.SetOAICookie(deviceId)
chat_require := chatgpt.CheckRequire(&secret, deviceId, proxy_url)
chat_require, p := chatgpt.CheckRequire(&secret, deviceId, proxy_url)
if chat_require == nil {
c.JSON(500, gin.H{"error": "unable to check chat requirement"})
return
Expand All @@ -288,13 +307,17 @@ func tts(c *gin.Context) {
if chat_require.Arkose.Required {
arkoseToken, err = arkose.GetOpenAIToken(4, secret.PUID, chat_require.Arkose.DX, proxy_url)
if err != nil {
println("Error getting Arkose token: ", err)
println("Error getting Arkose token: ", err.Error())
}
}
var turnstileToken string
if chat_require.Turnstile.Required {
turnstileToken = chatgpt.ProcessTurnstile(chat_require.Turnstile.DX, p)
}
// Convert the chat request to a ChatGPT request
translated_request := chatgpt_request_converter.ConvertTTSAPIRequest(original_request.Input)

response, err := chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, arkoseToken, proofToken, proxy_url)
response, err := chatgpt.POSTconversation(translated_request, &secret, deviceId, chat_require.Token, arkoseToken, proofToken, turnstileToken, proxy_url)
if err != nil {
c.JSON(500, gin.H{"error": "error sending request"})
return
Expand Down
44 changes: 33 additions & 11 deletions internal/chatgpt/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,14 @@ type ChatRequire struct {
Required bool `json:"required"`
DX string `json:"dx,omitempty"`
} `json:"arkose"`
Turnstile struct {
Required bool `json:"required"`
DX string `json:"dx,omitempty"`
} `json:"turnstile"`
ForceLogin bool `json:"force_login,omitempty"`
}

func CheckRequire(secret *tokens.Secret, deviceId string, proxy string) *ChatRequire {
func CheckRequire(secret *tokens.Secret, deviceId string, proxy string) (*ChatRequire, string) {
if proxy != "" {
client.SetProxy(proxy)
}
Expand All @@ -216,23 +220,23 @@ func CheckRequire(secret *tokens.Secret, deviceId string, proxy string) *ChatReq
}
request, err := newRequest(http.MethodPost, apiUrl, body, secret, deviceId)
if err != nil {
return nil
return nil, ""
}
request.Header.Set("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
return nil
return nil, ""
}
defer response.Body.Close()
var require ChatRequire
err = json.NewDecoder(response.Body).Decode(&require)
if err != nil {
return nil
return nil, ""
}
if require.ForceLogin {
return nil
return nil, ""
}
return &require
return &require, cachedRequireProof
}

var urlAttrMap = make(map[string]string)
Expand All @@ -248,9 +252,6 @@ func getURLAttribution(secret *tokens.Secret, deviceId string, url string) strin
return ""
}
request.Header.Set("Content-Type", "application/json")
if err != nil {
return ""
}
response, err := client.Do(request)
if err != nil {
return ""
Expand All @@ -264,7 +265,7 @@ func getURLAttribution(secret *tokens.Secret, deviceId string, url string) strin
return attr.Attribution
}

func POSTconversation(message ChatGPTRequest, secret *tokens.Secret, deviceId string, chat_token string, arkoseToken string, proofToken string, proxy string) (*http.Response, error) {
func POSTconversation(message ChatGPTRequest, secret *tokens.Secret, deviceId string, chat_token string, arkoseToken string, proofToken string, turnstileToken string, proxy string) (*http.Response, error) {
if proxy != "" {
client.SetProxy(proxy)
}
Expand Down Expand Up @@ -304,12 +305,15 @@ func POSTconversation(message ChatGPTRequest, secret *tokens.Secret, deviceId st
if proofToken != "" {
request.Header.Set("Openai-Sentinel-Proof-Token", proofToken)
}
if turnstileToken != "" {
request.Header.Set("Openai-Sentinel-Turnstile-Token", turnstileToken)
}
request.Header.Set("Origin", "https://chatgpt.com")
request.Header.Set("Referer", "https://chatgpt.com/")
response, err := client.Do(request)
if err != nil {
return &http.Response{}, err
}
response, err := client.Do(request)
return response, err
}

Expand Down Expand Up @@ -382,7 +386,25 @@ func GetImageSource(wg *sync.WaitGroup, url string, prompt string, secret *token
if err != nil || file_info.Status != "success" {
return
}
// if strings.HasPrefix(file_info.DownloadURL, "http") {
imgSource[idx] = "[![image](" + file_info.DownloadURL + " \"" + prompt + "\")](" + file_info.DownloadURL + ")"
// } else {
// req, err := newRequest(http.MethodGet, "https://chatgpt.com"+file_info.DownloadURL, nil, secret, deviceId)
// req.Header.Set("Accept", "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8")
// if err != nil {
// return
// }
// client.SetFollowRedirect(false)
// resp, err := client.Do(req)
// if err != nil {
// return
// }
// defer resp.Body.Close()
// redirURL := resp.Header.Get("Location")
// if redirURL != "" {
// imgSource[idx] = "[![image](" + redirURL + " \"" + prompt + "\")](" + redirURL + ")"
// }
// }
}

func Handler(c *gin.Context, response *http.Response, secret *tokens.Secret, proxy string, deviceId string, uuid string, stream bool) (string, *ContinueInfo) {
Expand Down
Loading

0 comments on commit 1299e39

Please sign in to comment.