Skip to content

Commit

Permalink
update go sdk: chat, conversation, quota, subscription api
Browse files Browse the repository at this point in the history
  • Loading branch information
zmh-program committed Oct 14, 2023
1 parent 8a6706f commit c3cda2a
Show file tree
Hide file tree
Showing 12 changed files with 552 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
*.exe
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# chatnio-api-go
The official Go library for the OpenAI API
# ChatNio Go Library

---
The official Go library for the Chat Nio API

- Authors: Deeptrain Team
- Free software: MIT license
- Documentation: https://docs.chatnio.net
78 changes: 78 additions & 0 deletions chat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package chatnio

import "github.com/Deeptrain-Community/chatnio-api-go/utils"

type Chat struct {
Id int
Uri string
Token string
Conn *utils.WebSocket
}

type ChatAuthForm struct {
Id int `json:"id"`
Token string `json:"token"`
}

type ChatRequestForm struct {
Message string `json:"message"`
Model string `json:"model"`
Web bool `json:"web"`
}

type ChatPartialResponse struct {
Message string `json:"message"`
Keyword string `json:"keyword"`
Quota float32 `json:"quota"`
End bool `json:"end"`
}

func (i *Instance) NewChat(id int) *Chat {
return &Chat{
Id: id,
Uri: i.GetChatEndpoint(),
Token: i.GetApiKey(),
Conn: utils.NewWebsocket(i.GetChatEndpoint()),
}
}

func (c *Chat) Send(v interface{}) bool {
return c.Conn.Send(v)
}

func (c *Chat) Close() error {
return c.Conn.Close()
}

func (c *Chat) SendAuthRequest() bool {
return c.Send(ChatAuthForm{
Id: c.Id,
Token: c.Token,
})
}

func (c *Chat) AskStream(form *ChatRequestForm, callback func(ChatPartialResponse)) {
// for authentication
if c.Conn.IsEmpty() {
c.SendAuthRequest()
}

c.Send(form)
for {
form := utils.ReadForm[ChatPartialResponse](c.Conn)
if form == nil {
continue
}

callback(*form)
if form.End {
break
}
}
}

func (c *Chat) Ask(form *ChatRequestForm, channel chan ChatPartialResponse) {
c.AskStream(form, func(res ChatPartialResponse) {
channel <- res
})
}
70 changes: 70 additions & 0 deletions conversation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package chatnio

import (
"fmt"
"github.com/Deeptrain-Community/chatnio-api-go/utils"
)

type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}

type Conversation struct {
Id int `json:"id"`
Name string `json:"name"`
Message []Message `json:"message"`
}

type ConversationList struct {
Status bool `json:"status"`
Message string `json:"message"`
Data []Conversation `json:"data"`
}

type ConversationLoad struct {
Status bool `json:"status"`
Message string `json:"message"`
Data Conversation `json:"data"`
}

type ConversationDelete struct {
Status bool `json:"status"`
Message string `json:"message"`
}

func (i *Instance) GetConversationList() ([]Conversation, error) {
data, err := utils.GetForm[ConversationList](i.Mix("/conversation/list"), i.GetHeaders())

if err != nil {
return nil, err
} else if !data.Status {
return nil, fmt.Errorf(data.Message)
}

return data.Data, nil
}

func (i *Instance) GetConversation(id int) (*Conversation, error) {
data, err := utils.GetForm[ConversationLoad](i.Mix(fmt.Sprintf("/conversation/load?id=%d", id)), i.GetHeaders())

if err != nil {
return nil, err
} else if !data.Status {
return nil, fmt.Errorf(data.Message)
}

return &data.Data, nil
}

func (i *Instance) DeleteConversation(id int) error {
data, err := utils.GetForm[ConversationDelete](i.Mix(fmt.Sprintf("/conversation/delete?id=%d", id)), i.GetHeaders())

if err != nil {
return err
} else if !data.Status {
return fmt.Errorf(data.Message)
}

return nil
}
11 changes: 11 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module github.com/Deeptrain-Community/chatnio-api-go

go 1.20

require (
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/klauspost/compress v1.17.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.50.0 // indirect
)
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/klauspost/compress v1.17.1/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
76 changes: 76 additions & 0 deletions instance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package chatnio

import (
"fmt"
"github.com/Deeptrain-Community/chatnio-api-go/utils"
"os"
"strings"
)

