go_discord_wrapper

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jun 6, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

README

go-discord-wrapper

CI Coverage Version Go Reference Go Report Card

A Go library for the Discord gateway and REST API.

Features

  • Gateway (WebSocket) client with automatic reconnection and resume
  • Near-complete REST API coverage for guilds, channels, messages, roles, interactions, webhooks, and more (~224 endpoints; see known gaps)
  • Proactive rate limiter — respects per-route and global Discord rate limits before sending
  • In-process memory cache (guild, channel, member, message, role, voice state, emoji, sticker, …) with TTL and LRU eviction
  • Pluggable cache backends (Redis and MongoDB drivers included)
  • Synthetic emoji and sticker events derived from raw gateway payloads
  • Slash command and interaction support (reply, defer, modal, component)
  • Horizontal sharding with a built-in shard coordinator
  • Middleware support for event handlers

Also see Features in the documentation: docs/README.md.

Project status & v1.0 scope

v1.0 — first stable release. The public API is frozen and follows semantic versioning: no breaking changes within the v1 line. That said, this is a young library — expect to hit bugs in less-travelled corners. Please open an issue when you do; reports against v1.0 are very welcome.

How this library was built

The original foundation of this library was written by hand. Most of the surface area beyond that — the breadth of REST endpoints, event handling, and supporting code — was built with substantial AI assistance and has not yet been reviewed line-by-line by a human. Correctness is instead guarded by an extensive automated test suite (see COVERAGE.md); the tests, not a manual read-through, are the primary correctness guarantee today. We're being upfront about this so you can weigh it for your use case. Human review is ongoing, and — as above — bug reports are the fastest way to harden the library.

Installation

go get github.com/streame-gg/go-discord-wrapper

Requires Go 1.26 or later.

Quick start

package main

import (
    "context"
    "log/slog"
    "os"
    "os/signal"
    "syscall"

    "github.com/streame-gg/go-discord-wrapper/connection"
    "github.com/streame-gg/go-discord-wrapper/types/discord"
    "github.com/streame-gg/go-discord-wrapper/types/events"
    "github.com/streame-gg/go-discord-wrapper/types/interactions/responses"
)

func main() {
    bot, err := connection.NewClient(os.Getenv("DISCORD_TOKEN"), discord.IntentGuilds|discord.IntentGuildMessages)
    if err != nil {
        slog.Error("failed to create client", "err", err)
        os.Exit(1)
    }

    bot.OnMessageCreate(func(c *connection.Client, e *events.MessageCreateEvent) {
        if e.Author == nil {
            return
        }
        slog.Info("new message", "author", e.Author.Username, "content", e.Content)
    })

    bot.OnEvent(events.EventInteractionCreate, func(c *connection.Client, e *events.InteractionCreateEvent) {
        if e.IsCommand() && e.GetFullCommand() == "ping" {
            _, _ = c.Reply(context.Background(), &e.Interaction, &responses.InteractionResponseDataDefault{
                Content: "Pong!",
            }, false)
        }
    })

    if err := bot.Login(context.Background()); err != nil {
        slog.Error("login failed", "err", err)
        os.Exit(1)
    }

    ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
    defer stop()
    <-ctx.Done()

    _ = bot.Shutdown()
}

Working with Collections

Most cache and listing operations return a *collection.Collection[K, V] — a map with insertion order, plus 30+ utility methods inspired by @discordjs/collection.

Basic operations
import "github.com/streame-gg/go-discord-wrapper/collection"

users := bot.Cache.Users().All()  // returns *Collection[Snowflake, *User]

count := users.Len()
admin, ok := users.Get(adminID)
humanCount := users.Filter(func(u *discord.User) bool { return !u.Bot }).Len()
Search and partition
bots, humans := users.Partition(func(u *discord.User) bool { return u.Bot })
recent := messages.Filter(func(m *discord.Message) bool {
    return time.Since(m.Created()) < time.Hour
})

oldest, _ := messages.Sorted(func(a, b *discord.Message) bool {
    return a.Created().Before(b.Created())
}).First()
Transform
// Method-based: returns a new Collection
sorted := users.Sorted(func(a, b *discord.User) bool {
    return a.Username < b.Username
})

// Top-level: transforms to a different value-type
names := collection.Map(users, func(u *discord.User) string {
    return u.Username
})
// names is []string

// Iterate (Go 1.23+ range-over-func)
for id, user := range users.All() {
    fmt.Printf("%s -> %s\n", id, user.Username)
}

Full API: see godoc.

Cache

Pass a cache to NewClient and the gateway will populate it automatically:

import "github.com/streame-gg/go-discord-wrapper/cache"

