Skip to content

Commit

Permalink
修改、新增openai chat api和web通信可以预配置api key和token功能
Browse files Browse the repository at this point in the history
  • Loading branch information
zatxm committed May 22, 2024
1 parent b3ad4a7 commit 90e2501
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 33 deletions.
8 changes: 2 additions & 6 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,14 @@ func main() {
app.Any("/public-api/*path", oapi.DoWeb("public-api"))

// 免登录chat会话
app.Post("/backend-anon/conversation", oapi.DoAnon())
app.Post("/backend-anon/conversation", oapi.DoAnonOrigin())
app.Post("/backend-anon/web2api", func(c *fhblade.Context) error {
return oapi.DoWebToApi(c, "backend-anon")
})

// middleware - check authorization
// middleware
app.Use(func(next fhblade.Handler) fhblade.Handler {
return func(c *fhblade.Context) error {
authorization := c.Request().Header("Authorization")
if authorization == "" {
return c.JSONAndStatus(http.StatusUnauthorized, fhblade.H{"errorMessage": "please provide a valid access token or api key in 'Authorization' header"})
}
// cors
c.Response().SetHeader("Access-Control-Allow-Origin", "*")
c.Response().SetHeader("Access-Control-Allow-Headers", "*")
Expand Down
15 changes: 15 additions & 0 deletions etc/c.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ openai:
# 不设置默认官方https://chatgpt.com容易出盾
# 目前chat.openai.com还能用,建议设置成这个
chat_web_url: https://chat.openai.com
# api密钥
api_keys:
-
# 密钥标识,可通过头部传递x-auth-id识别
id: 10001
# 密钥
val: sk-proj-HduBcfGGimFxxxxgohfUZCXKm
# web chat token
# 通过登录https://chatgpt.com/api/auth/session获取
web_sessions:
-
# 密钥标识,可通过头部传递x-auth-id识别
id: 10001
# accessToken
val: eyJhbGciOiJSUzxxxe5w50h7ls7rIf4onG59fIFCJAwsoyyvjq7KUrI3nI7lwA

# 谷歌gemini接口
# https://makersuite.google.com/app/apikey申请
Expand Down
25 changes: 11 additions & 14 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ type httpsInfo struct {
}

type openai struct {
AuthProxyUrl string `yaml:"auth_proxy_url"`
CookiePath string `yaml:"cookie_path"`
ChatWebUrl string `yaml:"chat_web_url"`
AuthProxyUrl string `yaml:"auth_proxy_url"`
CookiePath string `yaml:"cookie_path"`
ChatWebUrl string `yaml:"chat_web_url"`
ApiKeys []ApiKeyMap `yaml:"api_keys"`
WebSessions []ApiKeyMap `yaml:"web_sessions"`
}

type gemini struct {
Expand Down Expand Up @@ -85,21 +87,16 @@ type cozeApiBot struct {
}

type claude struct {
ProxyUrl string `yaml:"proxy_url"`
ApiVersion string `yaml:"api_version"`
WebSessions []websession `yaml:"web_sessions"`
ApiKeys []claudeApiKey `yaml:"api_keys"`
ProxyUrl string `yaml:"proxy_url"`
ApiVersion string `yaml:"api_version"`
WebSessions []ApiKeyMap `yaml:"web_sessions"`
ApiKeys []ApiKeyMap `yaml:"api_keys"`
}

type websession struct {
type ApiKeyMap struct {
ID string `yaml:"id"`
Val string `yaml:"val"`
OrganizationId string `yaml:"organization_id"`
}

type claudeApiKey struct {
ID string `yaml:"id"`
Val string `yaml:"val"`
OrganizationId string `yaml:"organization_id,omitempty"`
}

func V() *Config {
Expand Down
57 changes: 56 additions & 1 deletion internal/openai/api/platform.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package api

import (
"math/rand"
"strings"
"time"

http "github.com/bogdanfinn/fhttp"
"github.com/bogdanfinn/fhttp/httputil"
"github.com/zatxm/any-proxy/internal/client"
"github.com/zatxm/any-proxy/internal/config"
"github.com/zatxm/any-proxy/internal/vars"
"github.com/zatxm/fhblade"
tlsClient "github.com/zatxm/tls-client"
Expand All @@ -24,12 +29,16 @@ func DoHttp(c *fhblade.Context, path string) error {
if accept == "" {
accept = "*/*"
}
auth, index := parseAuth(c, "api", "")
if index != "" {
c.Response().SetHeader("x-auth-id", index)
}
c.Request().Req().Header = http.Header{
"Accept": {accept},
"Accept-Encoding": {vars.AcceptEncoding},
"User-Agent": {vars.UserAgentOkHttp},
"Content-Type": {vars.ContentTypeJSON},
"Authorization": {c.Request().Header("Authorization")},
"Authorization": {"Bearer " + auth},
}
query := c.Request().RawQuery()
goProxy := httputil.ReverseProxy{
Expand All @@ -45,3 +54,49 @@ func DoHttp(c *fhblade.Context, path string) error {
goProxy.ServeHTTP(c.Response().Rw(), c.Request().Req())
return nil
}

// tag: api和web两种
func parseAuth(c *fhblade.Context, tag string, index string) (string, string) {
auth := c.Request().Header("Authorization")
if auth != "" {
if strings.HasPrefix(auth, "Bearer ") {
return strings.TrimPrefix(auth, "Bearer "), ""
}
return auth, ""
}

var keys []config.ApiKeyMap
if tag == "web" {
keys = config.V().Openai.WebSessions
} else {
keys = config.V().Openai.ApiKeys
}
l := len(keys)
if l == 0 {
return "", ""
}

hIndex := c.Request().Header("x-auth-id")
if hIndex != "" {
index = hIndex
}
if index != "" {
for k := range keys {
v := keys[k]
if index == v.ID {
return v.Val, index
}
}
return "", ""
}

if l == 1 {
v := keys[0]
return v.Val, v.ID
}

rand.Seed(time.Now().UnixNano())
i := rand.Intn(l)
v := keys[i]
return v.Val, v.ID
}
35 changes: 23 additions & 12 deletions internal/openai/api/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func DoWeb(tag string) func(*fhblade.Context) error {
yPath := c.Get("path")
// 提问问题,专门处理
if yPath == "conversation" && c.Request().Method() == "POST" {
return DoAsk(c, tag)
return DoAskOrigin(c, tag)
}
if yPath == "web2api" && c.Request().Method() == "POST" {
return DoWebToApi(c, tag)
Expand Down Expand Up @@ -82,7 +82,7 @@ func DoWeb(tag string) func(*fhblade.Context) error {
}
}

func DoAsk(c *fhblade.Context, tag string) error {
func DoAskOrigin(c *fhblade.Context, tag string) error {
// 参数
var p types.OpenAiCompletionChatRequest
if err := c.ShouldBindJSON(&p); err != nil {
Expand All @@ -94,12 +94,12 @@ func DoAsk(c *fhblade.Context, tag string) error {
},
})
}
auth := c.Request().Header("Authorization")
auth, index := parseAuth(c, "web", "")
resp, code, err := askConversationWebHttp(p, tag, auth)
if err != nil {
return c.JSONAndStatus(code, err)
}
return handleOriginStreamData(c, resp)
return handleOriginStreamData(c, resp, index)
}

func DoWebToApi(c *fhblade.Context, tag string) error {
Expand All @@ -114,12 +114,12 @@ func DoWebToApi(c *fhblade.Context, tag string) error {
},
})
}
auth := c.Request().Header("Authorization")
auth, index := parseAuth(c, "web", "")
resp, code, err := askConversationWebHttp(p, tag, auth)
if err != nil {
return c.JSONAndStatus(code, err)
}
return handleV1StreamData(c, resp)
return handleV1StreamData(c, resp, index)
}

func askConversationWebHttp(p types.OpenAiCompletionChatRequest, mt, auth string) (*http.Response, int, *types.ErrorResponse) {
Expand Down Expand Up @@ -275,9 +275,12 @@ func askConversationWebHttp(p types.OpenAiCompletionChatRequest, mt, auth string
return resp, resp.StatusCode, nil
}

func handleOriginStreamData(c *fhblade.Context, resp *http.Response) error {
func handleOriginStreamData(c *fhblade.Context, resp *http.Response, index string) error {
defer resp.Body.Close()
if strings.Contains(resp.Header.Get("Content-Type"), "event-stream") {
if index != "" {
c.Response().SetHeader("x-auth-id", index)
}
return c.Reader(resp.Body)
}
rw := c.Response().Rw()
Expand Down Expand Up @@ -369,6 +372,9 @@ func handleOriginStreamData(c *fhblade.Context, resp *http.Response) error {
header.Set("Cache-Control", "no-cache")
header.Set("Connection", "keep-alive")
header.Set("Access-Control-Allow-Origin", "*")
if index != "" {
header.Set("x-auth-id", index)
}
rw.WriteHeader(200)

cancle := make(chan struct{})
Expand Down Expand Up @@ -426,7 +432,7 @@ func handleOriginStreamData(c *fhblade.Context, resp *http.Response) error {
return nil
}

func handleV1StreamData(c *fhblade.Context, resp *http.Response) error {
func handleV1StreamData(c *fhblade.Context, resp *http.Response, index string) error {
defer resp.Body.Close()
rw := c.Response().Rw()
flusher, ok := rw.(http.Flusher)
Expand Down Expand Up @@ -497,6 +503,7 @@ func handleV1StreamData(c *fhblade.Context, resp *http.Response) error {
Object: "chat.completion.chunk",
OpenAi: &types.OpenAiConversation{
ID: chatRes.ConversationID,
Index: index,
ParentMessageId: chatRes.Message.Metadata.ParentId,
LastMessageId: chatRes.Message.ID,
},
Expand Down Expand Up @@ -695,7 +702,7 @@ func handleV1StreamData(c *fhblade.Context, resp *http.Response) error {
return nil
}

func DoAnon() func(*fhblade.Context) error {
func DoAnonOrigin() func(*fhblade.Context) error {
return func(c *fhblade.Context) error {
// 参数
var p types.OpenAiCompletionChatRequest
Expand All @@ -712,7 +719,7 @@ func DoAnon() func(*fhblade.Context) error {
if err != nil {
return c.JSONAndStatus(code, err)
}
return handleOriginStreamData(c, resp)
return handleOriginStreamData(c, resp, "")
}
}

Expand Down Expand Up @@ -799,7 +806,11 @@ func DoChatCompletionsByWeb(c *fhblade.Context, p types.ChatCompletionRequest) e
if p.OpenAi.ArkoseToken != "" {
rp.ArkoseToken = p.OpenAi.ArkoseToken
}
auth := c.Request().Header("Authorization")
reqIndex := ""
if p.OpenAi != nil && p.OpenAi.Conversation != nil {
reqIndex = p.OpenAi.Conversation.Index
}
auth, index := parseAuth(c, "web", reqIndex)
mt := "backend-api"
if auth == "" {
mt = "backend-anon"
Expand All @@ -808,5 +819,5 @@ func DoChatCompletionsByWeb(c *fhblade.Context, p types.ChatCompletionRequest) e
if err != nil {
return c.JSONAndStatus(code, err)
}
return handleV1StreamData(c, resp)
return handleV1StreamData(c, resp, index)
}
1 change: 1 addition & 0 deletions internal/types/openai.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ type OpenAiCompletionRequest struct {

type OpenAiConversation struct {
ID string `json:"conversation_id"`
Index string `json:"index,omitempty"`
ParentMessageId string `json:"parent_message_id"`
LastMessageId string `json:"last_message_id"`
}
Expand Down

0 comments on commit 90e2501

Please sign in to comment.