type Instance struct {
ApiKey string
Endpoint string
}

func (i *Instance) GetApiKey() string {
return i.ApiKey
}

func (i *Instance) GetEndpoint() string {
if i.Endpoint == "" {
return "https://api.chatnio.net"
}
return i.Endpoint
}

func (i *Instance) SetApiKey(apiKey string) {
i.ApiKey = apiKey
}

func (i *Instance) SetEndpoint(endpoint string) {
if strings.HasSuffix(endpoint, "/") {
endpoint = strings.TrimSuffix(endpoint, "/")
}
i.Endpoint = endpoint
}

func (i *Instance) GetChatApiKey() string {
if !i.IsAuthenticated() {
return "anonymous"
}
return i.ApiKey
}

func (i *Instance) IsAuthenticated() bool {
return strings.TrimSpace(i.ApiKey) != ""
}

func (i *Instance) GetChatEndpoint() string {
host := utils.TrimPrefixes(i.Endpoint, "http://", "https://")
return fmt.Sprintf("wss://%s/chat", host)
}

func (i *Instance) GetHeaders() utils.Headers {
return utils.Headers{
"Authorization": fmt.Sprintf("Bearer %s", i.GetApiKey()),
"Content-Type": "application/json",
"Accept": "application/json",
}
}

func (i *Instance) Mix(path string) string {
return i.GetEndpoint() + path
}

// NewInstance creates a new instance of the chatnio client
func NewInstance(key string) *Instance {
return &Instance{
ApiKey: key,
}
}

// NewInstanceFromEnv creates a new instance of the chatnio client from the environment
func NewInstanceFromEnv(env string) *Instance {
key := os.Getenv(env)
return NewInstance(key)
}
99 changes: 99 additions & 0 deletions quota.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package chatnio

import (
"fmt"
"github.com/Deeptrain-Community/chatnio-api-go/utils"
)

type Quota struct {
Status bool `json:"status"`
Quota float32 `json:"quota"`
}

type QuotaBuy struct {
Status bool `json:"status"`
Error string `json:"error"`
}

type Package struct {
Status bool `json:"status"`
Data struct {
Cert bool `json:"cert"`
Teenager bool `json:"teenager"`
} `json:"data"`
}

type Subscription struct {
Status bool `json:"status"`
IsSubscribed bool `json:"is_subscribed"`
Expired int64 `json:"expired"`
}

type Subscribe struct {
Status bool `json:"status"`
Error string `json:"error"`
}

func (i *Instance) GetQuota() (float32, error) {
quota, err := utils.GetForm[Quota](i.Mix("/quota"), i.GetHeaders())

if err != nil {
return 0., err
} else if !quota.Status {
return 0., fmt.Errorf("quota status is false")
}

return quota.Quota, nil
}

func (i *Instance) BuyQuota(quota int) error {
data, err := utils.PostForm[QuotaBuy](i.Mix("/buy"), i.GetHeaders(), map[string]interface{}{
"quota": quota,
})

if err != nil {
return err
} else if !data.Status {
return fmt.Errorf(data.Error)
}

return nil
}

func (i *Instance) GetPackage() (*Package, error) {
data, err := utils.GetForm[Package](i.Mix("/package"), i.GetHeaders())

if err != nil {
return nil, err
} else if !data.Status {
return nil, fmt.Errorf("package status is false")
}

return data, nil
}

func (i *Instance) GetSubscription() (*Subscription, error) {
data, err := utils.GetForm[Subscription](i.Mix("/subscription"), i.GetHeaders())

if err != nil {
return nil, err
} else if !data.Status {
return nil, fmt.Errorf("subscription status is false")
}

return data, nil
}

func (i *Instance) Subscribe(month int) error {
data, err := utils.PostForm[Subscribe](i.Mix("/subscribe"), i.GetHeaders(), map[string]interface{}{
"month": month,
})

if err != nil {
return err
} else if !data.Status {
return fmt.Errorf(data.Error)
}

return nil
}
12 changes: 12 additions & 0 deletions utils/base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package utils

import (
"strings"
)

func TrimPrefixes(s string, prefixes ...string) string {
for _, prefix := range prefixes {
s = strings.TrimPrefix(s, prefix)
}
return s
}
Loading

0 comments on commit c3cda2a

Please sign in to comment.