sandwich

package module
v0.0.0-...-cc899f0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2026 License: MIT Imports: 34 Imported by: 4

README

Sandwich Daemon

Documentation

Index

Constants

View Source
const (
	SandwichEventConfigUpdate       = "SW_CONFIGURATION_RELOAD"
	SandwichShardStatusUpdate       = "SW_SHARD_STATUS_UPDATE"
	SandwichApplicationStatusUpdate = "SW_APPLICATION_STATUS_UPDATE"
)
View Source
const (
	ReadyTimeout = 1 * time.Second

	StandardDeduplicationTimeout = time.Millisecond * 500
)
View Source
const (
	WebsocketReconnectCloseCode = 4000
)

Variables

View Source
var (
	ErrApplicationMissingIdentifier = errors.New("application missing identifier")
	ErrApplicationMissingBotToken   = errors.New("application missing bot token")
	ErrApplicationIdentifierExists  = errors.New("application identifier already exists")

	ErrApplicationInitializeFailed = errors.New("application initialize failed")
	ErrApplicationMissingShards    = errors.New("application missing shards")

	ErrApplicationNotFound       = errors.New("application not found")
	ErrApplicationAlreadyRunning = errors.New("application already running")
	ErrApplicationNotRunning     = errors.New("application not running")

	ErrShardConnectFailed            = errors.New("shard connect failed")
	ErrShardInvalidHeartbeatInterval = errors.New("shard invalid heartbeat interval")
	ErrShardStopping                 = errors.New("shard stopping")

	ErrNoGatewayHandler  = errors.New("no gateway handler found")
	ErrNoDispatchHandler = errors.New("no dispatch handler found")

	ErrGuildNotFound = errors.New("guild not found")
	ErrShardNotFound = errors.New("shard not found")
	ErrUserNotFound  = errors.New("user not found")
)
View Source
var (
	StandardIdentifyLimit = 5 * time.Second
	IdentifyRetry         = 5 * time.Second
	IdentifyRateLimit     = StandardIdentifyLimit + (time.Millisecond * 500)
)
View Source
var (
	// Number of retries to attempt before giving up on a shard
	ShardConnectRetries = int32(3)

	// Number of heartbeats that can fail before the shard is considered dead
	ShardMaxHeartbeatFailures = int32(5)

	GatewayLargeThreshold = int32(100)

	MemberChunkTimeout = time.Second * 3
)
View Source
var EventMetrics = struct {
	EventsTotal    *prometheus.CounterVec
	GatewayLatency *prometheus.GaugeVec
}{
	EventsTotal: promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "sandwich_events_total",
			Help: "Total number of events processed, split by identifier and event type",
		},
		[]string{"application_identifier", "event_type"},
	),
	GatewayLatency: promauto.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "sandwich_gateway_latency_seconds",
			Help: "Gateway latency in seconds, measured by heartbeat",
		},
		[]string{"application_identifier", "shard_id"},
	),
}

EventMetrics tracks event-related metrics.

View Source
var GRPCMetrics = struct {
	Requests prometheus.Counter
}{
	Requests: promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "sandwich_grpc_requests_total",
			Help: "Total number of GRPC requests",
		},
	),
}

GRPCMetrics tracks GRPC-related metrics.

View Source
var IgnoreHeartbeatTimeouts = strings.ToLower(os.Getenv("SANDWICH_IGNORE_HEARTBEAT_TIMEOUTS")) == "true"
View Source
var ShardMetrics = struct {
	ApplicationStatus *prometheus.GaugeVec
	ShardStatus       *prometheus.GaugeVec
}{
	ApplicationStatus: promauto.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "sandwich_shard_application_status",
			Help: "Status of the shard application",
		},
		[]string{"application_identifier"},
	),
	ShardStatus: promauto.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "sandwich_shard_status",
			Help: "Status of the shard",
		},
		[]string{"application_identifier", "shard_id"},
	),
}

ShardMetrics tracks shard-related metrics.

View Source
var StateMetrics = struct {
	StateRequests prometheus.Counter
	StateHits     prometheus.Counter
	StateMisses   prometheus.Counter
	GuildMembers  prometheus.Gauge
	GuildRoles    prometheus.Gauge
	Emojis        prometheus.Gauge
	Users         prometheus.Gauge
	Channels      prometheus.Gauge
	Stickers      prometheus.Gauge
	Guilds        prometheus.Gauge
	VoiceStates   prometheus.Gauge
}{
	StateRequests: promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "sandwich_state_requests_total",
			Help: "Total number of state requests",
		},
	),
	StateHits: promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "sandwich_state_hits_total",
			Help: "Total number of state hits",
		},
	),
	StateMisses: promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "sandwich_state_misses_total",
			Help: "Total number of state misses",
		},
	),

	GuildMembers: promauto.NewGauge(
		prometheus.GaugeOpts{
			Name: "sandwich_state_guild_members",
			Help: "Total number of guild members in state",
		},
	),
	GuildRoles: promauto.NewGauge(
		prometheus.GaugeOpts{
			Name: "sandwich_state_guild_roles",
			Help: "Total number of guild roles in state",
		},
	),
	Emojis: promauto.NewGauge(
		prometheus.GaugeOpts{
			Name: "sandwich_state_emojis",
			Help: "Total number of emojis in state",
		},
	),
	Users: promauto.NewGauge(
		prometheus.GaugeOpts{
			Name: "sandwich_state_users",
			Help: "Total number of users in state",
		},
	),
	Channels: promauto.NewGauge(
		prometheus.GaugeOpts{
			Name: "sandwich_state_channels",
			Help: "Total number of channels in state",
		},
	),
	Stickers: promauto.NewGauge(
		prometheus.GaugeOpts{
			Name: "sandwich_state_stickers",
			Help: "Total number of stickers in state",
		},
	),
	Guilds: promauto.NewGauge(
		prometheus.GaugeOpts{
			Name: "sandwich_state_guilds",
			Help: "Total number of guilds in state",
		},
	),
	VoiceStates: promauto.NewGauge(
		prometheus.GaugeOpts{
			Name: "sandwich_state_voice_states",
			Help: "Total number of voice states in state",
		},
	),
}

StateMetrics tracks state-related metrics

