From c48b7bc0f5448f9a7e9a729850c5de0c783f9c1a Mon Sep 17 00:00:00 2001
From: JustSong
Date: Mon, 3 Jul 2023 19:49:39 +0800
Subject: [PATCH 1/3] docs: update README
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index fad214c1..a9780d07 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,8 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用
赞赏支持
+> **Warning**:本项目为开源项目,请在遵循 OpenAI 的[使用条款](https://openai.com/policies/terms-of-use)以及**法律法规**的情况下使用,不得用于非法用途。
+
> **Note**:使用 Docker 拉取的最新镜像可能是 `alpha` 版本,如果追求稳定性请手动指定版本。
> **Warning**:从 `v0.3` 版本升级到 `v0.4` 版本需要手动迁移数据库,请手动执行[数据库迁移脚本](./bin/migration_v0.3-v0.4.sql)。
@@ -324,7 +326,6 @@ https://openai.justsong.cn
[FastGPT](https://github.com/c121914yu/FastGPT): 三分钟搭建 AI 知识库
## 注意
-本项目为开源项目,请在遵循 OpenAI 的[使用条款](https://openai.com/policies/terms-of-use)以及**法律法规**的情况下使用,不得用于非法用途。
本项目使用 MIT 协议进行开源,**在此基础上**,必须在页面底部保留署名以及指向本项目的链接。如果不想保留署名,必须首先获得授权。
From 04f40def2f6670a874ead0b7f5262c3b34a78f20 Mon Sep 17 00:00:00 2001
From: JustSong
Date: Mon, 3 Jul 2023 19:51:12 +0800
Subject: [PATCH 2/3] docs: update README
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index a9780d07..c54450ee 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用
赞赏支持
-> **Warning**:本项目为开源项目,请在遵循 OpenAI 的[使用条款](https://openai.com/policies/terms-of-use)以及**法律法规**的情况下使用,不得用于非法用途。
+> **Note**:本项目为开源项目,请在遵循 OpenAI 的[使用条款](https://openai.com/policies/terms-of-use)以及**法律法规**的情况下使用,不得用于非法用途。
> **Note**:使用 Docker 拉取的最新镜像可能是 `alpha` 版本,如果追求稳定性请手动指定版本。
From d383302e8ae10131e7539921e1530520404b516b Mon Sep 17 00:00:00 2001
From: Cross Fire <9145160+diemus@users.noreply.github.com>
Date: Mon, 3 Jul 2023 20:43:42 +0800
Subject: [PATCH 3/3] feat: support balance query for CloseAI (#240)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 增加CloseAI余额查询功能
* 去除debug代码
* fix: bug fix
* docs: update README
---------
Co-authored-by: sudongyang
Co-authored-by: JustSong
---
README.md | 1 +
common/constants.go | 28 ++++++++++++++--------------
controller/channel-billing.go | 28 ++++++++++++++++++++++++++++
web/src/components/ChannelsTable.js | 3 +++
4 files changed, 46 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index c54450ee..9280a347 100644
--- a/README.md
+++ b/README.md
@@ -66,6 +66,7 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用
+ [x] [API2D](https://api2d.com/r/197971)
+ [x] [OhMyGPT](https://aigptx.top?aff=uFpUl2Kf)
+ [x] [AI Proxy](https://aiproxy.io/?i=OneAPI) (邀请码:`OneAPI`)
+ + [x] [CloseAI](https://console.closeai-asia.com/r/2412)
+ [x] 自定义渠道:例如各种未收录的第三方代理服务
2. 支持通过**负载均衡**的方式访问多个渠道。
3. 支持 **stream 模式**,可以通过流式传输实现打字机效果。
diff --git a/common/constants.go b/common/constants.go
index a850b3e8..08754213 100644
--- a/common/constants.go
+++ b/common/constants.go
@@ -152,18 +152,18 @@ const (
)
var ChannelBaseURLs = []string{
- "", // 0
- "https://api.openai.com", // 1
- "https://oa.api2d.net", // 2
- "", // 3
- "https://api.openai-proxy.org", // 4
- "https://api.openai-sb.com", // 5
- "https://api.openaimax.com", // 6
- "https://api.ohmygpt.com", // 7
- "", // 8
- "https://api.caipacity.com", // 9
- "https://api.aiproxy.io", // 10
- "", // 11
- "https://api.api2gpt.com", // 12
- "https://api.aigc2d.com", // 13
+ "", // 0
+ "https://api.openai.com", // 1
+ "https://oa.api2d.net", // 2
+ "", // 3
+ "https://api.closeai-proxy.xyz", // 4
+ "https://api.openai-sb.com", // 5
+ "https://api.openaimax.com", // 6
+ "https://api.ohmygpt.com", // 7
+ "", // 8
+ "https://api.caipacity.com", // 9
+ "https://api.aiproxy.io", // 10
+ "", // 11
+ "https://api.api2gpt.com", // 12
+ "https://api.aigc2d.com", // 13
}
diff --git a/controller/channel-billing.go b/controller/channel-billing.go
index 4026e583..31c9a133 100644
--- a/controller/channel-billing.go
+++ b/controller/channel-billing.go
@@ -32,6 +32,13 @@ type OpenAIUsageDailyCost struct {
}
}
+type OpenAICreditGrants struct {
+ Object string `json:"object"`
+ TotalGranted float64 `json:"total_granted"`
+ TotalUsed float64 `json:"total_used"`
+ TotalAvailable float64 `json:"total_available"`
+}
+
type OpenAIUsageResponse struct {
Object string `json:"object"`
//DailyCosts []OpenAIUsageDailyCost `json:"daily_costs"`
@@ -100,6 +107,22 @@ func GetResponseBody(method, url string, channel *model.Channel, headers http.He
return body, nil
}
+func updateChannelCloseAIBalance(channel *model.Channel) (float64, error) {
+ url := fmt.Sprintf("%s/dashboard/billing/credit_grants", channel.BaseURL)
+ body, err := GetResponseBody("GET", url, channel, GetAuthHeader(channel.Key))
+
+ if err != nil {
+ return 0, err
+ }
+ response := OpenAICreditGrants{}
+ err = json.Unmarshal(body, &response)
+ if err != nil {
+ return 0, err
+ }
+ channel.UpdateBalance(response.TotalAvailable)
+ return response.TotalAvailable, nil
+}
+
func updateChannelOpenAISBBalance(channel *model.Channel) (float64, error) {
url := fmt.Sprintf("https://api.openai-sb.com/sb-api/user/status?api_key=%s", channel.Key)
body, err := GetResponseBody("GET", url, channel, GetAuthHeader(channel.Key))
@@ -175,6 +198,9 @@ func updateChannelAIGC2DBalance(channel *model.Channel) (float64, error) {
func updateChannelBalance(channel *model.Channel) (float64, error) {
baseURL := common.ChannelBaseURLs[channel.Type]
+ if channel.BaseURL == "" {
+ channel.BaseURL = baseURL
+ }
switch channel.Type {
case common.ChannelTypeOpenAI:
if channel.BaseURL != "" {
@@ -184,6 +210,8 @@ func updateChannelBalance(channel *model.Channel) (float64, error) {
return 0, errors.New("尚未实现")
case common.ChannelTypeCustom:
baseURL = channel.BaseURL
+ case common.ChannelTypeCloseAI:
+ return updateChannelCloseAIBalance(channel)
case common.ChannelTypeOpenAISB:
return updateChannelOpenAISBBalance(channel)
case common.ChannelTypeAIProxy:
diff --git a/web/src/components/ChannelsTable.js b/web/src/components/ChannelsTable.js
index 0b29ff9e..4ea6965d 100644
--- a/web/src/components/ChannelsTable.js
+++ b/web/src/components/ChannelsTable.js
@@ -30,6 +30,9 @@ function renderType(type) {
function renderBalance(type, balance) {
switch (type) {
case 1: // OpenAI
+ return ${balance.toFixed(2)};
+ case 4: // CloseAI
+ return ¥{balance.toFixed(2)};
case 8: // 自定义
return ${balance.toFixed(2)};
case 5: // OpenAI-SB