Bläddra i källkod

feat: 添加查询余额的交互能力 (#68)

二丫讲梵 2 år sedan
förälder
incheckning
510d9c5324
5 ändrade filer med 81 tillägg och 0 borttagningar
  1. 8 0
      README.md
  2. 2 0
      go.mod
  3. 9 0
      go.sum
  4. 16 0
      main.go
  5. 46 0
      public/gpt.go

+ 8 - 0
README.md

@@ -81,6 +81,8 @@
 $ docker run -itd --name chatgpt -p 8090:8090 -e APIKEY=换成你的key -e SESSION_TIMEOUT=600 -e HTTP_PROXY="" -e DEFAULT_MODE="单聊" --restart=always  dockerproxy.com/eryajf/chatgpt-dingtalk:latest
 ```
 
+`📢 注意:`如果你使用docker部署,那么proxy指定地址的时候,请指定宿主机的IP,而不要写成127,以免代理不生效。
+
 运行命令中映射的配置文件参考下边的配置文件说明。
 
 `第二种:基于配置文件挂载运行`
@@ -170,6 +172,12 @@ $ curl --location --request POST 'http://chat.eryajf.net/' \
 > 📢 注意:串聊模式下,群里每个人的聊天上下文是独立的。
 > 📢 注意:默认对话模式为单聊,因此不必发送单聊即可进入单聊模式,而要进入串聊,则需要发送串聊关键字进行切换,当串聊内容超过最大限制的时候,你可以发送重置,然后再次进入串聊模式。
 
+`查询余额`
+
+> 艾特机器人发送 `余额` 二字,会返回当前key对应的账号的剩余额度以及可用日期。
+
+![image_20230304_222522](https://cdn.staticaly.com/gh/eryajf/tu/main/img/image_20230304_222522.jpg)
+
 `实际聊天效果如下`
 
 ![image_20221209_163739](https://cdn.staticaly.com/gh/eryajf/tu/main/img/image_20221209_163739.png)

+ 2 - 0
go.mod

@@ -3,6 +3,7 @@ module github.com/eryajf/chatgpt-dingtalk
 go 1.18
 
 require (
+	github.com/go-resty/resty/v2 v2.7.0
 	github.com/patrickmn/go-cache v2.1.0+incompatible
 	github.com/solywsh/chatgpt v0.0.14
 )
@@ -10,6 +11,7 @@ require (
 require (
 	github.com/joho/godotenv v1.5.1 // indirect
 	github.com/sashabaranov/go-gpt3 v1.3.0 // indirect
+	golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect
 )
 
 replace github.com/solywsh/chatgpt => ./pkg/chatgpt

+ 9 - 0
go.sum

@@ -1,6 +1,15 @@
+github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
+github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
 github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
 github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
 github.com/sashabaranov/go-gpt3 v1.3.0 h1:IbvaK2yTnlm7f/oiC2HC9cbzu/4Znt4GkarFiwZ60uI=
 github.com/sashabaranov/go-gpt3 v1.3.0/go.mod h1:BIZdbwdzxZbCrcKGMGH6u2eyGe1xFuX9Anmh3tCP8lQ=
+golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM=
+golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

+ 16 - 0
main.go

@@ -6,6 +6,7 @@ import (
 	"io/ioutil"
 	"net/http"
 	"strings"
+	"time"
 
 	"github.com/eryajf/chatgpt-dingtalk/config"
 	"github.com/eryajf/chatgpt-dingtalk/public"
@@ -25,6 +26,7 @@ var Welcome string = `Commands:
 🙋 单聊 👉 单独聊天
 📣 串聊 👉 带上下文聊天
 🔃 重置 👉 重置带上下文聊天
+💵 余额 👉 查询剩余额度
 🚀 帮助 👉 显示帮助信息
 =================================
 🚜 例:@我发送 空 或 帮助 将返回此帮助信息
@@ -107,6 +109,20 @@ func ProcessRequest(rmsg public.ReceiveMsg) error {
 		if err != nil {
 			logger.Warning(fmt.Errorf("send message error: %v", err))
 		}
+	case "余额":
+		rst, err := public.GetBalance()
+		if err != nil {
+			logger.Warning(fmt.Errorf("get balance error: %v", err))
+			return err
+		}
+		t1 := time.Unix(int64(rst.Grants.Data[0].EffectiveAt), 0)
+		t2 := time.Unix(int64(rst.Grants.Data[0].ExpiresAt), 0)
+		msg := fmt.Sprintf("💵 已用: 💲%v\n💵 剩余: 💲%v\n⏳ 有效时间: 从 %v 到 %v\n", fmt.Sprintf("%.2f", rst.TotalUsed), fmt.Sprintf("%.2f", rst.TotalAvailable), t1.Format("2006-01-02 15:04:05"), t2.Format("2006-01-02 15:04:05"))
+
+		_, err = rmsg.ReplyText(msg, rmsg.SenderStaffId)
+		if err != nil {
+			logger.Warning(fmt.Errorf("send message error: %v", err))
+		}
 	default:
 		if public.FirstCheck(rmsg) {
 			return Do("串聊", rmsg)

+ 46 - 0
public/gpt.go

@@ -0,0 +1,46 @@
+package public
+
+import (
+	"encoding/json"
+	"fmt"
+	"time"
+
+	"github.com/eryajf/chatgpt-dingtalk/config"
+	"github.com/go-resty/resty/v2"
+)
+
+func InitAiCli() *resty.Client {
+	return resty.New().SetTimeout(30*time.Second).SetHeader("Authorization", fmt.Sprintf("Bearer %s", config.LoadConfig().ApiKey)).SetProxy(config.LoadConfig().HttpProxy)
+}
+
+type Billing struct {
+	Object         string  `json:"object"`
+	TotalGranted   float64 `json:"total_granted"`
+	TotalUsed      float64 `json:"total_used"`
+	TotalAvailable float64 `json:"total_available"`
+	Grants         struct {
+		Object string `json:"object"`
+		Data   []struct {
+			Object      string  `json:"object"`
+			ID          string  `json:"id"`
+			GrantAmount float64 `json:"grant_amount"`
+			UsedAmount  float64 `json:"used_amount"`
+			EffectiveAt float64 `json:"effective_at"`
+			ExpiresAt   float64 `json:"expires_at"`
+		} `json:"data"`
+	} `json:"grants"`
+}
+
+func GetBalance() (Billing, error) {
+	var data Billing
+	url := "https://api.openai.com/dashboard/billing/credit_grants"
+	resp, err := InitAiCli().R().Get(url)
+	if err != nil {
+		return data, err
+	}
+	err = json.Unmarshal(resp.Body(), &data)
+	if err != nil {
+		return data, err
+	}
+	return data, nil
+}