diff --git a/api/api.go b/api/api.go index 50c51dd..e77e146 100644 --- a/api/api.go +++ b/api/api.go @@ -30,7 +30,8 @@ func init() { group.GET("/gpts/editor", Editor) group.GET("/gpts/editor/:slug", Slug) group.GET("/g/:gizmoId/c/:convId", GC) - group.GET(("/gpts/mine"), Mine) + group.GET("/gpts/mine", Mine) + group.GET("/gpts", Gpts) group.GET("/login", Login) group.GET("/share/:shareId", Share) diff --git a/api/index.go b/api/index.go index bb48cdd..8e72499 100644 --- a/api/index.go +++ b/api/index.go @@ -60,7 +60,7 @@ func Index(r *ghttp.Request) { if model != "" { propsJson.Set("query.model", model) } - propsJson.Set("buildId", config.CacheBuildId) + propsJson.Set("buildId", config.BuildId) propsJson.Set("assetPrefix", config.AssetPrefix) r.Response.WriteTpl(config.CacheBuildId+"/chat.html", g.Map{ @@ -117,7 +117,7 @@ func C(r *ghttp.Request) { propsJson := gjson.New(props) propsJson.Set("query.default.1", convId) - propsJson.Set("buildId", config.CacheBuildId) + propsJson.Set("buildId", config.BuildId) propsJson.Set("assetPrefix", config.AssetPrefix) r.Response.WriteTpl(config.CacheBuildId+"/chat.html", g.Map{ @@ -128,6 +128,59 @@ func C(r *ghttp.Request) { }) } +// Gpts +func Gpts(r *ghttp.Request) { + + if r.Session.MustGet("offical-session").IsEmpty() { + r.Session.RemoveAll() + r.Response.RedirectTo("/login") + return + } + props := ` + { + "props": { + "pageProps": { + "user": { + "id": "user-xyhelper", + "name": "admin@openai.com", + "email": "admin@openai.com", + "image": "/avatars.png", + "picture": "/avatars.png", + "idp": "auth0", + "iat": 2699699364, + "mfa": false, + "groups": [] + }, + "serviceStatus": {}, + "userCountry": "US", + "serviceAnnouncement": { "public": {}, "paid": {} }, + "serverPrimedAllowBrowserStorageValue": true, + "canManageBrowserStorage": false, + "ageVerificationDeadline": null, + "showCookieConsentBanner": false + }, + "__N_SSP": true + }, + "page": "/gpts", + "query": {}, + "buildId": "wtXFegAXt6bfbujLr1e7S", + "assetPrefix": "", + "isFallback": false, + "gssp": true, + "scriptLoader": [] + } + ` + propsJson := gjson.New(props) + propsJson.Set("buildId", config.BuildId) + + r.Response.WriteTpl(config.CacheBuildId+"/gpts.html", g.Map{ + "arkoseUrl": config.ArkoseUrl, + "props": propsJson, + "assetPrefix": config.AssetPrefix, + "envScript": config.GetEnvScript(r.GetCtx()), + }) +} + // Discovery 发现 func Discovery(r *ghttp.Request) { @@ -171,7 +224,7 @@ func Discovery(r *ghttp.Request) { } ` propsJson := gjson.New(props) - propsJson.Set("buildId", config.CacheBuildId) + propsJson.Set("buildId", config.BuildId) r.Response.WriteTpl(config.CacheBuildId+"/discovery.html", g.Map{ "arkoseUrl": config.ArkoseUrl, @@ -225,7 +278,7 @@ func Editor(r *ghttp.Request) { } ` propsJson := gjson.New(props) - propsJson.Set("buildId", config.CacheBuildId) + propsJson.Set("buildId", config.BuildId) propsJson.Set("assetPrefix", config.AssetPrefix) // if slug != "" { @@ -289,7 +342,7 @@ func Slug(r *ghttp.Request) { propsJson := gjson.New(props) propsJson.Set("query.slug", slug) - propsJson.Set("buildId", config.CacheBuildId) + propsJson.Set("buildId", config.BuildId) propsJson.Set("assetPrefix", config.AssetPrefix) r.Response.WriteTpl(config.CacheBuildId+"/slug.html", g.Map{ @@ -347,7 +400,7 @@ func G(r *ghttp.Request) { ` propsJson := gjson.New(props) propsJson.Set("query.gizmoId", gizmoId) - propsJson.Set("buildId", config.CacheBuildId) + propsJson.Set("buildId", config.BuildId) propsJson.Set("assetPrefix", config.AssetPrefix) r.Response.WriteTpl(config.CacheBuildId+"/g.html", g.Map{ @@ -409,7 +462,7 @@ func GC(r *ghttp.Request) { propsJson := gjson.New(props) propsJson.Set("query.gizmoId", gizmoId) propsJson.Set("query.convId", convId) - propsJson.Set("buildId", config.CacheBuildId) + propsJson.Set("buildId", config.BuildId) r.Response.WriteTpl(config.CacheBuildId+"/gc.html", g.Map{ "arkoseUrl": config.ArkoseUrl, @@ -464,7 +517,7 @@ func Mine(r *ghttp.Request) { "scriptLoader": [] }` propsJson := gjson.New(props) - propsJson.Set("buildId", config.CacheBuildId) + propsJson.Set("buildId", config.BuildId) propsJson.Set("assetPrefix", config.AssetPrefix) r.Response.WriteTpl(config.CacheBuildId+"/mine.html", g.Map{ diff --git a/backend-api/backend-api.go b/backend-api/backend-api.go index 468f754..0e9c443 100644 --- a/backend-api/backend-api.go +++ b/backend-api/backend-api.go @@ -28,7 +28,8 @@ var ( func init() { s := g.Server() s.BindHandler("/backend-api/*any", ProxyAll) - s.BindHandler("/_next/data/*any", NextDataGptsFixed) + // s.BindHandler("/public-api/*any", ProxyAll) + // s.BindHandler("/_next/data/*any", NextDataGptsFixed) backendGroup := s.Group("/backend-api") backendGroup.POST("/accounts/data_export", NotFound) // 禁用导出 backendGroup.POST("/payments/checkout", NotFound) // 禁用支付 @@ -49,8 +50,13 @@ func ProxyAll(r *ghttp.Request) { ctx := r.GetCtx() // 获取header中的token Authorization: Bearer xxx 去掉Bearer + userToken := "" + Authorization := r.Header.Get("Authorization") + if Authorization != "" { + userToken = r.Header.Get("Authorization")[7:] + } + g.Log().Debug(ctx, "userToken", userToken) - userToken := r.Header.Get("Authorization")[7:] isStream := strings.Contains(r.Header.Get("accept"), "text/event-stream") // 获得当前的请求域名 // g.Log().Debug(ctx, "ProxyAll", r.URL.Path, r.Header.Get("accept"), isStream) @@ -78,10 +84,12 @@ func ProxyAll(r *ghttp.Request) { newreq.URL.Scheme = u.Scheme newreq.Host = u.Host newreq.Header.Set("authkey", config.AUTHKEY(ctx)) - newreq.Header.Set("Authorization", "Bearer "+accessToken) newreq.Header.Set("Host", "chat.openai.com") newreq.Header.Set("Origin", "https://chat.openai.com/chat") + if accessToken != "" { + newreq.Header.Set("Authorization", "Bearer "+accessToken) + } // g.Dump(newreq.URL) cdnhost := config.CDNHOST(ctx) diff --git a/backend-api/me.go b/backend-api/me.go index 7bb74c6..01a45cb 100644 --- a/backend-api/me.go +++ b/backend-api/me.go @@ -40,6 +40,7 @@ func Me(r *ghttp.Request) { res, err := g.Client().SetHeaderMap(map[string]string{ "Authorization": "Bearer " + AccessToken, "User-Agent": r.Header.Get("User-Agent"), + "authKey": config.AUTHKEY(ctx), }).Get(ctx, UpStream+"/backend-api/me") if err != nil { r.Response.WriteStatus(http.StatusUnauthorized) diff --git a/config.yaml b/config.yaml index c855660..6363b45 100644 --- a/config.yaml +++ b/config.yaml @@ -55,7 +55,7 @@ modules: enable: 1 # 接入网关地址 -CHATPROXY: "https://chatgpt.ggss.club/gateway" +CHATPROXY: "https://chatgpt.ggss.club/gateway" ARKOSE_URL: "https://chatgpt.ggss.club/arkose/v2/" # 接入网关的authkey AUTHKEY: "maidou" diff --git a/main.go b/main.go index ec040c8..27513a7 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,7 @@ import ( _ "chatgpt-mirror-server/api" _ "chatgpt-mirror-server/backend-api" _ "chatgpt-mirror-server/modules" + _ "chatgpt-mirror-server/public-api" "github.com/gogf/gf/v2/os/gctx" diff --git a/public-api/proxypublic.go b/public-api/proxypublic.go new file mode 100644 index 0000000..be50609 --- /dev/null +++ b/public-api/proxypublic.go @@ -0,0 +1,31 @@ +package publicapi + +import ( + "chatgpt-mirror-server/config" + "net/http" + "net/http/httputil" + "net/url" + + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" +) + +func ProxyPublic(r *ghttp.Request) { + ctx := r.GetCtx() + u, _ := url.Parse(config.CHATPROXY(ctx)) + proxy := httputil.NewSingleHostReverseProxy(u) + proxy.ErrorHandler = func(writer http.ResponseWriter, request *http.Request, e error) { + g.Log().Error(ctx, e) + writer.WriteHeader(http.StatusBadGateway) + } + newreq := r.Request.Clone(ctx) + newreq.URL.Host = u.Host + newreq.URL.Scheme = u.Scheme + newreq.Host = u.Host + newreq.Header.Set("authkey", config.AUTHKEY(ctx)) + + // newreq.Header.Set("Cookie", "__Secure-next-auth.session-token="+carinfo.RefreshCookie) + // // 去除header 中的 压缩 + // newreq.Header.Del("Accept-Encoding") + proxy.ServeHTTP(r.Response.Writer.RawWriter(), newreq) +} diff --git a/public-api/public-api.go b/public-api/public-api.go new file mode 100644 index 0000000..e47598b --- /dev/null +++ b/public-api/public-api.go @@ -0,0 +1,9 @@ +package publicapi + +import "github.com/gogf/gf/v2/frame/g" + +func init() { + s := g.Server() + publicApiGroup := s.Group("/public-api") + publicApiGroup.ALL("/*", ProxyPublic) +} diff --git a/resource/template/Rp5H7oULko6u7cJEjMucd/chat.html b/resource/template/Rp5H7oULko6u7cJEjMucd/chat.html new file mode 100644 index 0000000..22810c9 --- /dev/null +++ b/resource/template/Rp5H7oULko6u7cJEjMucd/chat.html @@ -0,0 +1 @@ +
{{.envScript}}