View Source
var UserAgent = fmt.Sprintf("Sandwich/%s (https://github.com/WelcomerTeam/Sandwich-Daemon)", Version)
View Source
var Version = "2.4"

Functions

func GatewayOpDispatch

func GatewayOpDispatch(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, trace *Trace) error

func GatewayOpHeartbeat

func GatewayOpHeartbeat(ctx context.Context, shard *Shard, _ *discord.GatewayPayload, _ *Trace) error

func GatewayOpHeartbeatAck

func GatewayOpHeartbeatAck(_ context.Context, shard *Shard, _ *discord.GatewayPayload, _ *Trace) error

func GatewayOpHello

func GatewayOpHello(_ context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) error

func GatewayOpInvalidSession

func GatewayOpInvalidSession(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) error

func GatewayOpReconnect

func GatewayOpReconnect(ctx context.Context, shard *Shard, _ *discord.GatewayPayload, _ *Trace) error

func GuildIDFromContext

func GuildIDFromContext(ctx context.Context) (discord.Snowflake, bool)

GuildIDFromContext retrieves the guild ID from the context if present

func IsStatusCodeRecoverable

func IsStatusCodeRecoverable(code websocket.StatusCode) bool

func NewInMemoryDedupeProvider

func NewInMemoryDedupeProvider() *inMemoryDedupeProvider

func NewNoopDedupeProvider

func NewNoopDedupeProvider() *noopDedupeProvider

func NewProxyClient

func NewProxyClient(client http.Client, host url.URL) *http.Client

NewProxyClient creates an HTTP client that redirects all requests through a specified host. This is useful when using a proxy such as twilight or nirn.

func RecordEvent

func RecordEvent(identifier, eventType string)

func RecordGRPCRequest

func RecordGRPCRequest()

func RecordStateHit

func RecordStateHit()

func RecordStateHitWithValue

func RecordStateHitWithValue(value float64)

func RecordStateMiss

func RecordStateMiss()

func RecordStateRequest

func RecordStateRequest()

func RegisterDispatchHandler

func RegisterDispatchHandler(eventType string, handler DispatchHandler)

func RegisterGatewayEvent

func RegisterGatewayEvent(eventType discord.GatewayOp, handler GatewayHandler)

func ReturnRangeInt32

func ReturnRangeInt32(nodeCount, nodeID int32, rangeString string, max int32) (result []int32)

ReturnRangeInt32 converts a string like 0-4,6-7 to [0,1,2,3,4,6,7].

func StateChannelToDiscord

func StateChannelToDiscord(v StateChannel) discord.Channel

func StateEmojiToDiscord

func StateEmojiToDiscord(v StateEmoji) discord.Emoji

func StateGuildMemberToDiscord

func StateGuildMemberToDiscord(v StateGuildMember) discord.GuildMember

func StateGuildToDiscord

func StateGuildToDiscord(v StateGuild) discord.Guild

func StateRoleToDiscord

func StateRoleToDiscord(v StateRole) discord.Role

func StateStickerToDiscord

func StateStickerToDiscord(v StateSticker) discord.Sticker

func StateUserToDiscord

func StateUserToDiscord(v StateUser) discord.User

func StateVoiceStateToDiscord

func StateVoiceStateToDiscord(v StateVoiceState) discord.VoiceState

func UpdateApplicationStatus

func UpdateApplicationStatus(identifier string, status ApplicationStatus)

func UpdateGatewayLatency

func UpdateGatewayLatency(identifier string, shardID int32, latency float64)

func UpdateShardStatus

func UpdateShardStatus(identifier string, shardID int32, status ShardStatus)

func UpdateStateMetrics

func UpdateStateMetrics(members, roles, emojis, users, channels, stickers, guilds, voiceStates int)

func WithGuildID

func WithGuildID(ctx context.Context, guildID discord.Snowflake) context.Context

WithGuildID adds a guild ID to the context

Types

type Application

type Application struct {
	Logger *slog.Logger

	Identifier string

	Sandwich      *Sandwich
	Configuration *atomic.Pointer[ApplicationConfiguration]

	Gateway *atomic.Pointer[discord.GatewayBotResponse]

	User *atomic.Pointer[discord.User]

	ShardCount *atomic.Int32

	Shards *syncmap.Map[int32, *Shard]

	Status *atomic.Int32
	// contains filtered or unexported fields
}

func NewApplication

func NewApplication(sandwich *Sandwich, config *ApplicationConfiguration) *Application

func (*Application) GetInitialShardCount

func (application *Application) GetInitialShardCount(customShardCount int32, customShardIDs string, autoSharded bool) ([]int32, int32)

GetInitialShardCount returns the shard IDs and shard count for the application.

func (*Application) Initialize

func (application *Application) Initialize(ctx context.Context) error

Initialize initializes the application. This includes checking the gateway

func (*Application) SetStatus

func (application *Application) SetStatus(status ApplicationStatus)

func (*Application) SetUser

func (application *Application) SetUser(user *discord.User)

func (*Application) Start

func (application *Application) Start(ctx context.Context) error

func (*Application) StartShards

func (application *Application) StartShards(ctx context.Context, shardIDs []int32, shardCount int32) (ready chan struct{}, err error)

func (*Application) Stop

func (application *Application) Stop(ctx context.Context) error

type ApplicationConfiguration

type ApplicationConfiguration struct {
	// ApplicationIdentifier used in internal APIs to identify the application.
	ApplicationIdentifier string `json:"application_identifier"`

	// ProducerIdentifier is a reusable identifier that can be used by consumers for routing.
	// This can allow Bot A, Bot B, Bot C to all use the same producer identifier and be handled
	// by the same consumer. The consumer will use the Identifier to determine what token to use.
	ProducerIdentifier string `json:"producer_identifier"`

	// This is the display name of the application. This is included in status APIs.
	DisplayName string `json:"display_name"`

	// This is the client name that is passed to producers.
	ClientName          string `json:"client_name"`
	IncludeRandomSuffix bool   `json:"client_name_uses_random_suffix"`

	BotToken  string `json:"bot_token"`
	AutoStart bool   `json:"auto_start"`

	DefaultPresence    discord.UpdateStatus `json:"default_presence"`
	Intents            int32                `json:"intents"`
	ChunkGuildsOnStart bool                 `json:"chunk_guilds_on_start"`

	// Events that the application should not handle.
	EventBlacklist []string `json:"event_blacklist"`
	// Events that the application should handle, but will not be produced.
	ProduceBlacklist []string `json:"produce_blacklist"`

	AutoSharded bool   `json:"auto_sharded"`
	ShardCount  int32  `json:"shard_count"`
	ShardIDs    string `json:"shard_ids"`

	Values map[string]any `json:"values"`
}