mc := cache.NewMemoryCache(cache.Options{
    TTL:           30 * time.Minute,
    SweepInterval: 5 * time.Minute,
    Limits: cache.Limits{
        MaxMessages: 10_000,
        MaxUsers:    5_000,
    },
    Messages: cache.MessageOptions{
        MaxPerChannel: 200,
    },
})

bot, err := connection.NewClient(token, intents, options.WithCache(mc))

Look up entities without hitting the REST API:

if ch, ok := bot.Cache.Channels().Get(channelID); ok {
    fmt.Println(ch.Name)
}
Cache backends
Backend Import
In-process memory (default) cache.NewMemoryCache(...)
Redis cache/rediscache package
MongoDB cache/mongocache package

Sharding

// Shard 0 of 4 total shards.
bot, err := connection.NewClient(token, intents, options.WithSharding(4, 0))

Slash commands

_, err := bot.BulkRegisterCommands(ctx, []*commands.ApplicationCommand{
    {
        Name:        "ping",
        Description: "Replies with Pong!",
        Type:        discord.ApplicationCommandTypeChatInput,
    },
})

Configuration reference

Option Description
options.WithCache(c) Attach a cache backend
options.WithSharding(total, shardID) Enable sharding
options.WithLogger(l) Custom *slog.Logger
options.WithRetry(opts) Retry policy for REST requests
options.WithRateLimiting(opts) Rate-limiter tuning (safety margin, disable)
options.WithMinRequestInterval(d) Global minimum delay between REST requests
options.WithAPIVersion(v) Discord API version (default: v10)
options.WithBaseURL(url) Override the Discord API base URL (useful for mock servers in tests)

Testing with a mock server

Use WithBaseURL together with Go's net/http/httptest to run integration tests without hitting Discord:

import (
    "net/http/httptest"
    "github.com/streame-gg/go-discord-wrapper/api"
    "github.com/streame-gg/go-discord-wrapper/options"
)

ts := httptest.NewServer(myHandler)
defer ts.Close()

client, err := api.NewRestClient("test-token",
    options.WithBaseURL(ts.URL),
)

Synthetic events

Synthetic events are high-level events derived by the wrapper from raw Discord gateway events. They are never sent by Discord directly — the library computes them by diffing state across consecutive gateway payloads.

Synthetic events require the cache to be enabled (via options.WithCache). When the cache is cold (no prior state), the event is silently skipped rather than firing with incomplete data.

mc := cache.NewMemoryCache(cache.Options{})
bot, err := connection.NewClient(token, intents, options.WithCache(mc))

// Fires once per emoji added to a guild.
bot.OnGuildEmojiAdd(func(c *connection.Client, ev *events.GuildEmojiAddEvent) {
    fmt.Printf("emoji %s added to guild %s\n", ev.Emoji.Name, ev.GuildID)
})

// Fires once per sticker removed from a guild.
bot.OnGuildStickerRemove(func(c *connection.Client, ev *events.GuildStickerRemoveEvent) {
    fmt.Printf("sticker %s removed from guild %s\n", ev.Sticker.Name, ev.GuildID)
})
Emoji events (source: GUILD_EMOJIS_UPDATE, cache required)
Helper Struct Fires when
OnGuildEmojiAdd GuildEmojiAddEvent An emoji is created in a guild
OnGuildEmojiRemove GuildEmojiRemoveEvent An emoji is deleted from a guild
OnGuildEmojiUpdate GuildEmojiUpdateEvent An emoji's name, roles, or availability changes
Sticker events (source: GUILD_STICKERS_UPDATE, cache required)
Helper Struct Fires when
OnGuildStickerAdd GuildStickerAddEvent A sticker is created in a guild
OnGuildStickerRemove GuildStickerRemoveEvent A sticker is deleted from a guild
OnGuildStickerUpdate GuildStickerUpdateEvent A sticker's name, tags, or availability changes

Supported gateway events

