Просмотр исходного кода

feat: support API2GPT platform (#173)

* support API2GPT platform

* chore: update balance renderer

---------

Co-authored-by: JustSong <songquanpeng@foxmail.com>
Kidultx 2 лет назад
Родитель
Сommit
a43b1e2add

+ 1 - 0
README.md

@@ -56,6 +56,7 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用
    + [x] [OhMyGPT](https://aigptx.top?aff=uFpUl2Kf)
    + [x] [AI Proxy](https://aiproxy.io/?i=OneAPI) (邀请码:`OneAPI`)
    + [x] [OpenAI-SB](https://openai-sb.com)
+   + [x] [API2GPT](http://console.api2gpt.com/m/00002S)
    + [x] [CloseAI](https://console.openai-asia.com/r/2412)
    + [x] [AI.LS](https://ai.ls)
    + [x] [OpenAI Max](https://openaimax.com)

+ 4 - 1
common/constants.go

@@ -1,9 +1,10 @@
 package common
 
 import (
-	"github.com/google/uuid"
 	"sync"
 	"time"
+
+	"github.com/google/uuid"
 )
 
 var StartTime = time.Now().Unix() // unit: second
@@ -133,6 +134,7 @@ const (
 	ChannelTypeAILS      = 9
 	ChannelTypeAIProxy   = 10
 	ChannelTypePaLM      = 11
+	ChannelTypeAPI2GPT   = 12
 )
 
 var ChannelBaseURLs = []string{
@@ -148,4 +150,5 @@ var ChannelBaseURLs = []string{
 	"https://api.caipacity.com",   // 9
 	"https://api.aiproxy.io",      // 10
 	"",                            // 11
+	"https://api.api2gpt.com",     // 12
 }

+ 26 - 0
controller/channel-billing.go

@@ -54,6 +54,13 @@ type AIProxyUserOverviewResponse struct {
 	} `json:"data"`
 }
 
+type API2GPTUsageResponse struct {
+	Object         string  `json:"object"`
+	TotalGranted   float64 `json:"total_granted"`
+	TotalUsed      float64 `json:"total_used"`
+	TotalRemaining float64 `json:"total_remaining"`
+}
+
 // GetAuthHeader get auth header
 func GetAuthHeader(token string) http.Header {
 	h := http.Header{}
@@ -127,6 +134,23 @@ func updateChannelAIProxyBalance(channel *model.Channel) (float64, error) {
 	return response.Data.TotalPoints, nil
 }
 
+func updateChannelAPI2GPTBalance(channel *model.Channel) (float64, error) {
+	url := "https://api.api2gpt.com/dashboard/billing/credit_grants"
+	body, err := GetResponseBody("GET", url, channel, GetAuthHeader(channel.Key))
+
+	if err != nil {
+		return 0, err
+	}
+	response := API2GPTUsageResponse{}
+	err = json.Unmarshal(body, &response)
+	fmt.Print(response)
+	if err != nil {
+		return 0, err
+	}
+	channel.UpdateBalance(response.TotalRemaining)
+	return response.TotalRemaining, nil
+}
+
 func updateChannelBalance(channel *model.Channel) (float64, error) {
 	baseURL := common.ChannelBaseURLs[channel.Type]
 	switch channel.Type {
@@ -142,6 +166,8 @@ func updateChannelBalance(channel *model.Channel) (float64, error) {
 		return updateChannelOpenAISBBalance(channel)
 	case common.ChannelTypeAIProxy:
 		return updateChannelAIProxyBalance(channel)
+	case common.ChannelTypeAPI2GPT:
+		return updateChannelAPI2GPTBalance(channel)
 	default:
 		return 0, errors.New("尚未实现")
 	}

+ 2 - 0
web/src/components/ChannelsTable.js

@@ -36,6 +36,8 @@ function renderBalance(type, balance) {
       return <span>¥{(balance / 10000).toFixed(2)}</span>;
     case 10: // AI Proxy
       return <span>{renderNumber(balance)}</span>;
+    case 12: // API2GPT
+      return <span>¥{balance.toFixed(2)}</span>;
     default:
       return <span>不支持</span>;
   }

+ 2 - 1
web/src/constants/channel.constants.js

@@ -8,5 +8,6 @@ export const CHANNEL_OPTIONS = [
   { key: 6, text: 'OpenAI Max', value: 6, color: 'violet' },
   { key: 7, text: 'OhMyGPT', value: 7, color: 'purple' },
   { key: 9, text: 'AI.LS', value: 9, color: 'yellow' },
-  { key: 10, text: 'AI Proxy', value: 10, color: 'purple' }
+  { key: 10, text: 'AI Proxy', value: 10, color: 'purple' },
+  { key: 12, text: 'API2GPT', value: 12, color: 'blue' }
 ];