type ApplicationStatus

type ApplicationStatus int32
const (
	ApplicationStatusIdle ApplicationStatus = iota
	ApplicationStatusFailed
	ApplicationStatusStarting
	ApplicationStatusConnecting
	ApplicationStatusConnected
	ApplicationStatusReady
	ApplicationStatusStopping
	ApplicationStatusStopped
)

func (ApplicationStatus) String

func (status ApplicationStatus) String() string

type ApplicationStatusUpdateEvent

type ApplicationStatusUpdateEvent struct {
	Identifier string            `json:"identifier"`
	Status     ApplicationStatus `json:"status"`
}

type BuiltinDispatchProvider

type BuiltinDispatchProvider struct {
	// contains filtered or unexported fields
}

func NewBuiltinDispatchProvider

func NewBuiltinDispatchProvider(allowEventPassthrough bool) *BuiltinDispatchProvider

func (*BuiltinDispatchProvider) Dispatch

func (p *BuiltinDispatchProvider) Dispatch(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, trace *Trace) (DispatchResult, bool, error)

Dispatch dispatches an event to the appropriate handler.

type ConfigProvider

type ConfigProvider interface {
	GetConfig(ctx context.Context) (*Configuration, error)
	SaveConfig(ctx context.Context, config *Configuration) error
}

type ConfigProviderFromPath

type ConfigProviderFromPath struct {
	// contains filtered or unexported fields
}

func NewConfigProviderFromPath

func NewConfigProviderFromPath(path string) ConfigProviderFromPath

func (ConfigProviderFromPath) GetConfig

func (ConfigProviderFromPath) SaveConfig

func (c ConfigProviderFromPath) SaveConfig(_ context.Context, config *Configuration) error

type Configuration

type Configuration struct {
	Sandwich     *DaemonConfiguration        `json:"sandwich"`
	Applications []*ApplicationConfiguration `json:"applications"`
}

type DaemonConfiguration

type DaemonConfiguration struct {
	// This is used to segment automatically sharded applications.
	NodeCount int32 `json:"node_count"`
	NodeID    int32 `json:"node_id"`
}

type DedupeProvider

type DedupeProvider interface {
	Deduplicate(ctx context.Context, key string, ttl time.Duration) bool
	Release(ctx context.Context, key string)
}

DedupeProvider is an interface for deduplication operations. It provides a method to check if a key is already being processed. If the key has been/already being processed, it returns false.

type DispatchHandler

type DispatchHandler func(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, trace *Trace) (result DispatchResult, ok bool, err error)

type DispatchResult

type DispatchResult struct {
	Data  any
	Extra *Extra
}

func OnApplicationCommandCreate

func OnApplicationCommandCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnApplicationCommandDelete

func OnApplicationCommandDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnApplicationCommandUpdate

func OnApplicationCommandUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnChannelCreate

func OnChannelCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnChannelDelete

func OnChannelDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnChannelPinsUpdate

func OnChannelPinsUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnChannelUpdate

func OnChannelUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnEntitlementCreate

func OnEntitlementCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnEntitlementDelete

func OnEntitlementDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnEntitlementUpdate

func OnEntitlementUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildAuditLogEntryCreate

func OnGuildAuditLogEntryCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildBanAdd

