113 lines
3.3 KiB
Go
113 lines
3.3 KiB
Go
package ws
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"log/slog"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
type WebsocketGateway struct {
|
|
port int
|
|
apiKey string
|
|
bodySizeBytes int64
|
|
|
|
upgrader websocket.Upgrader
|
|
connsMu sync.Mutex
|
|
conns map[*websocket.Conn]connMetadata
|
|
|
|
modHandler ModHandler
|
|
botHandler BotHandler
|
|
|
|
logger *slog.Logger
|
|
closefn func() error
|
|
}
|
|
|
|
type User struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
// GatewayModMessageIn : Mod -> Gateway -> Bot
|
|
type GatewayModMessageIn struct {
|
|
MsgID string `json:"msg_id"`
|
|
Server string `json:"server"`
|
|
User User `json:"user"`
|
|
Content string `json:"content"`
|
|
Meta map[string]interface{} `json:"meta,omitempty"`
|
|
Ts string `json:"ts,omitempty"`
|
|
ReceivedAt time.Time `json:"-"` // ReceivedAt is populated by gateway (not from mod)
|
|
}
|
|
|
|
// GatewayBotMessageIn : Bot -> Gateway -> Mod
|
|
type GatewayBotMessageIn struct {
|
|
MsgID string `json:"msg_id"`
|
|
ChannelID string `json:"channel_id"`
|
|
Author string `json:"author"`
|
|
Content string `json:"content"`
|
|
Meta map[string]interface{} `json:"meta,omitempty"`
|
|
Ts string `json:"ts,omitempty"`
|
|
ReceivedAt time.Time `json:"-"`
|
|
}
|
|
|
|
// ForwardedModMessage : Gateway<GatewayModMessageIn> -> Bot
|
|
type ForwardedModMessage struct {
|
|
Type string `json:"type"` // "mod"
|
|
ServerID string `json:"server_id"`
|
|
ChannelID string `json:"channel_id"`
|
|
User User `json:"user"`
|
|
Content string `json:"content"`
|
|
Meta map[string]interface{} `json:"meta,omitempty"`
|
|
Ts string `json:"ts,omitempty"`
|
|
ReceivedAt time.Time `json:"received_at"`
|
|
ForwardedAt time.Time `json:"forwarded_at"`
|
|
}
|
|
|
|
// ForwardedBotMessage : Gateway<GatewayBotMessageIn> -> Mod
|
|
type ForwardedBotMessage struct {
|
|
Type string `json:"type"` // "bot"
|
|
ServerID string `json:"server_id"`
|
|
ChannelID string `json:"channel_id"`
|
|
Author string `json:"author"`
|
|
Content string `json:"content"`
|
|
Meta map[string]interface{} `json:"meta,omitempty"`
|
|
Ts string `json:"ts,omitempty"`
|
|
ReceivedAt time.Time `json:"received_at"`
|
|
ForwardedAt time.Time `json:"forwarded_at"`
|
|
}
|
|
|
|
type BotAck struct {
|
|
Type string `json:"type"` // "acknowledge"
|
|
MsgID string `json:"msg_id"`
|
|
Status string `json:"status,omitempty"` // "queued"/"sent"
|
|
}
|
|
|
|
type MessageEnvelope struct {
|
|
Type string `json:"type"` // "mod" or "bot"
|
|
Data json.RawMessage `json:"data"`
|
|
}
|
|
|
|
type ModHandler interface {
|
|
Handle(ctx context.Context, msg GatewayModMessageIn) error
|
|
}
|
|
|
|
type BotHandler interface {
|
|
Handle(ctx context.Context, msg GatewayBotMessageIn) error
|
|
}
|
|
|
|
type ModHandshake struct {
|
|
ServerID string `json:"server_id"`
|
|
}
|
|
|
|
type BotHandshake struct {
|
|
BotID string `json:"bot_id"`
|
|
}
|
|
|
|
type connMetadata struct {
|
|
connType string // "mod" or "bot"
|
|
id string // server_id or bot_id for logging
|
|
}
|