Skip to content

Commit

Permalink
refactor!: split gateway into separate module from client
Browse files Browse the repository at this point in the history
  • Loading branch information
ooliver1 committed Aug 10, 2023
1 parent 3c9facc commit e89cef3
Show file tree
Hide file tree
Showing 28 changed files with 730 additions and 311 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@

# Go workspace file
go.work
main
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

An Eludris API wrapper written in go.

This takes heavy inspiration from [Disgo](https://github.com/disgoorg/disgo).

## Installation

```bash
Expand Down
15 changes: 8 additions & 7 deletions _test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@
package main

import (
"context"
"fmt"
"os"
"os/signal" // whatsapp
"syscall"

"github.com/apex/log"
"github.com/apex/log/handlers/text"
"github.com/eludris-community/eludris.go/v2"
"github.com/eludris-community/eludris.go/v2/client"
"github.com/eludris-community/eludris.go/v2/events"
"github.com/eludris-community/eludris.go/v2/interfaces"
)

func onMessage(msg *events.MessageEvent, c interfaces.Client) {
func onMessage(msg *events.MessageCreate) {
c := msg.Client()
if msg.Author == "hello" {
return
}
Expand Down Expand Up @@ -52,18 +54,17 @@ func main() {
log.SetLevel(log.DebugLevel)
log.SetHandler(text.Default)

manager := events.NewEventManager()
events.Subscribe(manager, onMessage)
c, err := client.New(
client.WithEventManagerOpts(events.WithListenerFunc(onMessage)),
c, err := eludris.New(
client.WithEventManagerOpts(client.WithListenerFunc(onMessage)),
client.WithHttpUrl(HTTPUrl),
client.WithDefaultGateway(),
)

if err != nil {
panic(err)
}

if err := c.Connect(); err != nil {
if err := c.ConnectGateway(context.TODO()); err != nil {
panic(err)
}

Expand Down
103 changes: 69 additions & 34 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,73 @@
package client

import (
"errors"
"context"
"io"
"net/http"

"github.com/eludris-community/eludris-api-types.go/models"
"github.com/eludris-community/eludris.go/v2/events"
"github.com/eludris-community/eludris.go/v2/interfaces"
"github.com/eludris-community/eludris-api-types.go/v2/models"
"github.com/eludris-community/eludris.go/v2/gateway"
"github.com/eludris-community/eludris.go/v2/types"
)

var (
ErrNoHttpUrl = errors.New("HttpUrl is required")
)
// Client represents a client for Eludris, with functions to interact with the API.
type Client interface {
ConnectGateway(ctx context.Context) error
EventManager() EventManager

// SendMessage sends a message to the chat.
// Returns the message that was sent.
// Author must be between 1 and 32 characters long.
// Content must be between 1 and the instance's configured max message length.
SendMessage(author, content string) (models.Message, error)

// UploadAttachment uploads a file to the instance's attachments bucket.
UploadAttachment(file io.Reader, spoiler bool) (models.FileData, error)
// UploadFile uploads a file to a specific bucket.
// Currently only "attachments" exists.
UploadFile(bucket string, file io.Reader, spoiler bool) (models.FileData, error)
// FetchAttachment fetches a file from the instance's attachments bucket.
FetchAttachment(id string) (io.ReadCloser, error)
// FetchFile fetches a file from a specific bucket.
// Currently only "attachments" exists.
FetchFile(bucket, id string) (io.ReadCloser, error)
// FetchAttachmentData fetches a file from the instance's attachments bucket.
FetchAttachmentData(id string) (models.FileData, error)
// FetchFileData fetches a file from a specific bucket.
// Currently only "attachments" exists.
FetchFileData(bucket, id string) (models.FileData, error)
}

type clientImpl struct {
httpUrl string
wsUrl string
fileUrl string
httpClient http.Client
eventManager events.EventManager
gateway gateway.Gateway
eventManager EventManager
rateLimiter RateLimiter
}

// BuildClient builds a client from a configuration.
func BuildClient(config *Config) (interfaces.Client, error) {
func BuildClient(config *Config) (Client, error) {
if config.HttpUrl == "" {
return nil, ErrNoHttpUrl
return nil, types.ErrNoHttpUrl
}

client := &clientImpl{}

if config.EventManager == nil {
config.EventManager = NewEventManager(client, config.EventManagerOpts...)
}
client.eventManager = config.EventManager

if config.RateLimiter == nil {
config.RateLimiter = NewRateLimiter(config.RateLimiterOpts...)
}
client.rateLimiter = config.RateLimiter

client.httpUrl = config.HttpUrl
if config.WsUrl == "" || config.FileUrl == "" {
tmp := clientImpl{httpUrl: config.HttpUrl, rateLimiter: NewRateLimiter()}
info, err := tmp.FetchInstanceInfo()
info, err := client.FetchInstanceInfo()
if err != nil {
return nil, err
}
Expand All @@ -46,30 +83,16 @@ func BuildClient(config *Config) (interfaces.Client, error) {
}
}

if config.EventManager == nil {
config.EventManager = events.NewEventManager(config.EventManagerOpts...)
}
if config.Gateway == nil && len(config.GatewayOpts) > 0 {
config.GatewayOpts = append([]gateway.ConfigOpt{
gateway.WithURL(config.WsUrl),
}, config.GatewayOpts...)

if config.RateLimiter == nil {
config.RateLimiter = NewRateLimiter(config.RateLimiterOpts...)
config.Gateway = gateway.New(config.EventManager.HandleGatewayEvent, config.GatewayOpts...)
}
client.gateway = config.Gateway

return &clientImpl{
httpUrl: config.HttpUrl,
wsUrl: config.WsUrl,
fileUrl: config.FileUrl,
httpClient: http.Client{},
eventManager: config.EventManager,
rateLimiter: config.RateLimiter,
}, nil
}

// New creates a new client.
func New(opts ...ConfigOpt) (interfaces.Client, error) {
config := DefaultConfig()
config.Apply(opts)

return BuildClient(config)
return client, nil
}

// FetchInstanceInfo fetches information about the instance.
Expand All @@ -79,3 +102,15 @@ func (c *clientImpl) FetchInstanceInfo() (models.InstanceInfo, error) {

return res, err
}

func (c *clientImpl) EventManager() EventManager {
return c.eventManager
}

func (c *clientImpl) ConnectGateway(ctx context.Context) error {
if c.gateway == nil {
return types.ErrNoGateway
}

return c.gateway.Connect(ctx)
}
44 changes: 35 additions & 9 deletions client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

package client

import "github.com/eludris-community/eludris.go/v2/events"
import (
"github.com/eludris-community/eludris-api-types.go/v2/pandemonium"
"github.com/eludris-community/eludris.go/v2/gateway"
)

type ConfigOpt func(config *Config)

Expand All @@ -19,18 +22,22 @@ type Config struct {
// This is obtainable from HTTPUrl if not set.
FileUrl string
// An event manager to use for the client.
EventManager events.EventManager
EventManager EventManager
// Options to apply to EventManager
EventManagerOpts []events.EventManagerOpt
EventManagerOpts []EventManagerOpt
// A rate limiter to use for the client.
RateLimiter RateLimiter
// Options to apply to RateLimiter
RateLimiterOpts []RateLimiterOpt
Gateway gateway.Gateway
GatewayOpts []gateway.ConfigOpt
}

// DefaultConfig returns a new Config with default values.
func DefaultConfig() *Config {
return &Config{}
func DefaultConfig(gatewayHandlers map[pandemonium.OpcodeType]GatewayEventHandler) *Config {
return &Config{
EventManagerOpts: []EventManagerOpt{WithGatewayHandlers(gatewayHandlers)},
}
}

// Apply applies the given ConfigOpts to the Config.
Expand Down Expand Up @@ -62,16 +69,16 @@ func WithFileUrl(url string) ConfigOpt {
}

// WithEventManager returns a ConfigOpt that sets the event manager.
func WithEventManager(manager events.EventManager) ConfigOpt {
func WithEventManager(manager EventManager) ConfigOpt {
return func(config *Config) {
config.EventManager = manager
}
}

// WithEventManagerOpts returns a ConfigOpt that sets the event manager options.
func WithEventManagerOpts(opts ...events.EventManagerOpt) ConfigOpt {
func WithEventManagerOpts(opts ...EventManagerOpt) ConfigOpt {
return func(config *Config) {
config.EventManagerOpts = opts
config.EventManagerOpts = append(config.EventManagerOpts, opts...)
}
}

Expand All @@ -85,6 +92,25 @@ func WithRateLimiter(limiter RateLimiter) ConfigOpt {
// WithRateLimiterOpts returns a ConfigOpt that sets the rate limiter options.
func WithRateLimiterOpts(opts ...RateLimiterOpt) ConfigOpt {
return func(config *Config) {
config.RateLimiterOpts = opts
config.RateLimiterOpts = append(config.RateLimiterOpts, opts...)
}
}

// WithGateway lets you inject your own gateway.Gateway.
func WithGateway(gateway gateway.Gateway) ConfigOpt {
return func(config *Config) {
config.Gateway = gateway
}
}

func WithDefaultGateway() ConfigOpt {
return func(config *Config) {
config.GatewayOpts = append(config.GatewayOpts, func(_ *gateway.Config) {})
}
}

func WithGatewayConfigOpts(opts ...gateway.ConfigOpt) ConfigOpt {
return func(config *Config) {
config.GatewayOpts = append(config.GatewayOpts, opts...)
}
}
Loading

0 comments on commit e89cef3

Please sign in to comment.