func OnGuildBanAdd(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildBanRemove

func OnGuildBanRemove(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildCreate

func OnGuildCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildDelete

func OnGuildDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildEmojisUpdate

func OnGuildEmojisUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildIntegrationsUpdate

func OnGuildIntegrationsUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildJoinRequestDelete

func OnGuildJoinRequestDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildMemberAdd

func OnGuildMemberAdd(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildMemberRemove

func OnGuildMemberRemove(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildMemberUpdate

func OnGuildMemberUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildMembersChunk

func OnGuildMembersChunk(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildRoleCreate

func OnGuildRoleCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildRoleDelete

func OnGuildRoleDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildRoleUpdate

func OnGuildRoleUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildStickersUpdate

func OnGuildStickersUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnGuildUpdate

func OnGuildUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnIntegrationCreate

func OnIntegrationCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnIntegrationDelete

func OnIntegrationDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnIntegrationUpdate

func OnIntegrationUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnInteractionCreate

func OnInteractionCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnInviteCreate

func OnInviteCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnInviteDelete

func OnInviteDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnMessageCreate

func OnMessageCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnMessageDelete

func OnMessageDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnMessageDeleteBulk

func OnMessageDeleteBulk(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnMessageReactionAdd

func OnMessageReactionAdd(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnMessageReactionRemove

func OnMessageReactionRemove(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnMessageReactionRemoveAll

func OnMessageReactionRemoveAll(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnMessageReactionRemoveEmoji

func OnMessageReactionRemoveEmoji(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnMessageUpdate

func OnMessageUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnPresenceUpdate

func OnPresenceUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnReady

func OnReady(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, trace *Trace) (DispatchResult, bool, error)

OnReady handles the READY event. It will go and mark guilds as unavailable and go through any GUILD_CREATE events for the next few seconds.

func OnResumed

func OnResumed(_ context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnStageInstanceCreate

func OnStageInstanceCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnStageInstanceDelete

func OnStageInstanceDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnStageInstanceUpdate

func OnStageInstanceUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnThreadCreate

func OnThreadCreate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnThreadDelete

func OnThreadDelete(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnThreadListSync

func OnThreadListSync(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnThreadMemberUpdate

func OnThreadMemberUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnThreadMembersUpdate

func OnThreadMembersUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnThreadUpdate

func OnThreadUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnTypingStart

func OnTypingStart(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnUserUpdate

func OnUserUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnVoiceServerUpdate

func OnVoiceServerUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnVoiceStateUpdate

func OnVoiceStateUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

func OnWebhookUpdate

func OnWebhookUpdate(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, _ *Trace) (DispatchResult, bool, error)

type EventDispatchProvider

type EventDispatchProvider interface {
	Dispatch(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, trace *Trace) (result DispatchResult, ok bool, err error)
}

type EventProvider

type EventProvider interface {
	Dispatch(ctx context.Context, shard *Shard, event *discord.GatewayPayload, trace *Trace) error
}

type EventProviderWithBlacklist

type EventProviderWithBlacklist struct {
	// contains filtered or unexported fields
}

func NewEventProviderWithBlacklist

func NewEventProviderWithBlacklist(dispatchProvider EventDispatchProvider) *EventProviderWithBlacklist

func (*EventProviderWithBlacklist) Dispatch

func (p *EventProviderWithBlacklist) Dispatch(ctx context.Context, shard *Shard, event *discord.GatewayPayload, trace *Trace) error

type Extra

type Extra map[string]json.RawMessage

func NewExtra

func NewExtra() *Extra

func (*Extra) Set

func (e *Extra) Set(key string, value any) *Extra

type GRPCServer

type GRPCServer struct {
	sandwich_protobuf.UnimplementedSandwichServer
	// contains filtered or unexported fields
}

func (*GRPCServer) CreateApplication

CreateApplication implements the CreateApplication RPC method

func (*GRPCServer) DeleteApplication

DeleteApplication implements the DeleteApplication RPC method

func (*GRPCServer) FetchApplication

FetchApplication implements the FetchApplication RPC method

func (*GRPCServer) FetchGuild

FetchGuild implements the FetchGuild RPC method

func (*GRPCServer) FetchGuildChannel

FetchGuildChannel implements the FetchGuildChannel RPC method

func (*GRPCServer) FetchGuildEmoji

FetchGuildEmoji implements the FetchGuildEmoji RPC method

func (*GRPCServer) FetchGuildMember

FetchGuildMember implements the FetchGuildMember RPC method

func (*GRPCServer) FetchGuildRole

FetchGuildRole implements the FetchGuildRole RPC method

func (*GRPCServer) FetchGuildSticker

FetchGuildSticker implements the FetchGuildSticker RPC method

func (*GRPCServer) FetchGuildVoiceState

FetchGuildVoiceState implements the FetchGuildVoiceState RPC method

func (*GRPCServer) FetchUser

FetchUser implements the FetchUser RPC method

func (*GRPCServer) FetchUserMutualGuilds

FetchUserMutualGuilds implements the FetchUserMutualGuilds RPC method

func (*GRPCServer) Listen

Listen implements the Listen RPC method

func (*GRPCServer) RelayMessage

RelayMessage implements the RelayMessage RPC method

func (*GRPCServer) ReloadConfiguration

func (grpcServer *GRPCServer) ReloadConfiguration(ctx context.Context, req *emptypb.Empty) (*sandwich_protobuf.BaseResponse, error)

ReloadConfiguration implements the ReloadConfiguration RPC method

func (*GRPCServer) RequestGuildChunk

RequestGuildChunk implements the RequestGuildChunk RPC method

func (*GRPCServer) SendWebsocketMessage

SendWebsocketMessage implements the SendWebsocketMessage RPC method

func (*GRPCServer) StartApplication

StartApplication implements the StartApplication RPC method

func (*GRPCServer) StopApplication

StopApplication implements the StopApplication RPC method

func (*GRPCServer) WhereIsGuild

WhereIsGuild implements the WhereIsGuild RPC method

type GatewayHandler

type GatewayHandler func(ctx context.Context, shard *Shard, msg *discord.GatewayPayload, trace *Trace) error

type GuildChunk

type GuildChunk struct {
	// contains filtered or unexported fields
}

type GuildChunkPartial

type GuildChunkPartial struct {
	// contains filtered or unexported fields
}

type IdentifyProvider

type IdentifyProvider interface {
	Identify(ctx context.Context, shard *Shard) error
}

type IdentifyViaBuckets

type IdentifyViaBuckets struct {
	// contains filtered or unexported fields
}

IdentifyViaBuckets is a bare minimum identify provider that uses buckets to identify shards. This will work for most use cases, but it's not the most efficient way to identify shards when dealing with multiple processes.

func NewIdentifyViaBuckets

func NewIdentifyViaBuckets() *IdentifyViaBuckets

func (*IdentifyViaBuckets) Identify

func (i *IdentifyViaBuckets) Identify(_ context.Context, shard *Shard) error

type IdentifyViaURL

type IdentifyViaURL struct {
	URL     string
	Headers map[string]string
}

This will expect a 200 or 204 response. If the response is a 402, it will retry based on the header `X-Retry-After-Ms` or 5000 milliseconds. If the response is anything else, it will return an error.

func NewIdentifyViaURL

func NewIdentifyViaURL(url string, headers map[string]string) *IdentifyViaURL

func (*IdentifyViaURL) Identify

func (i *IdentifyViaURL) Identify(ctx context.Context, shard *Shard) error

type PanicHandler

type PanicHandler func(sandwich *Sandwich, r any)

type ProducedMetadata

type ProducedMetadata struct {
	Identifier    string            `json:"i"`
	Application   string            `json:"a"`
	ApplicationID discord.Snowflake `json:"id"`
	Shard         [3]int32          `json:"s"`
}

type ProducedPayload

type ProducedPayload struct {
	discord.GatewayPayload

	Extra    map[string]json.RawMessage `json:"__extra,omitempty"`
	Metadata ProducedMetadata           `json:"__metadata"`
	Trace    Trace                      `json:"__trace,omitempty"`
}

type Producer

type Producer interface {
	Publish(ctx context.Context, shard *Shard, payload *ProducedPayload) error
	Close() error
}

type ProducerProvider

type ProducerProvider interface {
	GetProducer(ctx context.Context, applicationIdentifier, clientName string) (Producer, error)
}

type Sandwich

type Sandwich struct {
	Logger *slog.Logger

	Config *atomic.Pointer[Configuration]

	Client *http.Client

	Applications *syncmap.Map[string, *Application]
	// contains filtered or unexported fields
}

func NewSandwich

func NewSandwich(logger *slog.Logger, configProvider ConfigProvider, client *http.Client, eventProvider EventProvider, identifyProvider IdentifyProvider, producerProvider ProducerProvider, stateProvider StateProvider, dedupeProvider DedupeProvider) *Sandwich

func (*Sandwich) AddApplication

func (sandwich *Sandwich) AddApplication(ctx context.Context, applicationConfig *ApplicationConfiguration) (*Application, error)

func (*Sandwich) AddListener

func (sandwich *Sandwich) AddListener(listener chan *listenerData) int32

func (*Sandwich) Broadcast

func (sandwich *Sandwich) Broadcast(eventType string, data any) error

func (*Sandwich) NewGRPCServer

func (sandwich *Sandwich) NewGRPCServer() *GRPCServer

func (*Sandwich) RemoveListener

func (sandwich *Sandwich) RemoveListener(counter int32)

func (*Sandwich) Start

func (sandwich *Sandwich) Start(ctx context.Context) error

func (*Sandwich) Stop

func (sandwich *Sandwich) Stop(ctx context.Context)

func (*Sandwich) WithGRPCServer

func (sandwich *Sandwich) WithGRPCServer(listenerConfig *net.ListenConfig, network, address string, server *grpc.Server) *Sandwich

func (*Sandwich) WithPanicHandler

func (sandwich *Sandwich) WithPanicHandler(panicHandler PanicHandler) *Sandwich

func (*Sandwich) WithPrometheusAnalytics

func (sandwich *Sandwich) WithPrometheusAnalytics(
	server *http.Server,
	registry *prometheus.Registry,
	opts promhttp.HandlerOpts,
) *Sandwich

type Shard

type Shard struct {
	Logger *slog.Logger

	Sandwich    *Sandwich
	Application *Application

	ShardID int32

	StartedAt     *atomic.Pointer[time.Time]
	InitializedAt *atomic.Pointer[time.Time]

	HeartbeatActive   *atomic.Bool
	LastHeartbeatAck  *atomic.Pointer[time.Time]
	LastHeartbeatSent *atomic.Pointer[time.Time]
	GatewayLatency    *atomic.Int64

	UnavailableGuilds *syncmap.Map[discord.Snowflake, bool]
	LazyGuilds        *syncmap.Map[discord.Snowflake, bool]
	Guilds            *syncmap.Map[discord.Snowflake, bool]

	Status *atomic.Int32

	Metadata *atomic.Pointer[ProducedMetadata]
	// contains filtered or unexported fields
}

func NewShard

func NewShard(sandwich *Sandwich, application *Application, shardID int32) *Shard

func (*Shard) Connect

func (shard *Shard) Connect(ctx context.Context) error

func (*Shard) ConnectWithRetry

func (shard *Shard) ConnectWithRetry(ctx context.Context) error

func (*Shard) Listen

func (shard *Shard) Listen(ctx context.Context) error

func (*Shard) OnDispatch

func (shard *Shard) OnDispatch(ctx context.Context, msg *discord.GatewayPayload, trace *Trace) error

func (*Shard) OnEvent

func (shard *Shard) OnEvent(ctx context.Context, msg *discord.GatewayPayload, trace *Trace) error

func (*Shard) SendEvent

func (shard *Shard) SendEvent(ctx context.Context, gatewayOp discord.GatewayOp, data any) error

func (*Shard) SetMetadata

func (shard *Shard) SetMetadata(configuration *ApplicationConfiguration)

func (*Shard) SetStatus

func (shard *Shard) SetStatus(status ShardStatus)

func (*Shard) Start

func (shard *Shard) Start(ctx context.Context) error

func (*Shard) Stop

func (shard *Shard) Stop(ctx context.Context, code websocket.StatusCode)

func (*Shard) WaitForReady

func (shard *Shard) WaitForReady() error

type ShardStatus

type ShardStatus int32
const (
	ShardStatusIdle ShardStatus = iota
	ShardStatusFailed
	ShardStatusConnecting
	ShardStatusConnected
	ShardStatusReady
	ShardStatusStopping
	ShardStatusStopped
)

func (ShardStatus) String

func (status ShardStatus) String() string

type ShardStatusUpdateEvent

type ShardStatusUpdateEvent struct {
	Identifier string      `json:"identifier"`
	ShardID    int32       `json:"shard_id"`
	Status     ShardStatus `json:"status"`
}

type StateChannel

type StateChannel struct {
	ID                         discord.Snowflake          `json:"id"`
	GuildID                    *discord.Snowflake         `json:"guild_id"`
	OwnerID                    *discord.Snowflake         `json:"owner_id"`
	ApplicationID              *discord.Snowflake         `json:"application_id"`
	ParentID                   *discord.Snowflake         `json:"parent_id"`
	LastPinTimestamp           *time.Time                 `json:"last_pin_timestamp"`
	Permissions                *discord.Int64             `json:"permissions"`
	ThreadMetadata             *discord.ThreadMetadata    `json:"thread_metadata"`
	ThreadMember               *discord.ThreadMember      `json:"member"`
	VideoQualityMode           *discord.VideoQualityMode  `json:"video_quality_mode"`
	PermissionOverwrites       []discord.ChannelOverwrite `json:"permission_overwrites"`
	Recipients                 []discord.Snowflake        `json:"recipients"`
	Type                       discord.ChannelType        `json:"type"`
	Position                   int32                      `json:"position"`
	Bitrate                    int32                      `json:"bitrate"`
	UserLimit                  int32                      `json:"user_limit"`
	RateLimitPerUser           int32                      `json:"rate_limit_per_user"`
	MessageCount               int32                      `json:"message_count"`
	MemberCount                int32                      `json:"member_count"`
	DefaultAutoArchiveDuration int32                      `json:"default_auto_archive_duration"`
	NSFW                       bool                       `json:"nsfw"`
	Name                       string                     `json:"name"`
	Topic                      string                     `json:"topic"`
	LastMessageID              string                     `json:"last_message_id"`
	Icon                       string                     `json:"icon"`
	RTCRegion                  string                     `json:"rtc_region"`
}

func DiscordToStateChannel

func DiscordToStateChannel(v discord.Channel) StateChannel

type StateEmoji

type StateEmoji struct {
	ID            discord.Snowflake   `json:"id"`
	UserID        discord.Snowflake   `json:"user"`
	Name          string              `json:"name"`
	Roles         []discord.Snowflake `json:"roles"`
	RequireColons bool                `json:"require_colons"`
	Managed       bool                `json:"managed"`
	Animated      bool                `json:"animated"`
	Available     bool                `json:"available"`
}

func DiscordToStateEmoji

func DiscordToStateEmoji(v discord.Emoji) StateEmoji

type StateGuild

type StateGuild struct {
	ID              discord.Snowflake `json:"id"`
	Name            string            `json:"name"`
	Icon            string            `json:"icon"`
	IconHash        string            `json:"icon_hash"`
	Splash          string            `json:"splash"`
	DiscoverySplash string            `json:"discovery_splash"`

	Owner       bool               `json:"owner"`
	OwnerID     *discord.Snowflake `json:"owner_id"`
	Permissions *discord.Int64     `json:"permissions"`
	Region      string             `json:"region"`

	AFKChannelID *discord.Snowflake `json:"afk_channel_id"`
	AFKTimeout   int32              `json:"afk_timeout"`

	WidgetEnabled   bool               `json:"widget_enabled"`
	WidgetChannelID *discord.Snowflake `json:"widget_channel_id"`

	VerificationLevel           discord.VerificationLevel          `json:"verification_level"`
	DefaultMessageNotifications discord.MessageNotificationLevel   `json:"default_message_notifications"`
	ExplicitContentFilter       discord.ExplicitContentFilterLevel `json:"explicit_content_filter"`

	MFALevel           discord.MFALevel            `json:"mfa_level"`
	ApplicationID      *discord.Snowflake          `json:"application_id"`
	SystemChannelID    *discord.Snowflake          `json:"system_channel_id"`
	SystemChannelFlags *discord.SystemChannelFlags `json:"system_channel_flags"`
	RulesChannelID     *discord.Snowflake          `json:"rules_channel_id"`

	JoinedAt    time.Time `json:"joined_at"`
	Large       bool      `json:"large"`
	Unavailable bool      `json:"unavailable"`
	MemberCount int32     `json:"member_count"`

	MaxPresences  int32  `json:"max_presences"`
	MaxMembers    int32  `json:"max_members"`
	VanityURLCode string `json:"vanity_url_code"`
	Description   string `json:"description"`
	Banner        string `json:"banner"`

	PremiumTier               *discord.PremiumTier       `json:"premium_tier"`
	PremiumSubscriptionCount  int32                      `json:"premium_subscription_count"`
	PreferredLocale           string                     `json:"preferred_locale"`
	PublicUpdatesChannelID    *discord.Snowflake         `json:"public_updates_channel_id"`
	MaxVideoChannelUsers      int32                      `json:"max_video_channel_users"`
	ApproximateMemberCount    int32                      `json:"approximate_member_count"`
	ApproximatePresenceCount  int32                      `json:"approximate_presence_count"`
	NSFWLevel                 discord.GuildNSFWLevelType `json:"nsfw_level"`
	PremiumProgressBarEnabled bool                       `json:"premium_progress_bar_enabled"`

	Features             []string                 `json:"features"`
	StageInstances       []discord.StageInstance  `json:"stage_instances"`
	GuildScheduledEvents []discord.ScheduledEvent `json:"guild_scheduled_events"`
}

func DiscordToStateGuild

func DiscordToStateGuild(guild discord.Guild) StateGuild

type StateGuildMember

type StateGuildMember struct {
	UserID                     discord.Snowflake   `json:"user_id"`
	Permissions                *discord.Int64      `json:"permissions"`
	JoinedAt                   time.Time           `json:"joined_at"`
	Roles                      []discord.Snowflake `json:"roles"`
	Nick                       string              `json:"nick"`
	Avatar                     string              `json:"avatar"`
	PremiumSince               *time.Time          `json:"premium_since"`
	CommunicationDisabledUntil *time.Time          `json:"communication_disabled_until"`
	Deaf                       bool                `json:"deaf"`
	Mute                       bool                `json:"mute"`
	Pending                    bool                `json:"pending"`
}

func DiscordToStateGuildMember

func DiscordToStateGuildMember(v discord.GuildMember) StateGuildMember

type StateProvider

type StateProvider interface {
	// Guilds
	GetGuilds(ctx context.Context) ([]*discord.Guild, bool)

	GetGuild(ctx context.Context, guildID discord.Snowflake) (*discord.Guild, bool)
	SetGuild(ctx context.Context, guildID discord.Snowflake, guild discord.Guild)

	// Guild Members
	GetGuildMembers(ctx context.Context, guildID discord.Snowflake) ([]*discord.GuildMember, bool)

	GetGuildMember(ctx context.Context, guildID, userID discord.Snowflake) (*discord.GuildMember, bool)
	SetGuildMember(ctx context.Context, guildID discord.Snowflake, member discord.GuildMember)
	RemoveGuildMember(ctx context.Context, guildID, userID discord.Snowflake)

	// Channels
	GetGuildChannels(ctx context.Context, guildID discord.Snowflake) ([]*discord.Channel, bool)
	SetGuildChannels(ctx context.Context, guildID discord.Snowflake, channels []discord.Channel)

	GetGuildChannel(ctx context.Context, guildID, channelID discord.Snowflake) (*discord.Channel, bool)
	SetGuildChannel(ctx context.Context, guildID discord.Snowflake, channel discord.Channel)
	RemoveGuildChannel(ctx context.Context, guildID, channelID discord.Snowflake)

	// Roles
	GetGuildRoles(ctx context.Context, guildID discord.Snowflake) ([]*discord.Role, bool)
	SetGuildRoles(ctx context.Context, guildID discord.Snowflake, roles []discord.Role)

	GetGuildRole(ctx context.Context, guildID, roleID discord.Snowflake) (*discord.Role, bool)
	SetGuildRole(ctx context.Context, guildID discord.Snowflake, role discord.Role)
	RemoveGuildRole(ctx context.Context, guildID, roleID discord.Snowflake)

	// Emojis
	GetGuildEmojis(ctx context.Context, guildID discord.Snowflake) ([]*discord.Emoji, bool)
	SetGuildEmojis(ctx context.Context, guildID discord.Snowflake, emojis []discord.Emoji)

	GetGuildEmoji(ctx context.Context, guildID, emojiID discord.Snowflake) (*discord.Emoji, bool)
	SetGuildEmoji(ctx context.Context, guildID discord.Snowflake, emoji discord.Emoji)
	RemoveGuildEmoji(ctx context.Context, guildID, emojiID discord.Snowflake)

	// Stickers
	GetGuildStickers(ctx context.Context, guildID discord.Snowflake) ([]*discord.Sticker, bool)
	SetGuildStickers(ctx context.Context, guildID discord.Snowflake, stickers []discord.Sticker)

	GetGuildSticker(ctx context.Context, guildID, stickerID discord.Snowflake) (*discord.Sticker, bool)
	SetGuildSticker(ctx context.Context, guildID discord.Snowflake, sticker discord.Sticker)
	RemoveGuildSticker(ctx context.Context, guildID, stickerID discord.Snowflake)

	// Voice States
	GetVoiceStates(ctx context.Context, guildID discord.Snowflake) ([]*discord.VoiceState, bool)

	GetVoiceState(ctx context.Context, guildID, userID discord.Snowflake) (*discord.VoiceState, bool)
	SetVoiceState(ctx context.Context, guildID discord.Snowflake, voiceState discord.VoiceState)
	RemoveVoiceState(ctx context.Context, guildID, userID discord.Snowflake)

	// Users
	GetUser(ctx context.Context, userID discord.Snowflake) (*discord.User, bool)
	SetUser(ctx context.Context, userID discord.Snowflake, user discord.User)

	// User Mutuals
	GetUserMutualGuilds(ctx context.Context, userID discord.Snowflake) ([]discord.Snowflake, bool)
	AddUserMutualGuild(ctx context.Context, userID, guildID discord.Snowflake)
	RemoveUserMutualGuild(ctx context.Context, userID, guildID discord.Snowflake)
}

type StateProviderMemoryOptimized

func NewStateProviderMemoryOptimized

func NewStateProviderMemoryOptimized() *StateProviderMemoryOptimized

func NewStateProviderMemoryOptimizedWithContext

func NewStateProviderMemoryOptimizedWithContext(ctx context.Context) *StateProviderMemoryOptimized

func (*StateProviderMemoryOptimized) AddUserMutualGuild

func (s *StateProviderMemoryOptimized) AddUserMutualGuild(_ context.Context, userID, guildID discord.Snowflake)

func (*StateProviderMemoryOptimized) GetGuild

func (*StateProviderMemoryOptimized) GetGuildChannel

func (s *StateProviderMemoryOptimized) GetGuildChannel(_ context.Context, guildID, channelID discord.Snowflake) (*discord.Channel, bool)

func (*StateProviderMemoryOptimized) GetGuildChannels

func (s *StateProviderMemoryOptimized) GetGuildChannels(_ context.Context, guildID discord.Snowflake) ([]*discord.Channel, bool)

func (*StateProviderMemoryOptimized) GetGuildEmoji

func (s *StateProviderMemoryOptimized) GetGuildEmoji(_ context.Context, guildID, emojiID discord.Snowflake) (*discord.Emoji, bool)

func (*StateProviderMemoryOptimized) GetGuildEmojis

func (s *StateProviderMemoryOptimized) GetGuildEmojis(_ context.Context, guildID discord.Snowflake) ([]*discord.Emoji, bool)

func (*StateProviderMemoryOptimized) GetGuildMember

func (s *StateProviderMemoryOptimized) GetGuildMember(_ context.Context, guildID, userID discord.Snowflake) (*discord.GuildMember, bool)

func (*StateProviderMemoryOptimized) GetGuildMembers

func (*StateProviderMemoryOptimized) GetGuildRole

func (s *StateProviderMemoryOptimized) GetGuildRole(_ context.Context, guildID, roleID discord.Snowflake) (*discord.Role, bool)

func (*StateProviderMemoryOptimized) GetGuildRoles

func (s *StateProviderMemoryOptimized) GetGuildRoles(_ context.Context, guildID discord.Snowflake) ([]*discord.Role, bool)

func (*StateProviderMemoryOptimized) GetGuildSticker

func (s *StateProviderMemoryOptimized) GetGuildSticker(_ context.Context, guildID, stickerID discord.Snowflake) (*discord.Sticker, bool)

func (*StateProviderMemoryOptimized) GetGuildStickers

func (s *StateProviderMemoryOptimized) GetGuildStickers(_ context.Context, guildID discord.Snowflake) ([]*discord.Sticker, bool)

func (*StateProviderMemoryOptimized) GetGuilds

func (*StateProviderMemoryOptimized) GetUser

func (*StateProviderMemoryOptimized) GetUserMutualGuilds

func (s *StateProviderMemoryOptimized) GetUserMutualGuilds(_ context.Context, userID discord.Snowflake) ([]discord.Snowflake, bool)

func (*StateProviderMemoryOptimized) GetVoiceState

func (s *StateProviderMemoryOptimized) GetVoiceState(_ context.Context, guildID, userID discord.Snowflake) (*discord.VoiceState, bool)

func (*StateProviderMemoryOptimized) GetVoiceStates

func (*StateProviderMemoryOptimized) RemoveGuildChannel

func (s *StateProviderMemoryOptimized) RemoveGuildChannel(_ context.Context, guildID, channelID discord.Snowflake)

func (*StateProviderMemoryOptimized) RemoveGuildEmoji

func (s *StateProviderMemoryOptimized) RemoveGuildEmoji(_ context.Context, guildID, emojiID discord.Snowflake)

func (*StateProviderMemoryOptimized) RemoveGuildMember

func (s *StateProviderMemoryOptimized) RemoveGuildMember(_ context.Context, guildID, userID discord.Snowflake)

func (*StateProviderMemoryOptimized) RemoveGuildRole

func (s *StateProviderMemoryOptimized) RemoveGuildRole(_ context.Context, guildID, roleID discord.Snowflake)

func (*StateProviderMemoryOptimized) RemoveGuildSticker

func (s *StateProviderMemoryOptimized) RemoveGuildSticker(_ context.Context, guildID, stickerID discord.Snowflake)

func (*StateProviderMemoryOptimized) RemoveUserMutualGuild

func (s *StateProviderMemoryOptimized) RemoveUserMutualGuild(_ context.Context, userID, guildID discord.Snowflake)

func (*StateProviderMemoryOptimized) RemoveVoiceState

func (s *StateProviderMemoryOptimized) RemoveVoiceState(_ context.Context, guildID, userID discord.Snowflake)

func (*StateProviderMemoryOptimized) SetGuild

func (s *StateProviderMemoryOptimized) SetGuild(ctx context.Context, guildID discord.Snowflake, guild discord.Guild)

func (*StateProviderMemoryOptimized) SetGuildChannel

func (s *StateProviderMemoryOptimized) SetGuildChannel(_ context.Context, guildID discord.Snowflake, channel discord.Channel)

func (*StateProviderMemoryOptimized) SetGuildChannels

func (s *StateProviderMemoryOptimized) SetGuildChannels(_ context.Context, guildID discord.Snowflake, channels []discord.Channel)

func (*StateProviderMemoryOptimized) SetGuildEmoji

func (s *StateProviderMemoryOptimized) SetGuildEmoji(_ context.Context, guildID discord.Snowflake, emoji discord.Emoji)

func (*StateProviderMemoryOptimized) SetGuildEmojis

func (s *StateProviderMemoryOptimized) SetGuildEmojis(_ context.Context, guildID discord.Snowflake, emojis []discord.Emoji)

func (*StateProviderMemoryOptimized) SetGuildMember

func (s *StateProviderMemoryOptimized) SetGuildMember(ctx context.Context, guildID discord.Snowflake, member discord.GuildMember)

func (*StateProviderMemoryOptimized) SetGuildMembers

func (s *StateProviderMemoryOptimized) SetGuildMembers(ctx context.Context, guildID discord.Snowflake, guildMembers []discord.GuildMember)

func (*StateProviderMemoryOptimized) SetGuildRole

func (s *StateProviderMemoryOptimized) SetGuildRole(_ context.Context, guildID discord.Snowflake, role discord.Role)

func (*StateProviderMemoryOptimized) SetGuildRoles

func (s *StateProviderMemoryOptimized) SetGuildRoles(_ context.Context, guildID discord.Snowflake, roles []discord.Role)

func (*StateProviderMemoryOptimized) SetGuildSticker

func (s *StateProviderMemoryOptimized) SetGuildSticker(_ context.Context, guildID discord.Snowflake, sticker discord.Sticker)

func (*StateProviderMemoryOptimized) SetGuildStickers

func (s *StateProviderMemoryOptimized) SetGuildStickers(_ context.Context, guildID discord.Snowflake, stickers []discord.Sticker)

func (*StateProviderMemoryOptimized) SetUser

func (*StateProviderMemoryOptimized) SetVoiceState

func (s *StateProviderMemoryOptimized) SetVoiceState(_ context.Context, guildID discord.Snowflake, voiceState discord.VoiceState)

func (*StateProviderMemoryOptimized) UpdateStateMetricsFromStateProvider

func (s *StateProviderMemoryOptimized) UpdateStateMetricsFromStateProvider()

type StateRole

type StateRole struct {
	ID           discord.Snowflake `json:"id"`
	Permissions  discord.Int64     `json:"permissions"`
	Position     int32             `json:"position"`
	Color        int32             `json:"color"`
	Name         string            `json:"name"`
	Icon         string            `json:"icon"`
	UnicodeEmoji string            `json:"unicode_emoji"`
	Tags         *discord.RoleTag  `json:"tags"`
	Hoist        bool              `json:"hoist"`
	Managed      bool              `json:"managed"`
	Mentionable  bool              `json:"mentionable"`
}

func DiscordToStateRole

func DiscordToStateRole(v discord.Role) StateRole

type StateSticker

type StateSticker struct {
	ID          discord.Snowflake         `json:"id"`
	PackID      discord.Snowflake         `json:"pack_id"`
	GuildID     discord.Snowflake         `json:"guild_id"`
	UserID      discord.Snowflake         `json:"user"`
	Name        string                    `json:"name"`
	Description string                    `json:"description"`
	Tags        string                    `json:"tags"`
	Type        discord.StickerType       `json:"type"`
	FormatType  discord.StickerFormatType `json:"format_type"`
	SortValue   int32                     `json:"sort_value"`
	Available   bool                      `json:"available"`
}

func DiscordToStateSticker

func DiscordToStateSticker(v discord.Sticker) StateSticker

type StateUser

type StateUser struct {
	ID            discord.Snowflake       `json:"id"`
	DMChannelID   *discord.Snowflake      `json:"dm_channel_id"`
	AccentColor   int32                   `json:"accent_color"`
	Flags         discord.UserFlags       `json:"flags"`
	PublicFlags   discord.UserFlags       `json:"public_flags"`
	PremiumType   discord.UserPremiumType `json:"premium_type"`
	Username      string                  `json:"username"`
	Discriminator string                  `json:"discriminator"`
	GlobalName    string                  `json:"global_name"`
	Avatar        string                  `json:"avatar"`
	Banner        string                  `json:"banner"`
	Locale        string                  `json:"locale"`
	Email         string                  `json:"email"`
	Bot           bool                    `json:"bot"`
	System        bool                    `json:"system"`
	MFAEnabled    bool                    `json:"mfa_enabled"`
	Verified      bool                    `json:"verified"`
}

func DiscordToStateUser

func DiscordToStateUser(v discord.User) StateUser

type StateVoiceState

type StateVoiceState struct {
	RequestToSpeakTimestamp time.Time         `json:"request_to_speak_timestamp"`
	ChannelID               discord.Snowflake `json:"channel_id"`
	GuildID                 discord.Snowflake `json:"guild_id"`
	UserID                  discord.Snowflake `json:"user_id"`
	SessionID               string            `json:"session_id"`
	Deaf                    bool              `json:"deaf"`
	Mute                    bool              `json:"mute"`
	SelfDeaf                bool              `json:"self_deaf"`
	SelfMute                bool              `json:"self_mute"`
	SelfStream              bool              `json:"self_stream"`
	SelfVideo               bool              `json:"self_video"`
	Suppress                bool              `json:"suppress"`
}

func DiscordToStateVoiceState

func DiscordToStateVoiceState(v discord.VoiceState) StateVoiceState

type Trace

type Trace map[string]any

func NewTrace

func NewTrace() *Trace

func (*Trace) Set

func (t *Trace) Set(key string, value any) *Trace

Directories

Path Synopsis
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL