├── .github └── workflows │ └── go.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── cmd └── time.go ├── docker-compose.yml ├── go.mod ├── go.sum └── main.go /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a golang project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 | 4 | name: Release Workflow 5 | on: 6 | release: 7 | types: 8 | - created 9 | permissions: 10 | contents: write 11 | 12 | jobs: 13 | 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@v3 21 | with: 22 | go-version: 1.19 23 | 24 | - name: Build 25 | run: go build -o bin/ . 26 | 27 | - name: recursively list files 28 | run: ls -R 29 | 30 | - name: Get existing release body 31 | id: get_release_body 32 | run: | 33 | echo "::set-output name=body::$(curl -s -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' https://api.github.com/repos/${{ github.repository }}/releases/tags/${{ github.ref_path }} | jq -r '.body')" 34 | 35 | - name: Upload release artifact 36 | uses: svenstaro/upload-release-action@v2 37 | with: 38 | file: bin/* 39 | file_glob: true 40 | tag: ${{ github.ref }} 41 | body: | 42 | ${{ steps.get_release_body.outputs.body }} 43 | repo_token: ${{ secrets.GITHUB_TOKEN }} 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | main.go 17 | ChatGPT-Proxy-V4 18 | funcaptcha -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang 2 | RUN go install github.com/acheong08/ChatGPTProxy@latest 3 | CMD [ "ChatGPTProxy" ] 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ChatGPT Proxy 2 | 3 | Gets around cloudflare via TLS spoofing 4 | 5 | ## Notes 6 | There is an IP based rate limit. Set a PUID environment variable to get around it 7 | `export PUID="user-..."` 8 | This requires a ChatGPT Plus account 9 | 10 | ## Building and running 11 | `go build` 12 | `./ChatGPT-Proxy-V4` 13 | 14 | ## Limitations 15 | This cannot get around an outright IP ban by OpenAI 16 | -------------------------------------------------------------------------------- /cmd/time.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | fmt.Printf("%d", time.Now().UnixNano()/1000000000) 10 | } 11 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.3' 2 | services: 3 | chatgpt-proxy: 4 | image: chatgpt-proxy-v4 5 | container_name: chatgpt-proxy-v4 6 | ports: 7 | - '8080:8080' 8 | env_file: 9 | - .env 10 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/acheong08/ChatGPTProxy 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/acheong08/OpenAIAuth v0.0.0-20230625142757-7b01ccd04f63 7 | github.com/acheong08/endless v0.0.0-20230615162514-90545c7793fd 8 | github.com/acheong08/funcaptcha v1.9.2 9 | github.com/bogdanfinn/fhttp v0.5.23 10 | github.com/bogdanfinn/tls-client v1.4.0 11 | github.com/gin-gonic/gin v1.9.1 12 | ) 13 | 14 | require ( 15 | github.com/andybalholm/brotli v1.0.5 // indirect 16 | github.com/bogdanfinn/utls v1.5.16 // indirect 17 | github.com/bytedance/sonic v1.9.2 // indirect 18 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect 19 | github.com/gabriel-vasile/mimetype v1.4.2 // indirect 20 | github.com/gin-contrib/sse v0.1.0 // indirect 21 | github.com/go-playground/locales v0.14.1 // indirect 22 | github.com/go-playground/universal-translator v0.18.1 // indirect 23 | github.com/go-playground/validator/v10 v10.14.1 // indirect 24 | github.com/goccy/go-json v0.10.2 // indirect 25 | github.com/json-iterator/go v1.1.12 // indirect 26 | github.com/klauspost/compress v1.16.6 // indirect 27 | github.com/klauspost/cpuid/v2 v2.2.5 // indirect 28 | github.com/leodido/go-urn v1.2.4 // indirect 29 | github.com/mattn/go-isatty v0.0.19 // indirect 30 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 31 | github.com/modern-go/reflect2 v1.0.2 // indirect 32 | github.com/nirasan/go-oauth-pkce-code-verifier v0.0.0-20220510032225-4f9f17eaec4c // indirect 33 | github.com/pelletier/go-toml/v2 v2.0.8 // indirect 34 | github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 // indirect 35 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 36 | github.com/ugorji/go/codec v1.2.11 // indirect 37 | golang.org/x/arch v0.3.0 // indirect 38 | golang.org/x/crypto v0.10.0 // indirect 39 | golang.org/x/net v0.11.0 // indirect 40 | golang.org/x/sys v0.9.0 // indirect 41 | golang.org/x/text v0.10.0 // indirect 42 | google.golang.org/protobuf v1.31.0 // indirect 43 | gopkg.in/yaml.v3 v3.0.1 // indirect 44 | ) 45 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/acheong08/OpenAIAuth v0.0.0-20230530050836-f2a06cd52911 h1:KNdCGjt2DkrFn4RNS6Uh41rHwyD6dUhYxYuhVFxsZkc= 2 | github.com/acheong08/OpenAIAuth v0.0.0-20230530050836-f2a06cd52911/go.mod h1:ES3Dh9hnbR2mDPlNTagj5e3b4nXECd4tbAjVgxggXEE= 3 | github.com/acheong08/OpenAIAuth v0.0.0-20230625142757-7b01ccd04f63 h1:/dauxvuoqC4zqHCqCDjJfiNIY34Yj08Fqbs3S1cHCQw= 4 | github.com/acheong08/OpenAIAuth v0.0.0-20230625142757-7b01ccd04f63/go.mod h1:ES3Dh9hnbR2mDPlNTagj5e3b4nXECd4tbAjVgxggXEE= 5 | github.com/acheong08/endless v0.0.0-20230529075213-74050cf641c8 h1:mHtMoGlGNUfMRjsWcb5Kvd1mJfJG8Gr1TtIghE8iiN8= 6 | github.com/acheong08/endless v0.0.0-20230529075213-74050cf641c8/go.mod h1:0yO7neMeJLvKk/B/fq5votDY8rByrOPDubpvU+6saKo= 7 | github.com/acheong08/endless v0.0.0-20230615162514-90545c7793fd h1:oIpfrRhD7Jus41dotbK+SQjWSFRnf1cLZUYCZpF/o/4= 8 | github.com/acheong08/endless v0.0.0-20230615162514-90545c7793fd/go.mod h1:0yO7neMeJLvKk/B/fq5votDY8rByrOPDubpvU+6saKo= 9 | github.com/acheong08/funcaptcha v0.2.1-0.20230701114718-9bebae686f1e h1:LYR0QN4yt8puGJW/VldM81V7C5AdjYYR0CyAOxrpElY= 10 | github.com/acheong08/funcaptcha v0.2.1-0.20230701114718-9bebae686f1e/go.mod h1:VupbjtVAODvgyAB3Zo86fOA53G+UAmaV/Rk9jUCGuTU= 11 | github.com/acheong08/funcaptcha v1.9.2 h1:pjOUzT10OfauqVLCVTdP8FCFdtmlihOK3btVvURiQW4= 12 | github.com/acheong08/funcaptcha v1.9.2/go.mod h1:azmXv2Mfbw5eBOnMw5e1yTMNVyku17klWhGtkHwm7PY= 13 | github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= 14 | github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 15 | github.com/bogdanfinn/fhttp v0.5.23 h1:4Xb5OjYArB8GpnUw4A4r5jmt8UW0/Cvey3R9nS2dC9U= 16 | github.com/bogdanfinn/fhttp v0.5.23/go.mod h1:brqi5woc5eSCVHdKYBV8aZLbO7HGqpwyDLeXW+fT18I= 17 | github.com/bogdanfinn/tls-client v1.4.0 h1:ptZmkvVyRTjMFPc3Kevholf+ioePkCM5oj3qkOmOuoM= 18 | github.com/bogdanfinn/tls-client v1.4.0/go.mod h1:lgtqsHjoJYQMPz6H08bc8t30bmUaYnVjwtfVEzMGJDs= 19 | github.com/bogdanfinn/utls v1.5.16 h1:NhhWkegEcYETBMj9nvgO4lwvc6NcLH+znrXzO3gnw4M= 20 | github.com/bogdanfinn/utls v1.5.16/go.mod h1:mHeRCi69cUiEyVBkKONB1cAbLjRcZnlJbGzttmiuK4o= 21 | github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= 22 | github.com/bytedance/sonic v1.8.10 h1:XFSQg4/rwpQnNWSybNDr8oz6QtQY9uRGfRKDVWVsvP8= 23 | github.com/bytedance/sonic v1.8.10/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= 24 | github.com/bytedance/sonic v1.9.2 h1:GDaNjuWSGu09guE9Oql0MSTNhNCLlWwO8y/xM5BzcbM= 25 | github.com/bytedance/sonic v1.9.2/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= 26 | github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= 27 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= 28 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= 29 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 30 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 31 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 32 | github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= 33 | github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= 34 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 35 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 36 | github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= 37 | github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= 38 | github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= 39 | github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= 40 | github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= 41 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 42 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 43 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 44 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 45 | github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= 46 | github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= 47 | github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= 48 | github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= 49 | github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= 50 | github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 51 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 52 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 53 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 54 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 55 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 56 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 57 | github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= 58 | github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 59 | github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk= 60 | github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 61 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 62 | github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= 63 | github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= 64 | github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= 65 | github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= 66 | github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= 67 | github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= 68 | github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= 69 | github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 70 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 71 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 72 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 73 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 74 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 75 | github.com/nirasan/go-oauth-pkce-code-verifier v0.0.0-20220510032225-4f9f17eaec4c h1:4RYnE0ISVwRxm9Dfo7utw1dh0kdRDEmVYq2MFVLy5zI= 76 | github.com/nirasan/go-oauth-pkce-code-verifier v0.0.0-20220510032225-4f9f17eaec4c/go.mod h1:DvuJJ/w1Y59rG8UTDxsMk5U+UJXJwuvUgbiJSm9yhX8= 77 | github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= 78 | github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= 79 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 80 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 81 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 82 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 83 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 84 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 85 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 86 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 87 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 88 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 89 | github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 90 | github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= 91 | github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 92 | github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 h1:YqAladjX7xpA6BM04leXMWAEjS0mTZ5kUU9KRBriQJc= 93 | github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5/go.mod h1:2JjD2zLQYH5HO74y5+aE3remJQvl6q4Sn6aWA2wD1Ng= 94 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 95 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 96 | github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= 97 | github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 98 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= 99 | golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= 100 | golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= 101 | golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= 102 | golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= 103 | golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= 104 | golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= 105 | golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= 106 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 107 | golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= 108 | golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= 109 | golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 110 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 111 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 112 | golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= 113 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 114 | golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= 115 | golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 116 | golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= 117 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 118 | golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= 119 | golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 120 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 121 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 122 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 123 | google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= 124 | google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 125 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 126 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 127 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 128 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 129 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 130 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 131 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 132 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 133 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "io" 7 | "log" 8 | "net/url" 9 | "os" 10 | "strings" 11 | "time" 12 | 13 | arkose "github.com/acheong08/funcaptcha" 14 | 15 | http "github.com/bogdanfinn/fhttp" 16 | tls_client "github.com/bogdanfinn/tls-client" 17 | 18 | "github.com/acheong08/OpenAIAuth/auth" 19 | "github.com/acheong08/endless" 20 | "github.com/gin-gonic/gin" 21 | ) 22 | 23 | type auth_struct struct { 24 | OpenAI_Email string `json:"openai_email"` 25 | OpenAI_Password string `json:"openai_password"` 26 | } 27 | 28 | var ( 29 | jar = tls_client.NewCookieJar() 30 | options = []tls_client.HttpClientOption{ 31 | tls_client.WithTimeoutSeconds(360), 32 | tls_client.WithClientProfile(tls_client.Firefox_110), 33 | tls_client.WithNotFollowRedirects(), 34 | tls_client.WithCookieJar(jar), // create cookieJar instance and pass it as argument 35 | } 36 | client, _ = tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...) 37 | user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:114.0) Gecko/20100101 Firefox/114.0" 38 | http_proxy = os.Getenv("http_proxy") 39 | authorizations auth_struct 40 | OpenAI_HOST = os.Getenv("OPENAI_HOST") 41 | ) 42 | 43 | func admin(c *gin.Context) { 44 | if c.GetHeader("Authorization") != os.Getenv("PASSWORD") { 45 | c.String(401, "Unauthorized") 46 | c.Abort() 47 | return 48 | } 49 | c.Next() 50 | } 51 | 52 | func init() { 53 | if OpenAI_HOST == "" { 54 | OpenAI_HOST = "chat.openai.com" 55 | } 56 | authorizations.OpenAI_Email = os.Getenv("OPENAI_EMAIL") 57 | authorizations.OpenAI_Password = os.Getenv("OPENAI_PASSWORD") 58 | if authorizations.OpenAI_Email != "" && authorizations.OpenAI_Password != "" { 59 | go func() { 60 | for { 61 | authenticator := auth.NewAuthenticator(authorizations.OpenAI_Email, authorizations.OpenAI_Password, http_proxy) 62 | err := authenticator.Begin() 63 | if err != nil { 64 | log.Println(err) 65 | break 66 | } 67 | puid, err := authenticator.GetPUID() 68 | if err != nil { 69 | break 70 | } 71 | os.Setenv("PUID", puid) 72 | println(puid) 73 | client.SetCookies(&url.URL{ 74 | Host: OpenAI_HOST, 75 | }, []*http.Cookie{ 76 | { 77 | Name: "_puid", 78 | Value: puid, 79 | }, 80 | }) 81 | time.Sleep(24 * time.Hour * 7) 82 | } 83 | }() 84 | } 85 | // arkose.SetTLSClient(&client) 86 | } 87 | 88 | func main() { 89 | 90 | if http_proxy != "" { 91 | client.SetProxy(http_proxy) 92 | println("Proxy set:" + http_proxy) 93 | } 94 | 95 | PORT := os.Getenv("PORT") 96 | if PORT == "" { 97 | PORT = "9090" 98 | } 99 | handler := gin.Default() 100 | handler.GET("/ping", func(c *gin.Context) { 101 | c.JSON(200, gin.H{"message": "pong"}) 102 | }) 103 | 104 | handler.PATCH("/admin/puid", admin, func(c *gin.Context) { 105 | // Get the password from the request (json) and update the password 106 | type puid_struct struct { 107 | PUID string `json:"puid"` 108 | } 109 | var puid puid_struct 110 | err := c.BindJSON(&puid) 111 | if err != nil { 112 | c.String(400, "puid not provided") 113 | return 114 | } 115 | // Set environment variable 116 | os.Setenv("PUID", puid.PUID) 117 | c.String(200, "puid updated") 118 | }) 119 | handler.PATCH("/admin/password", admin, func(c *gin.Context) { 120 | // Get the password from the request (json) and update the password 121 | type password_struct struct { 122 | PASSWORD string `json:"password"` 123 | } 124 | var password password_struct 125 | err := c.BindJSON(&password) 126 | if err != nil { 127 | c.String(400, "password not provided") 128 | return 129 | } 130 | // Set environment variable 131 | os.Setenv("PASSWORD", password.PASSWORD) 132 | c.String(200, "PASSWORD updated") 133 | }) 134 | handler.PATCH("/admin/openai", admin, func(c *gin.Context) { 135 | err := c.BindJSON(&authorizations) 136 | if err != nil { 137 | c.JSON(400, gin.H{"error": "JSON invalid"}) 138 | } 139 | os.Setenv("OPENAI_EMAIL", authorizations.OpenAI_Email) 140 | os.Setenv("OPENAI_PASSWORD", authorizations.OpenAI_Password) 141 | }) 142 | handler.Any("/api/*path", proxy) 143 | 144 | gin.SetMode(gin.ReleaseMode) 145 | endless.ListenAndServe(os.Getenv("HOST")+":"+PORT, handler) 146 | } 147 | 148 | func proxy(c *gin.Context) { 149 | var url string 150 | var err error 151 | var request_method string 152 | var request *http.Request 153 | var response *http.Response 154 | 155 | if c.Request.URL.RawQuery != "" { 156 | url = "https://" + OpenAI_HOST + "/backend-api" + c.Param("path") + "?" + c.Request.URL.RawQuery 157 | } else { 158 | url = "https://" + OpenAI_HOST + "/backend-api" + c.Param("path") 159 | } 160 | request_method = c.Request.Method 161 | 162 | if c.Request.URL.Path == "/api/conversation" { 163 | var request_body map[string]interface{} 164 | if c.Request.Body != nil { 165 | err := json.NewDecoder(c.Request.Body).Decode(&request_body) 166 | if err != nil { 167 | c.JSON(400, gin.H{"error": "JSON invalid"}) 168 | return 169 | } 170 | } 171 | // Check if "model" is in the request json 172 | if _, ok := request_body["model"]; !ok { 173 | c.JSON(400, gin.H{"error": "model not provided"}) 174 | return 175 | } 176 | if strings.HasPrefix(request_body["model"].(string), "gpt-4") { 177 | if _, ok := request_body["arkose_token"]; !ok { 178 | log.Println("arkose token not provided") 179 | token, _, err := arkose.GetOpenAIToken() 180 | var arkose_token string 181 | if err != nil { 182 | c.JSON(500, gin.H{"error": err.Error()}) 183 | return 184 | } 185 | arkose_token = token 186 | request_body["arkose_token"] = arkose_token 187 | } 188 | } 189 | body_json, err := json.Marshal(request_body) 190 | if err != nil { 191 | c.JSON(500, gin.H{"error": err.Error()}) 192 | return 193 | } 194 | original_body := bytes.NewReader(body_json) 195 | request, _ = http.NewRequest(request_method, url, original_body) 196 | } else { 197 | request, _ = http.NewRequest(request_method, url, c.Request.Body) 198 | } 199 | request.Header.Set("Host", ""+OpenAI_HOST+"") 200 | request.Header.Set("Origin", "https://"+OpenAI_HOST+"/chat") 201 | request.Header.Set("Connection", "keep-alive") 202 | request.Header.Set("Content-Type", "application/json") 203 | request.Header.Set("Keep-Alive", "timeout=360") 204 | request.Header.Set("Authorization", c.Request.Header.Get("Authorization")) 205 | request.Header.Set("sec-ch-ua", "\"Chromium\";v=\"112\", \"Brave\";v=\"112\", \"Not:A-Brand\";v=\"99\"") 206 | request.Header.Set("sec-ch-ua-mobile", "?0") 207 | request.Header.Set("sec-ch-ua-platform", "\"Linux\"") 208 | request.Header.Set("sec-fetch-dest", "empty") 209 | request.Header.Set("sec-fetch-mode", "cors") 210 | request.Header.Set("sec-fetch-site", "same-origin") 211 | request.Header.Set("sec-gpc", "1") 212 | request.Header.Set("user-agent", user_agent) 213 | if c.Request.Header.Get("PUID") != "" { 214 | request.Header.Set("cookie", "_puid="+c.Request.Header.Get("PUID")+";") 215 | } 216 | response, err = client.Do(request) 217 | if err != nil { 218 | c.JSON(500, gin.H{"error": err.Error()}) 219 | return 220 | } 221 | defer response.Body.Close() 222 | // Copy headers from response 223 | for k, v := range response.Header { 224 | if strings.ToLower(k) == "content-encoding" { 225 | continue 226 | } 227 | c.Header(k, v[0]) 228 | } 229 | // Get status code 230 | c.Status(response.StatusCode) 231 | 232 | buf := make([]byte, 4096) 233 | for { 234 | n, err := response.Body.Read(buf) 235 | if n > 0 { 236 | _, writeErr := c.Writer.Write(buf[:n]) 237 | if writeErr != nil { 238 | log.Printf("Error writing to client: %v", writeErr) 239 | break 240 | } 241 | c.Writer.Flush() // flush buffer to make sure the data is sent to client in time. 242 | } 243 | if err == io.EOF { 244 | break 245 | } 246 | if err != nil { 247 | log.Printf("Error reading from response body: %v", err) 248 | break 249 | } 250 | } 251 | } 252 | --------------------------------------------------------------------------------