Event Constant
Ready events.EventReady
Resumed events.EventResumed
Application Command Permissions Update events.EventApplicationCommandPermissionsUpdate
Auto Moderation Rule Create events.EventAutoModerationRuleCreate
Auto Moderation Rule Update events.EventAutoModerationRuleUpdate
Auto Moderation Rule Delete events.EventAutoModerationRuleDelete
Auto Moderation Action Execution events.EventAutoModerationActionExecution
Channel Create events.EventChannelCreate
Channel Update events.EventChannelUpdate
Channel Delete events.EventChannelDelete
Channel Pins Update events.EventChannelPinsUpdate
Thread Create events.EventThreadCreate
Thread Update events.EventThreadUpdate
Thread Delete events.EventThreadDelete
Thread List Sync events.EventThreadListSync
Thread Member Update events.EventThreadMemberUpdate
Thread Members Update events.EventThreadMembersUpdate
Entitlement Create events.EventEntitlementCreate
Entitlement Update events.EventEntitlementUpdate
Entitlement Delete events.EventEntitlementDelete
Guild Create events.EventGuildCreate
Guild Update events.EventGuildUpdate
Guild Delete events.EventGuildDelete
Guild Audit Log Entry Create events.EventGuildAuditLogEntryCreate
Guild Ban Add events.EventGuildBanAdd
Guild Ban Remove events.EventGuildBanRemove
Guild Emojis Update events.EventGuildEmojisUpdate
Guild Stickers Update events.EventGuildStickersUpdate
Guild Integrations Update events.EventGuildIntegrationsUpdate
Guild Member Add events.EventGuildMemberAdd
Guild Member Update events.EventGuildMemberUpdate
Guild Member Remove events.EventGuildMemberRemove
Guild Members Chunk events.EventGuildMembersChunk
Guild Role Create events.EventGuildRoleCreate
Guild Role Update events.EventGuildRoleUpdate
Guild Role Delete events.EventGuildRoleDelete
Guild Scheduled Event Create events.EventGuildScheduledEventCreate
Guild Scheduled Event Update events.EventGuildScheduledEventUpdate
Guild Scheduled Event Delete events.EventGuildScheduledEventDelete
Guild Scheduled Event User Add events.EventGuildScheduledEventUserAdd
Guild Scheduled Event User Remove events.EventGuildScheduledEventUserRemove
Guild Soundboard Sound Create events.EventGuildSoundboardSoundCreate
Guild Soundboard Sound Update events.EventGuildSoundboardSoundUpdate
Guild Soundboard Sound Delete events.EventGuildSoundboardSoundDelete
Guild Soundboard Sounds Update events.EventGuildSoundboardSoundsUpdate
Soundboard Sounds events.EventSoundboardSounds
Integration Create events.EventIntegrationCreate
Integration Update events.EventIntegrationUpdate
Integration Delete events.EventIntegrationDelete
Interaction Create events.EventInteractionCreate
Invite Create events.EventInviteCreate
Invite Delete events.EventInviteDelete
Message Create events.EventMessageCreate
Message Update events.EventMessageUpdate
Message Delete events.EventMessageDelete
Message Delete Bulk events.EventMessageDeleteBulk
Message Reaction Add events.EventMessageReactionAdd
Message Reaction Remove events.EventMessageReactionRemove
Message Reaction Remove All events.EventMessageReactionRemoveAll
Message Reaction Remove Emoji events.EventMessageReactionRemoveEmoji
Message Poll Vote Add events.EventMessagePollVoteAdd
Message Poll Vote Remove events.EventMessagePollVoteRemove
Presence Update events.EventPresenceUpdate
Stage Instance Create events.EventStageInstanceCreate
Stage Instance Update events.EventStageInstanceUpdate
Stage Instance Delete events.EventStageInstanceDelete
Subscription Create events.EventSubscriptionCreate
Subscription Update events.EventSubscriptionUpdate
Subscription Delete events.EventSubscriptionDelete
Typing Start events.EventTypingStart
User Update events.EventUserUpdate
Voice State Update events.EventVoiceStateUpdate
Voice Server Update events.EventVoiceServerUpdate
Voice Channel Status Update events.EventVoiceChannelStatusUpdate
Voice Channel Start Time Update events.EventVoiceChannelStartTimeUpdate
Voice Channel Effect Send events.EventVoiceChannelEffectSend
Webhooks Update events.EventWebhooksUpdate

Voice channel status ≠ channel update. When a voice channel's status text changes, Discord sends a dedicated VOICE_CHANNEL_STATUS_UPDATEnot CHANNEL_UPDATE. Subscribe with OnVoiceChannelStatusUpdate, not OnChannelUpdate. (When the cache is enabled, the wrapper also patches the cached channel's Status field for you.)

Documentation

In-depth guides live in docs/:

Guide Covers
Getting started From empty folder to a running bot
Configuration Intents and every options.With… option
Events & handlers Handlers, middleware, concurrency, synthetic events
Slash commands Registering commands, reading options, replying
Command management Create, edit, delete, scope commands; permissions
Components Buttons, select menus, Components V2
Modals Modal forms: build, show, read
Messages Sending, editing, attachments, mentions
Embeds Building and validating embeds
Cache behavior What is cached, when, and incomplete member caches
Sharding ShardManager, local coordinator, cross-shard messaging
REST client Standalone REST usage and typed errors

New to the library? Start with Getting started, then copy example/template as your project skeleton. Other runnable programs under example/: caching, commands, sharding, and slash_with_defer.

API reference

Full API documentation is available at pkg.go.dev/github.com/streame-gg/go-discord-wrapper.

Contributing

See CONTRIBUTING.md.

Support

Join the Discord server: https://discord.gg/nfBuZVejqp

License

Apache 2.0 — see LICENSE.

Documentation

Index

Constants

