Spaces:
Sleeping
Sleeping
Dhudean
commited on
Commit
·
e0b8007
1
Parent(s):
2d457a6
update
Browse files- Dockerfile +2 -9
- README.md +251 -10
- common/config/config.go +5 -0
- common/constants.go +1 -1
- controller/chat.go +7 -0
- middleware/ip-list.go +28 -0
- model/openai.go +13 -1
- router/api-router.go +1 -0
Dockerfile
CHANGED
|
@@ -4,9 +4,8 @@ FROM golang AS builder
|
|
| 4 |
# 设置环境变量
|
| 5 |
ENV GO111MODULE=on \
|
| 6 |
CGO_ENABLED=0 \
|
| 7 |
-
GOOS=linux
|
| 8 |
-
|
| 9 |
-
|
| 10 |
# 设置工作目录
|
| 11 |
WORKDIR /build
|
| 12 |
|
|
@@ -25,12 +24,6 @@ FROM alpine
|
|
| 25 |
# 安装基本的运行时依赖
|
| 26 |
RUN apk --no-cache add ca-certificates tzdata
|
| 27 |
|
| 28 |
-
# 在最终镜像里声明环境变量,容器真正运行时可见
|
| 29 |
-
ENV AUTO_DEL_CHAT=1
|
| 30 |
-
|
| 31 |
-
RUN echo "AUTO_DEL_CHAT is $AUTO_DEL_CHAT"
|
| 32 |
-
|
| 33 |
-
|
| 34 |
# 从构建阶段复制可执行文件
|
| 35 |
COPY --from=builder /genspark2api .
|
| 36 |
|
|
|
|
| 4 |
# 设置环境变量
|
| 5 |
ENV GO111MODULE=on \
|
| 6 |
CGO_ENABLED=0 \
|
| 7 |
+
GOOS=linux
|
| 8 |
+
|
|
|
|
| 9 |
# 设置工作目录
|
| 10 |
WORKDIR /build
|
| 11 |
|
|
|
|
| 24 |
# 安装基本的运行时依赖
|
| 25 |
RUN apk --no-cache add ca-certificates tzdata
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
# 从构建阶段复制可执行文件
|
| 28 |
COPY --from=builder /genspark2api .
|
| 29 |
|
README.md
CHANGED
|
@@ -1,10 +1,251 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<p align="right">
|
| 2 |
+
<strong>中文</strong>
|
| 3 |
+
</p>
|
| 4 |
+
<div align="center">
|
| 5 |
+
|
| 6 |
+
# Genspark2API
|
| 7 |
+
|
| 8 |
+
_觉得有点意思的话 别忘了点个 ⭐_
|
| 9 |
+
|
| 10 |
+
<a href="https://t.me/+LGKwlC_xa-E5ZDk9">
|
| 11 |
+
<img src="https://telegram.org/img/website_icon.svg" width="16" height="16" style="vertical-align: middle;">
|
| 12 |
+
<span style="text-decoration: none; font-size: 12px; color: #0088cc; vertical-align: middle;">Telegram 交流群</span>
|
| 13 |
+
</a>
|
| 14 |
+
|
| 15 |
+
<sup><i>(原`coze-discord-proxy`交流群, 此项目仍可进此群**交流** / **反馈bug**)</i></sup>
|
| 16 |
+
|
| 17 |
+
</div>
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
## 功能
|
| 22 |
+
|
| 23 |
+
- [x] 支持对话接口(流式/非流式)(`/chat/completions`)(请求非以下列表的模型会触发`Mixture-of-Agents`模式)
|
| 24 |
+
- **gpt-4o**
|
| 25 |
+
- **o1**
|
| 26 |
+
- **o3-mini-high**
|
| 27 |
+
- **claude-3-5-sonnet**
|
| 28 |
+
- **claude-3-5-haiku**
|
| 29 |
+
- **gemini-1.5-pro**
|
| 30 |
+
- **gemini-1.5-flash**
|
| 31 |
+
- **deep-seek-v3**
|
| 32 |
+
- **deep-seek-r1**
|
| 33 |
+
- [x] 支持识别**图片**/**文件**多轮对话
|
| 34 |
+
- [x] 支持文生图接口(`/images/generations`),详细请看[生图模型配置](#生图模型配置)
|
| 35 |
+
- **flux**
|
| 36 |
+
- **flux-speed**
|
| 37 |
+
- **flux-pro/ultra**
|
| 38 |
+
- **ideogram**
|
| 39 |
+
- **recraft-v3**
|
| 40 |
+
- **dall-e-3**
|
| 41 |
+
- [x] 支持自定义请求头校验值(Authorization)
|
| 42 |
+
- [x] 支持cookie池(随机)
|
| 43 |
+
- [x] 支持请求失败自动切换cookie重试(需配置cookie池)
|
| 44 |
+
- [x] 可配置自动删除对话记录
|
| 45 |
+
- [x] 可配置代理请求(环境变量`PROXY_URL`)
|
| 46 |
+
- [x] 可配置Model绑定Chat(解决模型自动切换导致**降智**),详细请看[进阶配置](#解决模型自动切换导致降智问题)。
|
| 47 |
+
|
| 48 |
+
### 接口文档:
|
| 49 |
+
|
| 50 |
+
略
|
| 51 |
+
|
| 52 |
+
### 示例:
|
| 53 |
+
|
| 54 |
+
<span><img src="docs/img2.png" width="800"/></span>
|
| 55 |
+
|
| 56 |
+
## 如何使用
|
| 57 |
+
|
| 58 |
+
略
|
| 59 |
+
|
| 60 |
+
## 如何集成NextChat
|
| 61 |
+
|
| 62 |
+
填 接口地址(ip:端口/域名) 及 API-Key(`PROXY_SECRET`),其它的随便填随便选。
|
| 63 |
+
|
| 64 |
+
> 如果自己没有搭建NextChat面板,这里有个已经搭建好的可以使用 [NeatChat](https://ai.aytsao.cn/)
|
| 65 |
+
|
| 66 |
+
<span><img src="docs/img5.png" width="800"/></span>
|
| 67 |
+
|
| 68 |
+
## 如何集成one-api
|
| 69 |
+
|
| 70 |
+
填 `BaseURL`(ip:端口/域名) 及 密钥(`PROXY_SECRET`),其它的随便填随便选。
|
| 71 |
+
|
| 72 |
+
<span><img src="docs/img3.png" width="800"/></span>
|
| 73 |
+
|
| 74 |
+
## 部署
|
| 75 |
+
|
| 76 |
+
### 基于 Docker-Compose(All In One) 进行部署
|
| 77 |
+
|
| 78 |
+
```shell
|
| 79 |
+
docker-compose pull && docker-compose up -d
|
| 80 |
+
```
|
| 81 |
+
|
| 82 |
+
#### docker-compose.yml
|
| 83 |
+
|
| 84 |
+
```docker
|
| 85 |
+
version: '3.4'
|
| 86 |
+
|
| 87 |
+
services:
|
| 88 |
+
genspark2api:
|
| 89 |
+
image: deanxv/genspark2api:latest
|
| 90 |
+
container_name: genspark2api
|
| 91 |
+
restart: always
|
| 92 |
+
ports:
|
| 93 |
+
- "7055:7055"
|
| 94 |
+
volumes:
|
| 95 |
+
- ./data:/app/genspark2api/data
|
| 96 |
+
environment:
|
| 97 |
+
- GS_COOKIE=****** # cookie (多个请以,分隔)
|
| 98 |
+
- API_SECRET=123456 # [可选]接口密钥-修改此行为请求头校验的值(多个请以,分隔)
|
| 99 |
+
- TZ=Asia/Shanghai
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
### 基于 Docker 进行部署
|
| 103 |
+
|
| 104 |
+
```docker
|
| 105 |
+
docker run --name genspark2api -d --restart always \
|
| 106 |
+
-p 7055:7055 \
|
| 107 |
+
-v $(pwd)/data:/app/genspark2api/data \
|
| 108 |
+
-e GS_COOKIE=***** \
|
| 109 |
+
-e API_SECRET="123456" \
|
| 110 |
+
-e TZ=Asia/Shanghai \
|
| 111 |
+
deanxv/genspark2api
|
| 112 |
+
```
|
| 113 |
+
|
| 114 |
+
其中`API_SECRET`、`GS_COOKIE`修改为自己的。
|
| 115 |
+
|
| 116 |
+
如果上面的镜像无法拉取,可以尝试使用 GitHub 的 Docker 镜像,将上面的`deanxv/genspark2api`替换为`ghcr.io/deanxv/genspark2api`即可。
|
| 117 |
+
|
| 118 |
+
### 部署到第三方平台
|
| 119 |
+
|
| 120 |
+
<details>
|
| 121 |
+
<summary><strong>部署到 Zeabur</strong></summary>
|
| 122 |
+
<div>
|
| 123 |
+
|
| 124 |
+
> Zeabur 的服务器在国外,自动解决了网络的问题,~~同时免费的额度也足够个人使用~~
|
| 125 |
+
|
| 126 |
+
1. 首先 **fork** 一份代码。
|
| 127 |
+
2. 进入 [Zeabur](https://zeabur.com?referralCode=deanxv),使用github登录,进入控制台。
|
| 128 |
+
3. 在 Service -> Add Service,选择 Git(第一次使用需要先授权),选择你 fork 的仓库。
|
| 129 |
+
4. Deploy 会自动开始,先取消。
|
| 130 |
+
5. 添加环境变量
|
| 131 |
+
|
| 132 |
+
`GS_COOKIE:******` cookie (多个请以,分隔)
|
| 133 |
+
|
| 134 |
+
`API_SECRET:123456` [可选]接口密钥-修改此行为请求头校验的值(多个请以,分隔)(与openai-API-KEY用法一致)
|
| 135 |
+
|
| 136 |
+
保存。
|
| 137 |
+
|
| 138 |
+
6. 选择 Redeploy。
|
| 139 |
+
|
| 140 |
+
</div>
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
</details>
|
| 144 |
+
|
| 145 |
+
<details>
|
| 146 |
+
<summary><strong>部署到 Render</strong></summary>
|
| 147 |
+
<div>
|
| 148 |
+
|
| 149 |
+
> Render 提供免费额度,绑卡后可以进一步提升额度
|
| 150 |
+
|
| 151 |
+
Render 可以直接部署 docker 镜像,不需要 fork 仓库:[Render](https://dashboard.render.com)
|
| 152 |
+
|
| 153 |
+
</div>
|
| 154 |
+
</details>
|
| 155 |
+
|
| 156 |
+
## 配置
|
| 157 |
+
|
| 158 |
+
### 环境变量
|
| 159 |
+
|
| 160 |
+
1. `PORT=7055` [可选]端口,默认为7055
|
| 161 |
+
2. `DEBUG=true` [可选]DEBUG模式,可打印更多信息[true:打开、false:关闭]
|
| 162 |
+
3. `API_SECRET=123456` [可选]接口密钥-修改此行为请求头(Authorization)校验的值(同API-KEY)(多个请以,分隔)
|
| 163 |
+
4. `GS_COOKIE=******` cookie (多个请以,分隔)
|
| 164 |
+
5. `YES_CAPTCHA_CLIENT_KEY=******` [可选]YesCaptcha Client Key 过谷歌验证,详细请看[使用YesCaptcha过谷歌验证](#使用YesCaptcha过谷歌验证)
|
| 165 |
+
6. `AUTO_DEL_CHAT=0` [可选]对话完成自动删除(默认:0)[0:关闭,1:开启]
|
| 166 |
+
7. `REQUEST_RATE_LIMIT=60` [可选]每分钟下的单ip请求速率限制,默认:60次/min
|
| 167 |
+
8. `PROXY_URL=http://127.0.0.1:10801` [可选]代理
|
| 168 |
+
9. `AUTO_MODEL_CHAT_MAP_TYPE=1` [可选]自动配置Model绑定Chat(默认:1)[0:关闭,1:开启]
|
| 169 |
+
10. `MODEL_CHAT_MAP=claude-3-5-sonnet=a649******00fa,gpt-4o=su74******47hd` [可选]Model绑定Chat(多个请以,分隔),详细请看[进阶配置](#解决模型自动切换导致降智问题)
|
| 170 |
+
11. `SESSION_IMAGE_CHAT_MAP=aed9196b-********-4ed6e32f7e4d=0c6785e6-********-7ff6e5a2a29c,aefwer6b-********-casds22=fda234-********-sfaw123` [可选]Session绑定Image-Chat(多个请以,分隔),详细请看[进阶配置](#生图模型配置)
|
| 171 |
+
|
| 172 |
+
### cookie获取方式
|
| 173 |
+
|
| 174 |
+
1. 打开**F12**开发者工具。
|
| 175 |
+
2. 发起对话。
|
| 176 |
+
3. 点击ask请求,请求头中的**cookie**即为环境变量**GS_COOKIE**所需值。
|
| 177 |
+
|
| 178 |
+
> **【注】** 其中`session_id=f9c60******cb6d`是必须的,其他内容可要可不要,即环境变量`GS_COOKIE=session_id=f9c60******cb6d`
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+

|
| 182 |
+
|
| 183 |
+
## 进阶配置
|
| 184 |
+
|
| 185 |
+
### 解决模型自动切换导致降智问题
|
| 186 |
+
|
| 187 |
+
#### 方案一 (默认启用此配置)【推荐】
|
| 188 |
+
|
| 189 |
+
> 配置环境变量 **AUTO_MODEL_CHAT_MAP_TYPE=1**
|
| 190 |
+
>
|
| 191 |
+
> 此配置下,会在调用模型时获取对话的id,并绑定模型。
|
| 192 |
+
|
| 193 |
+
#### 方案二
|
| 194 |
+
|
| 195 |
+
> 配置环境变量 MODEL_CHAT_MAP
|
| 196 |
+
>
|
| 197 |
+
> 【作用】指定对话,解决模型自动切换导致降智问题。
|
| 198 |
+
|
| 199 |
+
1. 打开**F12**开发者工具。
|
| 200 |
+
2. 选择需要绑定的对话的模型(示例:`claude-3-5-sonnet`),发起对话。
|
| 201 |
+
3. 点击ask请求,此时最上方url中的`id`(或响应中的`id`)即为此对话唯一id。
|
| 202 |
+

|
| 203 |
+
4. 配置环境变量 `MODEL_CHAT_MAP=claude-3-5-sonnet=3cdcc******474c5` (多个请以,分隔)
|
| 204 |
+
|
| 205 |
+
### 生图模型配置
|
| 206 |
+
|
| 207 |
+
> 配置环境变量 SESSION_IMAGE_CHAT_MAP
|
| 208 |
+
|
| 209 |
+
1. 打开**F12**开发者工具。
|
| 210 |
+
2. 选择生成图像,选择任一生图模型,发起对话。
|
| 211 |
+
3. 点击ask请求,此时最上方url中的`id`(或响应中的`id`)即为此对话唯一id,然后在请求头中获取`session_id`的值。
|
| 212 |
+

|
| 213 |
+
4. 配置环境变量 `SESSION_IMAGE_CHAT_MAP=aed9196b-********-4ed6e32f7e4d=0c6785e6-********-7ff6e5a2a29c` (即session=chatId的格式,多个请以,分隔)
|
| 214 |
+
|
| 215 |
+
### 使用YesCaptcha过谷歌验证[**暂不需要**]
|
| 216 |
+
|
| 217 |
+
> genspark官方目前文生图接口需要过谷歌验证,可使用YesCaptcha解决。
|
| 218 |
+
>
|
| 219 |
+
> **tip**: 过一次谷歌验证消耗20积分,约**0.0167元人民币**(1元人民币约能用60次)。
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
~~1. 注册 [YesCaptcha](https://yescaptcha.com/i/021iAE)[此链接注册直达**vip5**]~~
|
| 223 |
+
|
| 224 |
+
~~2. 获取`Client Key`~~
|
| 225 |
+
~~~~
|
| 226 |
+
|
| 227 |
+
~~3. 配置环变量`YES_CAPTCHA_CLIENT_KEY=******`~~
|
| 228 |
+
|
| 229 |
+
~~4. 重启服务~~
|
| 230 |
+
|
| 231 |
+
## 报错排查
|
| 232 |
+
|
| 233 |
+
> `Detected Cloudflare Challenge Page`
|
| 234 |
+
>
|
| 235 |
+
|
| 236 |
+
被Cloudflare拦截出5s盾,可配置`PROXY_URL`。
|
| 237 |
+
|
| 238 |
+
(【推荐方案】[自建ipv6代理池绕过cf对ip的速率限制及5s盾](https://linux.do/t/topic/367413)或购买[IProyal](https://iproyal.cn/?r=244330))
|
| 239 |
+
|
| 240 |
+
> `Genspark Service Unavailable`
|
| 241 |
+
>
|
| 242 |
+
Genspark官方服务不可用,请稍后再试。
|
| 243 |
+
|
| 244 |
+
> `All cookies are temporarily unavailable.`
|
| 245 |
+
>
|
| 246 |
+
所有用户(cookie)均到达速率限制,更换用户cookie或稍后再试。
|
| 247 |
+
|
| 248 |
+
## 其他
|
| 249 |
+
|
| 250 |
+
**Genspark**(
|
| 251 |
+
注册领取1个月Plus): [https://www.genspark.ai](https://www.genspark.ai/invite?invite_code=YjVjMGRkYWVMZmE4YUw5MDc0TDM1ODlMZDYwMzQ4OTJlNmEx)
|
common/config/config.go
CHANGED
|
@@ -13,8 +13,13 @@ import (
|
|
| 13 |
|
| 14 |
var ApiSecret = os.Getenv("API_SECRET")
|
| 15 |
var ApiSecrets = strings.Split(os.Getenv("API_SECRET"), ",")
|
|
|
|
| 16 |
var GSCookie = os.Getenv("GS_COOKIE")
|
| 17 |
var GSCookies = strings.Split(os.Getenv("GS_COOKIE"), ",")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
var AutoDelChat = env.Int("AUTO_DEL_CHAT", 0)
|
| 19 |
var ProxyUrl = env.String("PROXY_URL", "")
|
| 20 |
var AutoModelChatMapType = env.Int("AUTO_MODEL_CHAT_MAP_TYPE", 1)
|
|
|
|
| 13 |
|
| 14 |
var ApiSecret = os.Getenv("API_SECRET")
|
| 15 |
var ApiSecrets = strings.Split(os.Getenv("API_SECRET"), ",")
|
| 16 |
+
|
| 17 |
var GSCookie = os.Getenv("GS_COOKIE")
|
| 18 |
var GSCookies = strings.Split(os.Getenv("GS_COOKIE"), ",")
|
| 19 |
+
|
| 20 |
+
// var IpBlackList = os.Getenv("IP_BLACK_LIST")
|
| 21 |
+
var IpBlackList = strings.Split(os.Getenv("IP_BLACK_LIST"), ",")
|
| 22 |
+
|
| 23 |
var AutoDelChat = env.Int("AUTO_DEL_CHAT", 0)
|
| 24 |
var ProxyUrl = env.String("PROXY_URL", "")
|
| 25 |
var AutoModelChatMapType = env.Int("AUTO_MODEL_CHAT_MAP_TYPE", 1)
|
common/constants.go
CHANGED
|
@@ -3,7 +3,7 @@ package common
|
|
| 3 |
import "time"
|
| 4 |
|
| 5 |
var StartTime = time.Now().Unix() // unit: second
|
| 6 |
-
var Version = "v1.8.
|
| 7 |
|
| 8 |
var DefaultOpenaiModelList = []string{
|
| 9 |
"gpt-4o",
|
|
|
|
| 3 |
import "time"
|
| 4 |
|
| 5 |
var StartTime = time.Now().Unix() // unit: second
|
| 6 |
+
var Version = "v1.8.10" // this hard coding will be replaced automatically when building, no need to manually change
|
| 7 |
|
| 8 |
var DefaultOpenaiModelList = []string{
|
| 9 |
"gpt-4o",
|
controller/chat.go
CHANGED
|
@@ -323,6 +323,8 @@ func fetchImageBytes(url string) ([]byte, error) {
|
|
| 323 |
}
|
| 324 |
|
| 325 |
func createRequestBody(c *gin.Context, client cycletls.CycleTLS, cookie string, openAIReq *model.OpenAIChatCompletionRequest) (map[string]interface{}, error) {
|
|
|
|
|
|
|
| 326 |
// 处理消息中的图像 URL
|
| 327 |
err := processMessages(c, client, cookie, openAIReq.Messages)
|
| 328 |
if err != nil {
|
|
@@ -626,6 +628,11 @@ func makeDeleteRequest(client cycletls.CycleTLS, cookie, projectId string) (cycl
|
|
| 626 |
return cycletls.Response{}, nil
|
| 627 |
}
|
| 628 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 629 |
for _, v := range config.SessionImageChatMap {
|
| 630 |
if v == projectId {
|
| 631 |
return cycletls.Response{}, nil
|
|
|
|
| 323 |
}
|
| 324 |
|
| 325 |
func createRequestBody(c *gin.Context, client cycletls.CycleTLS, cookie string, openAIReq *model.OpenAIChatCompletionRequest) (map[string]interface{}, error) {
|
| 326 |
+
openAIReq.SystemMessagesProcess()
|
| 327 |
+
|
| 328 |
// 处理消息中的图像 URL
|
| 329 |
err := processMessages(c, client, cookie, openAIReq.Messages)
|
| 330 |
if err != nil {
|
|
|
|
| 628 |
return cycletls.Response{}, nil
|
| 629 |
}
|
| 630 |
}
|
| 631 |
+
for _, v := range config.GlobalSessionManager.GetChatIDsByCookie(cookie) {
|
| 632 |
+
if v == projectId {
|
| 633 |
+
return cycletls.Response{}, nil
|
| 634 |
+
}
|
| 635 |
+
}
|
| 636 |
for _, v := range config.SessionImageChatMap {
|
| 637 |
if v == projectId {
|
| 638 |
return cycletls.Response{}, nil
|
middleware/ip-list.go
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package middleware
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"genspark2api/common/config"
|
| 5 |
+
"github.com/gin-gonic/gin"
|
| 6 |
+
"net/http"
|
| 7 |
+
"strings"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
// IPBlacklistMiddleware 检查请求的IP是否在黑名单中
|
| 11 |
+
func IPBlacklistMiddleware() gin.HandlerFunc {
|
| 12 |
+
return func(c *gin.Context) {
|
| 13 |
+
// 获取请求的IP地址
|
| 14 |
+
clientIP := c.ClientIP()
|
| 15 |
+
|
| 16 |
+
// 检查IP是否在黑名单中
|
| 17 |
+
for _, blockedIP := range config.IpBlackList {
|
| 18 |
+
if strings.TrimSpace(blockedIP) == clientIP {
|
| 19 |
+
// 如果在黑名单中,返回403 Forbidden
|
| 20 |
+
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "Forbidden"})
|
| 21 |
+
return
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
// 如果不在黑名单中,继续处理请求
|
| 26 |
+
c.Next()
|
| 27 |
+
}
|
| 28 |
+
}
|
model/openai.go
CHANGED
|
@@ -16,6 +16,18 @@ type OpenAIChatMessage struct {
|
|
| 16 |
Content interface{} `json:"content"`
|
| 17 |
}
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
type OpenAIErrorResponse struct {
|
| 20 |
OpenAIError OpenAIError `json:"error"`
|
| 21 |
}
|
|
@@ -122,7 +134,7 @@ type OpenaiModelListResponse struct {
|
|
| 122 |
Data []OpenaiModelResponse `json:"data"`
|
| 123 |
}
|
| 124 |
|
| 125 |
-
func (r OpenAIChatCompletionRequest) GetUserContent() []string {
|
| 126 |
var userContent []string
|
| 127 |
|
| 128 |
for i := len(r.Messages) - 1; i >= 0; i-- {
|
|
|
|
| 16 |
Content interface{} `json:"content"`
|
| 17 |
}
|
| 18 |
|
| 19 |
+
func (r *OpenAIChatCompletionRequest) SystemMessagesProcess() {
|
| 20 |
+
if r.Messages == nil {
|
| 21 |
+
return
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
for i := range r.Messages {
|
| 25 |
+
if r.Messages[i].Role == "system" {
|
| 26 |
+
r.Messages[i].Role = "user"
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
type OpenAIErrorResponse struct {
|
| 32 |
OpenAIError OpenAIError `json:"error"`
|
| 33 |
}
|
|
|
|
| 134 |
Data []OpenaiModelResponse `json:"data"`
|
| 135 |
}
|
| 136 |
|
| 137 |
+
func (r *OpenAIChatCompletionRequest) GetUserContent() []string {
|
| 138 |
var userContent []string
|
| 139 |
|
| 140 |
for i := len(r.Messages) - 1; i >= 0; i-- {
|
router/api-router.go
CHANGED
|
@@ -9,6 +9,7 @@ import (
|
|
| 9 |
func SetApiRouter(router *gin.Engine) {
|
| 10 |
router.Use(middleware.CORS())
|
| 11 |
//router.Use(gzip.Gzip(gzip.DefaultCompression))
|
|
|
|
| 12 |
router.Use(middleware.RequestRateLimit())
|
| 13 |
|
| 14 |
router.GET("/")
|
|
|
|
| 9 |
func SetApiRouter(router *gin.Engine) {
|
| 10 |
router.Use(middleware.CORS())
|
| 11 |
//router.Use(gzip.Gzip(gzip.DefaultCompression))
|
| 12 |
+
router.Use(middleware.IPBlacklistMiddleware())
|
| 13 |
router.Use(middleware.RequestRateLimit())
|
| 14 |
|
| 15 |
router.GET("/")
|