View Source
const (
	RepositoryURL = "https://github.com/streame-gg/go-discord-wrapper"
)

Variables

View Source
var RepositoryVersion = resolveVersion()

RepositoryVersion is the library version advertised to Discord in the REST User-Agent header and the gateway IDENTIFY properties. It is resolved once at startup from the build's module version so it cannot drift out of sync with the published tag; it falls back to repositoryVersionFallback for local (untagged) builds.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
Package api implements the Discord REST API client with proactive rate limiting, configurable retry logic, and full coverage of Discord API v10 endpoints.
Package api implements the Discord REST API client with proactive rate limiting, configurable retry logic, and full coverage of Discord API v10 endpoints.
Package builder provides fluent constructors for Discord UI components: embeds, buttons, select menus, modals, action rows, and text inputs.
Package builder provides fluent constructors for Discord UI components: embeds, buttons, select menus, modals, action rows, and text inputs.
Package cache defines the caching interface for Discord entities and provides an in-process implementation via NewMemoryCache.
Package cache defines the caching interface for Discord entities and provides an in-process implementation via NewMemoryCache.
mongocache
Package mongocache provides a MongoDB-backed implementation of cache.Cache.
Package mongocache provides a MongoDB-backed implementation of cache.Cache.
rediscache
Package rediscache provides a Redis-backed implementation of cache.Cache.
Package rediscache provides a Redis-backed implementation of cache.Cache.
stores
Package stores provides the generic BaseStore foundation and all option types used by the cache package.
Package stores provides the generic BaseStore foundation and all option types used by the cache package.
Package collection provides a generic Collection[K, V] type — a map with insertion-order iteration and ~30 utility methods, inspired by @discordjs/collection.
Package collection provides a generic Collection[K, V] type — a map with insertion-order iteration and ~30 utility methods, inspired by @discordjs/collection.
Package connection — cache update helpers.
Package connection — cache update helpers.
example
caching command
caching demonstrates how to attach a cache to the client and read entities back out of it without hitting the REST API.
caching demonstrates how to attach a cache to the client and read entities back out of it without hitting the REST API.
commands command
commands demonstrates the full slash-command lifecycle:
commands demonstrates the full slash-command lifecycle:
error_handling command
error_handling demonstrates how to inspect Discord REST errors with strong typing: matching a specific JSON error code (e.g.
error_handling demonstrates how to inspect Discord REST errors with strong typing: matching a specific JSON error code (e.g.
sharding command
sharding demonstrates running multiple gateway connections in one process with a ShardManager and a local in-process coordinator.
sharding demonstrates running multiple gateway connections in one process with a ShardManager and a local in-process coordinator.
slash_with_defer command
slash_with_defer demonstrates three patterns:
slash_with_defer demonstrates three patterns:
template command
Command template is a batteries-included starter bot you can copy as the skeleton for a real project.
Command template is a batteries-included starter bot you can copy as the skeleton for a real project.
template/pkg/bot
Package bot wires the client, cache, command registry, event handlers, and component handlers together.
Package bot wires the client, cache, command registry, event handlers, and component handlers together.
template/pkg/commands
Package commands holds every slash command the bot exposes, plus a small self-registering registry that auto-loads them.
Package commands holds every slash command the bot exposes, plus a small self-registering registry that auto-loads them.
template/pkg/components
Package components provides the shared core for handling message-component and modal interactions: a Handler interface and a reloadable Registry keyed by custom ID.
Package components provides the shared core for handling message-component and modal interactions: a Handler interface and a reloadable Registry keyed by custom ID.
template/pkg/components/buttons
Package buttons holds button interaction handlers, matched by custom ID.
Package buttons holds button interaction handlers, matched by custom ID.
template/pkg/components/modals
Package modals holds modal-submit handlers, matched by the modal's custom ID.
Package modals holds modal-submit handlers, matched by the modal's custom ID.
template/pkg/components/selectmenus
Package selectmenus holds select-menu interaction handlers, matched by custom ID.
Package selectmenus holds select-menu interaction handlers, matched by custom ID.
template/pkg/config
Package config holds the template's compile-time settings.
Package config holds the template's compile-time settings.
template/pkg/events
Package events holds the bot's gateway event handlers plus a small registry that makes them reloadable at runtime.
Package events holds the bot's gateway event handlers plus a small registry that makes them reloadable at runtime.
internal
Package options provides functional options for configuring the Discord client and REST client.
Package options provides functional options for configuring the Discord client and REST client.
Package sharding provides multi-shard orchestration for Discord bots.
Package sharding provides multi-shard orchestration for Discord bots.
types
discord
Package discord contains Discord data types shared across the gateway, REST API, interactions, and cache packages.
Package discord contains Discord data types shared across the gateway, REST API, interactions, and cache packages.

Jump to

Keyboard shortcuts

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