banter

package module
v0.1.13 Latest Latest
Warning

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

Go to latest
Published: May 22, 2026 License: MIT Imports: 22 Imported by: 0

README

banterbotapigo

This is the Go SDK for Banter, a one-to-one port of the Python banterbotapi library. If you have used discord.py or banterbotapi before, the patterns here will feel familiar. The goal is to let you write a Banter bot in Go with the same ergonomics a Python developer gets from those libraries, without the runtime overhead or the dependency on the Python interpreter.

Installation

go get github.com/BanterChatDev/banterbotapigo

The library lives under one Go module at the repository root. There is no separate install step beyond go get and no compiled binary to fetch. Go pulls the source on demand and links it into your bot when you build.

A first bot

The smallest useful bot is a handful of lines. It connects to the gateway, registers a single prefix command, and replies when the command fires. Everything else is optional.

package main

import (
	"context"
	"log"

	banter "github.com/BanterChatDev/banterbotapigo"
)

func main() {
	bot := banter.NewBot(banter.BotOpts{
		Intents: banter.IntentsDefault() | banter.IntentMessageContent,
	})

	bot.PrefixCommand("ping", "Quick health check", "Info",
		func(ctx context.Context, c *banter.Context) error {
			return c.Reply(ctx, "pong")
		},
	)

	if err := bot.Run(context.Background(), "YOUR_BOT_TOKEN"); err != nil {
		log.Fatal(err)
	}
}

The IntentMessageContent flag is needed for the bot to actually see the text of messages, which prefix commands depend on. Without it the gateway will deliver message_create events but the Content field will be empty.

Slash commands

Slash commands are registered with Bot.SlashCommand and respond through the Interaction argument. The signature gives you a typed handler and a structured options list. Options have a builder pattern for type, description, and required/optional state.

bot.SlashCommand("echo", "Repeat what you sent",
	[]banter.SlashOption{
		banter.NewSlashOption("text", banter.OptionString).Describe("what to repeat"),
		banter.NewSlashOption("loud", banter.OptionBoolean).Describe("uppercase?").Optional(),
	},
	func(ctx context.Context, i *banter.Interaction) error {
		text := i.OptString("text", "")
		if i.OptBool("loud", false) {
			text = strings.ToUpper(text)
		}
		return i.Respond(ctx, text, banter.RespondOpts{})
	},
)

Registering the same slash command name twice is treated as a programmer error. The library will log a critical message and exit the process. This is deliberate. It catches a class of bug where two command loaders end up registering the same name from different files, which would otherwise silently overwrite one handler and create a confusing runtime mystery. The same applies to prefix commands and to exact-match button handlers.

The interaction can be answered in a few different ways. The most common is Respond, which posts a visible reply. Defer acknowledges the interaction within the three-second window and lets you reply later via Followup, which is useful for handlers that take longer to compute. Update is specific to button interactions and edits the source message in place. All four methods take a RespondOpts struct where you can attach an embed, mark the reply ephemeral, or pass component rows.

Embeds

Embeds use a fluent builder so chains read top to bottom in the order they appear in the rendered message.

e := banter.NewEmbed().
	Title("Status").
	Description("All systems nominal.").
	ColorInt(0x57F287).
	AddField("Uptime", "12d 4h", true).
	AddField("Users", "1,204", true).
	Footer("Last checked just now", "")

Buttons attach to embeds and travel with them through any method that sends a message — Bot.SendEmbed, Context.ReplyEmbed, and Interaction.Respond with an Embed set in RespondOpts. Each button has a label, a style, and either a URL (for link buttons) or a custom ID (for handler buttons). Up to five buttons fit in a row and up to five rows fit on a message.

e.AddButton("Confirm", banter.ButtonOpts{Style: "success", CustomID: "confirm_yes"})
e.AddButton("Cancel", banter.ButtonOpts{Style: "danger", CustomID: "confirm_no"})

bot.OnButton("confirm_yes", func(ctx context.Context, i *banter.Interaction) error {
	return i.Update(ctx, "Confirmed.", banter.RespondOpts{})
})

Button handlers can match exactly or by prefix. Passing "page_*" to OnButton registers a glob that fires for any custom ID starting with page_. This is useful for pagination where the page number is embedded in the ID. Reading the suffix from Interaction.CustomID inside the handler lets one function handle every page click.

The help command

A help command is registered automatically. Typing !help (or whatever prefix you set) replies with an embed listing every prefix and slash command grouped by category. This matches the behavior of discord.py and the Python SDK.

If you want a different help command you have three options, and the API is designed to express them clearly.

The default is to omit the option entirely. The library registers its own help command and you get it for free.

bot := banter.NewBot(banter.BotOpts{Intents: banter.IntentsDefault()})

To disable the help command, pass NoHelpCommand. Nothing is registered under that name and !help does nothing.

bot := banter.NewBot(banter.BotOpts{
	Intents:     banter.IntentsDefault(),
	HelpCommand: banter.NoHelpCommand,
})

To replace it with your own, wrap a handler in CustomHelpCommand. Your handler is registered as !help and takes priority over the default.

bot := banter.NewBot(banter.BotOpts{
	Intents: banter.IntentsDefault(),
	HelpCommand: banter.CustomHelpCommand(func(ctx context.Context, c *banter.Context) error {
		return c.Reply(ctx, "use the docs at example.com/help")
	}),
})

Whichever option you pick, the dedup behavior still applies. If you both pass a CustomHelpCommand and call bot.PrefixCommand("help", ...) yourself, the second registration panics. This catches the case where you forgot you already provided a custom help and would otherwise quietly overwrite it.

Events

The bot has typed methods for the events users typically care about: OnMessage, OnReady, OnMessageEdit, OnMessageDelete, OnMemberJoin, OnReactionAdd, OnReactionRemove, OnResumed, and OnError. Each accepts a function with the right signature for that event, so you get autocompletion and the compiler catches a wrong argument type before you ship.

bot.OnReady(func(ctx context.Context) {
	log.Printf("bot ready as %s", bot.User.Username)
})

bot.OnMessage(func(ctx context.Context, m *banter.Message) {
	if m.Content == "ping" {
		bot.SendMessage(ctx, m.ChannelID, "pong")
	}
})

Every handler runs in its own goroutine. This means concurrent messages fire concurrent handlers, which is the right default for a chat bot but worth remembering when you write to shared state. Use a mutex or a channel-based design if your handlers touch the same map or counter.

If a handler returns an error or panics, the library does not crash. Panics are recovered and logged. Errors returned from slash and prefix handlers are routed to your OnError callback. The point is to keep the bot alive even when individual handlers misbehave.

HTTP access

The Bot type wraps the most common operations as convenience methods that return typed values. SendMessage, SendEmbed, CreateChannel, CreateCategory, ListChannels, GetChannel, and GetGuild all unmarshal the response into the appropriate model and attach a back-reference to the bot so the returned value can be used as the receiver of further calls.

For anything the convenience layer does not cover, the underlying HTTP client is exposed as bot.HTTP. Every endpoint described in the Banter API is wrapped here as a method. The return value is a raw []byte so you can unmarshal into whatever shape you want.

raw, err := bot.HTTP.KickMember(ctx, guildID, userID)

This split keeps the convenience layer small and predictable without forcing you to write a wrapper every time you reach for a less common endpoint. The same applies to UploadAttachment, which takes a *File built from NewFileFromPath, NewFileFromBytes, or NewFileFromReader and uploads it as multipart form data.

Errors

The library uses Go's standard error interface with a hierarchy that lets you handle specific cases. The base type is BanterError. HTTP failures wrap it as HTTPException, and specific HTTP statuses get their own types — Forbidden, NotFound, RateLimited, LoginFailure, and DuplicateCommand. Use errors.As to discriminate.

var rl *banter.RateLimited
if errors.As(err, &rl) {
	time.Sleep(time.Duration(rl.RetryAfter * float64(time.Second)))
}

For rate limits, the HTTP client already retries once automatically based on the X-RateLimit-Reset-After header. The RateLimited error only surfaces if both attempts fail, so by the time you see it the simple wait-and-retry has already been tried.

Sentinel errors live in errors.go for the conditions that don't carry extra data — ErrInteractionDetached, ErrInteractionResponded, ErrEveryoneNotFound, and so on. Use errors.Is to check for these.

The gateway

The connection to the Banter gateway is managed automatically. The library handles the WebSocket handshake, heartbeats, sequence tracking, and resume-on-reconnect. When the connection drops, it reconnects with exponential backoff and jitter, and if the session is still resumable it sends the resume payload so events from the gap can be replayed. If the close code indicates an unrecoverable failure — invalid token, banned, or a protocol violation — the bot stops cleanly rather than retrying forever.

You do not normally need to think about any of this. The default behavior is what almost every bot wants. If you do want to opt out of reconnect for testing, set Reconnect: false in BotOpts. The bot will then run until the first disconnect and exit.

Logging

The library uses a coloured logger that writes to standard error. Levels are Debug, Info, Warn, Error, and Panic. The default level is Info. Set the BANTERAPI_DEBUG environment variable to 1, true, or yes to switch to Debug and see the per-request HTTP and gateway frame logs. Set NO_COLOR to disable ANSI escapes — useful in environments that pipe the output to a file or a logging service that does not handle the escapes.

You can use the same logger in your own code by calling banter.NewLogger("yourname"). The name appears as the third column of each log line and helps separate your messages from the library's. There is no separate user-facing logger and no second formatting pass to maintain.

Pagination

The Paginator type packages the common case where you want to show a list of items across multiple pages with Back and Forward buttons. You give it a fetch callback that returns the full slice, a per-page count, and a build callback that renders a slice into an embed. The paginator handles slicing, button wiring, and the page-number-in-custom-id round trip.

The full pagination example lives under examples/ and is the easiest way to understand the flow end to end. The short version is that you build the paginator once, respond to the initial slash command with paginator.Respond, and route button clicks for the matching prefix to paginator.Update.

Examples

The repository contains six examples under examples/, each in its own folder with a single main.go. They cover slash commands with options, prefix commands with aliases and an auto-help integration, channel creation, walking the bot's guild list with the library logger, generating and uploading a random text file, and inspecting attached files on a message. Together they touch most of the public surface and serve as the fastest way to learn the library after this README.

Run any of them from the repository root with go run ./examples/<name>. Each main.go has a const token = "REPLACE_ME" at the top that you swap with your real bot token before running. Be careful to revert the token to REPLACE_ME before pushing, since the whitelist .gitignore tracks every .go file under examples/.

Compatibility

The library targets Go 1.22 and later. It depends on github.com/gorilla/websocket for the gateway connection and on the standard library for everything else. The module path is github.com/BanterChatDev/banterbotapigo and the import alias is banter by convention.

Status

The library is at version 0.1.0 and is functionally complete relative to the Python SDK it ports. Both libraries cover the same set of HTTP endpoints, the same event types, the same gateway behavior including resume on reconnect, and the same dedup-on-duplicate-command pattern. There are minor differences in how the API surfaces in each language because Go and Python have different idioms for kwargs, decorators, and async, but anything you can do in one library you can do in the other.

The first tagged release will go out as v0.1.0 once the examples have run end to end against a live test bot. After that, semantic versioning applies. The public API surface as documented here is the contract.

License

MIT. See LICENSE for the full text.

Documentation

Index

Constants

View Source
const (
	ChannelTypeText  = "text"
	ChannelTypeVoice = "voice"
)
View Source
const (
	OptionString  = "STRING"
	OptionInteger = "INTEGER"
	OptionBoolean = "BOOLEAN"
	OptionUser    = "USER"
	OptionChannel = "CHANNEL"
	OptionRole    = "ROLE"
)
View Source
const (
	DefaultBaseURL       = "https://banterchat.org"
	DefaultGatewayPath   = "/api/v1/bot/gateway"
	DefaultCommandPrefix = "!"
	DefaultHelpColorInt  = 0x5865f2
)
View Source
const (
	MsgDupSlashCommand    = "duplicate slash command %q — fix your command loader and restart"
	MsgDupPrefixCommand   = "duplicate prefix command %q — fix your command loader and restart"
	MsgDupButtonHandler   = "duplicate button handler %q — fix your loader and restart"
	MsgEmptyButtonID      = "OnButton: custom_id must be non-empty"
	MsgCommandSyncDup     = "" /* 218-byte string literal not displayed */
	MsgSlashHandlerFailed = "Command failed."
)
View Source
const (
	IntentGuilds           int64 = 1 << 0
	IntentGuildMembers     int64 = 1 << 1
	IntentGuildModeration  int64 = 1 << 2
	IntentGuildPresences   int64 = 1 << 3
	IntentGuildMessages    int64 = 1 << 4
	IntentGuildReactions   int64 = 1 << 5
	IntentGuildTyping      int64 = 1 << 6
	IntentGuildVoiceStates int64 = 1 << 7
	IntentDirectMessages   int64 = 1 << 8
	IntentDirectReactions  int64 = 1 << 9
	IntentDirectTyping     int64 = 1 << 10
	IntentMessageContent   int64 = 1 << 11
	IntentBotEvents        int64 = 1 << 12
)
View Source
const (
	PermSendMessages     int64 = 1 << 0
	PermManageChannels   int64 = 1 << 1
	PermManageRoles      int64 = 1 << 2
	PermManageMessages   int64 = 1 << 3
	PermAdministrator    int64 = 1 << 4
	PermMentionEveryone  int64 = 1 << 5
	PermViewChannels     int64 = 1 << 6
	PermAttachFiles      int64 = 1 << 7
	PermBanMembers       int64 = 1 << 8
	PermUseSlashCommands int64 = 1 << 9
	PermManageGuild      int64 = 1 << 10
	PermKickMembers      int64 = 1 << 11
)
View Source
const Version = "0.1.0"

Variables

View Source
var (
	ErrInteractionDetached    = errors.New("interaction has no attached client")
	ErrBotAlreadyRunning      = errors.New("banter: bot already running")
	ErrBotNotRunning          = errors.New("banter: bot not running; call HTTP methods from handlers (e.g. OnReady) or after Run starts")
	ErrDownloadNilAttachment  = errors.New("banter: DownloadAttachment called with nil attachment")
	ErrSendFileNilFile        = errors.New("banter: SendFile called with nil file")
	ErrInteractionHTTPMissing = errors.New("interaction has no attached HTTP client")
	ErrInteractionResponded   = errors.New("interaction already responded to")
	ErrRespondEmpty           = errors.New("respond requires non-empty content or an embed")
	ErrFollowupEmpty          = errors.New("followup requires non-empty content or an embed")
	ErrUpdateNotButton        = errors.New("update is only valid for button interactions — use Respond or Followup for slash commands")
	ErrContextDetached        = errors.New("context detached from bot")
	ErrFileNeedsFilename      = errors.New("file constructors require a filename")
	ErrHTTPRetriesExhausted   = errors.New("http: exhausted retries without returning")
	ErrUploadRetriesExhausted = errors.New("upload: exhausted retries")
	ErrEveryoneNotFound       = errors.New("@everyone role not found in guild")
)
View Source
var NoHelpCommand = &HelpCommand{disabled: true}

Functions

func DescribePerms

func DescribePerms(bitmask int64) []string

func HasPerm

func HasPerm(bitmask, required int64) bool

func IntentsAll

func IntentsAll() int64

func IntentsDefault

func IntentsDefault() int64

func IntentsNone

func IntentsNone() int64

func PermsAll

func PermsAll() int64

Types

type Attachment

type Attachment struct {
	ID       string `json:"id"`
	Filename string `json:"filename"`
	Size     int64  `json:"size"`
	URL      string `json:"url"`
}

type BadArgument

type BadArgument struct {
	CommandError
	Name     string
	Value    string
	Expected string
}

type BanterError

type BanterError struct {
	Msg string
}

func (*BanterError) Error

func (e *BanterError) Error() string

type Bot

type Bot struct {
	User      *User
	SessionID string
	Guilds    map[string]*Guild

	HTTP *HTTPClient
	// contains filtered or unexported fields
}

func NewBot

func NewBot(opts BotOpts) *Bot

func (*Bot) AutoNotFoundReply added in v0.1.9

func (b *Bot) AutoNotFoundReply()

func (*Bot) CreateCategory

func (b *Bot) CreateCategory(ctx context.Context, guildID, name string) (*Category, error)

func (*Bot) CreateChannel

func (b *Bot) CreateChannel(ctx context.Context, guildID, name string, opts ChannelOpts) (*Channel, error)

func (*Bot) DeleteCategory added in v0.1.3

func (b *Bot) DeleteCategory(ctx context.Context, categoryID string) error

func (*Bot) DeleteChannel added in v0.1.3

func (b *Bot) DeleteChannel(ctx context.Context, channelID string) error

func (*Bot) Done added in v0.1.5

func (b *Bot) Done() <-chan struct{}

func (*Bot) DownloadAttachment added in v0.1.2

func (b *Bot) DownloadAttachment(ctx context.Context, att *Attachment) (*File, error)

func (*Bot) EnsureCategory added in v0.1.1

func (b *Bot) EnsureCategory(ctx context.Context, guildID, name string) (*Category, error)

func (*Bot) EnsureChannel added in v0.1.1

func (b *Bot) EnsureChannel(ctx context.Context, guildID, name string, opts ChannelOpts) (*Channel, error)

func (*Bot) EveryoneRole

func (b *Bot) EveryoneRole(ctx context.Context, guildID string) (*Role, error)

func (*Bot) GetChannel

func (b *Bot) GetChannel(ctx context.Context, channelID string) (*Channel, error)

func (*Bot) GetGuild

func (b *Bot) GetGuild(ctx context.Context, guildID string) (*Guild, error)

func (*Bot) ListCategories added in v0.1.1

func (b *Bot) ListCategories(ctx context.Context, guildID string) ([]*Category, error)

func (*Bot) ListChannels

func (b *Bot) ListChannels(ctx context.Context, guildID string) ([]*Channel, error)

func (*Bot) OnButton

func (b *Bot) OnButton(customID string, handler ButtonHandler)

func (*Bot) OnError

func (b *Bot) OnError(h ErrorHandler)

func (*Bot) OnMemberJoin

func (b *Bot) OnMemberJoin(h MemberJoinHandler)

func (*Bot) OnMessage

func (b *Bot) OnMessage(h MessageHandler)

func (*Bot) OnMessageDelete

func (b *Bot) OnMessageDelete(h MessageDeleteHandler)

func (*Bot) OnMessageEdit

func (b *Bot) OnMessageEdit(h MessageEditHandler)

func (*Bot) OnReactionAdd

func (b *Bot) OnReactionAdd(h ReactionAddHandler)

func (*Bot) OnReactionRemove

func (b *Bot) OnReactionRemove(h ReactionRemoveHandler)

func (*Bot) OnReady

func (b *Bot) OnReady(h ReadyHandler)

func (*Bot) OnResumed

func (b *Bot) OnResumed(h ResumedHandler)

func (*Bot) PrefixCommand

func (b *Bot) PrefixCommand(name, help, category string, handler PrefixHandler, aliases ...string)

func (*Bot) Run

func (b *Bot) Run(ctx context.Context, token string) error

func (*Bot) SendEmbed

func (b *Bot) SendEmbed(ctx context.Context, channelID string, embed *Embed) (*Message, error)

func (*Bot) SendFile added in v0.1.2

func (b *Bot) SendFile(ctx context.Context, channelID string, file *File, opts SendFileOpts) (*Message, error)

func (*Bot) SendMessage

func (b *Bot) SendMessage(ctx context.Context, channelID, content string) (*Message, error)

func (*Bot) SlashCommand

func (b *Bot) SlashCommand(name, description string, options []SlashOption, handler SlashHandler)

type BotOpts

type BotOpts struct {
	Intents       int64
	BaseURL       string
	WSURL         string
	Reconnect     bool
	CommandPrefix string
	ApplicationID string
	HelpCommand   *HelpCommand
	HelpColor     int
	Debug         bool
}

type BuildEmbedFn

type BuildEmbedFn func(items []any, page, total int) *Embed

type ButtonHandler

type ButtonHandler func(ctx context.Context, i *Interaction) error

type ButtonOpts

type ButtonOpts struct {
	Style    string
	URL      string
	Emoji    string
	Disabled bool
	CustomID string
}

type Category

type Category struct {
	ID       string `json:"id"`
	GuildID  string `json:"guild_id"`
	Name     string `json:"name"`
	Position int    `json:"position"`
	// contains filtered or unexported fields
}

type Channel

type Channel struct {
	ID          string `json:"id"`
	GuildID     string `json:"guild_id"`
	CategoryID  string `json:"category_id"`
	Name        string `json:"name"`
	Description string `json:"description"`
	Type        string `json:"type"`
	Position    int    `json:"position"`
	// contains filtered or unexported fields
}

type ChannelOpts added in v0.1.1

type ChannelOpts struct {
	CategoryID string
	Type       string
}

type CommandError

type CommandError struct{ Msg string }

func (*CommandError) Error

func (e *CommandError) Error() string

type CommandNotFound

type CommandNotFound struct {
	CommandError
	Name    string
	Message *Message
}

type Context

type Context struct {
	Bot     *Bot
	Message *Message
	Name    string
	RawArgs string
}

func (*Context) Reply

func (c *Context) Reply(ctx context.Context, content string) error

func (*Context) ReplyEmbed

func (c *Context) ReplyEmbed(ctx context.Context, embed *Embed) error

func (*Context) ReplyFile added in v0.1.2

func (c *Context) ReplyFile(ctx context.Context, file *File, content string) error

type CreateCategoryBody

type CreateCategoryBody struct {
	Name                string               `json:"name"`
	PermissionOverrides []PermissionOverride `json:"permission_overrides,omitempty"`
}

type CreateChannelBody

type CreateChannelBody struct {
	Name                string               `json:"name"`
	Description         string               `json:"description,omitempty"`
	CategoryID          string               `json:"category_id,omitempty"`
	Type                string               `json:"type,omitempty"`
	PermissionOverrides []PermissionOverride `json:"permission_overrides,omitempty"`
}

type CreateRoleBody

type CreateRoleBody struct {
	Name        string `json:"name"`
	Color       string `json:"color,omitempty"`
	Description string `json:"description,omitempty"`
	Permissions int64  `json:"permissions,omitempty"`
	Deny        int64  `json:"deny,omitempty"`
	Position    int    `json:"position,omitempty"`
	Mentionable bool   `json:"mentionable,omitempty"`
}

type Dispatcher

type Dispatcher func(ctx context.Context, eventType string, payload json.RawMessage)

type DuplicateCommand

type DuplicateCommand struct {
	BanterError
	Name    string
	Source  string
	HTTPExc *HTTPException
}

type EditCategoryPatch

type EditCategoryPatch struct {
	Name     *string `json:"name,omitempty"`
	Position *int    `json:"position,omitempty"`
}

type EditChannelPatch

type EditChannelPatch struct {
	Name        *string `json:"name,omitempty"`
	Description *string `json:"description,omitempty"`
	Position    *int    `json:"position,omitempty"`
	CategoryID  *string `json:"category_id,omitempty"`
}

type EditGuildPatch

type EditGuildPatch struct {
	Name             *string `json:"name,omitempty"`
	Description      *string `json:"description,omitempty"`
	WelcomeChannelID *string `json:"welcome_channel_id,omitempty"`
}

type Embed

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

func DefaultNotFoundEmbed added in v0.1.9

func DefaultNotFoundEmbed(name, prefix string) *Embed

func NewEmbed

func NewEmbed() *Embed

func (*Embed) AddButton

func (e *Embed) AddButton(label string, opts ButtonOpts) *Embed

func (*Embed) AddField

func (e *Embed) AddField(name, value string, inline bool) *Embed

func (*Embed) Author

func (e *Embed) Author(name, url, iconURL string) *Embed

func (*Embed) ColorHex

func (e *Embed) ColorHex(s string) *Embed

func (*Embed) ColorInt

func (e *Embed) ColorInt(c int) *Embed

func (*Embed) Description

func (e *Embed) Description(s string) *Embed

func (*Embed) Footer

func (e *Embed) Footer(text, iconURL string) *Embed

func (*Embed) Image

func (e *Embed) Image(url string) *Embed

func (*Embed) PendingComponents

func (e *Embed) PendingComponents() []map[string]any

func (*Embed) Thumbnail

func (e *Embed) Thumbnail(url string) *Embed

func (*Embed) Title

func (e *Embed) Title(s string) *Embed

func (*Embed) ToDict

func (e *Embed) ToDict() map[string]any

func (*Embed) URL

func (e *Embed) URL(s string) *Embed

type ErrorHandler

type ErrorHandler func(ctx context.Context, err error)

type FetchFn

type FetchFn func() []any

type File

type File struct {
	Data     []byte
	Filename string
}

func NewFileFromBytes

func NewFileFromBytes(data []byte, filename string) (*File, error)

func NewFileFromPath

func NewFileFromPath(path string) (*File, error)

func NewFileFromReader

func NewFileFromReader(r io.Reader, filename string) (*File, error)

func (*File) String

func (f *File) String() string

type Forbidden

type Forbidden struct{ HTTPException }

type Gateway

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

func NewGateway

func NewGateway(token string, intents int64, wsURL string, dispatcher Dispatcher) *Gateway

func (*Gateway) Close

func (g *Gateway) Close() error

func (*Gateway) CloseInfo

func (g *Gateway) CloseInfo() (int, string)

func (*Gateway) Connect

func (g *Gateway) Connect(ctx context.Context) error

func (*Gateway) InvalidSession

func (g *Gateway) InvalidSession() bool

func (*Gateway) LastSeq

func (g *Gateway) LastSeq() int

func (*Gateway) Run

func (g *Gateway) Run(ctx context.Context) error

func (*Gateway) SetResume

func (g *Gateway) SetResume(sessionID string, seq int)

type GatewayError

type GatewayError struct{ BanterError }

type Guild

type Guild struct {
	ID               string `json:"id"`
	Name             string `json:"name"`
	Description      string `json:"description"`
	OwnerID          string `json:"owner_id"`
	WelcomeChannelID string `json:"welcome_channel_id"`
	// contains filtered or unexported fields
}

type HTTPClient

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

func NewHTTPClient

func NewHTTPClient(token, baseURL string) *HTTPClient

func (*HTTPClient) AddReaction

func (h *HTTPClient) AddReaction(ctx context.Context, channelID, messageID, emoji string) ([]byte, error)

func (*HTTPClient) AddRole

func (h *HTTPClient) AddRole(ctx context.Context, guildID, userID, roleID string) ([]byte, error)

func (*HTTPClient) BanMember

func (h *HTTPClient) BanMember(ctx context.Context, guildID, userID, reason string) ([]byte, error)

func (*HTTPClient) Close

func (h *HTTPClient) Close() error

func (*HTTPClient) CreateCategory

func (h *HTTPClient) CreateCategory(ctx context.Context, guildID string, body CreateCategoryBody) ([]byte, error)

func (*HTTPClient) CreateChannel

func (h *HTTPClient) CreateChannel(ctx context.Context, guildID string, body CreateChannelBody) ([]byte, error)

func (*HTTPClient) CreateRole

func (h *HTTPClient) CreateRole(ctx context.Context, guildID string, body CreateRoleBody) ([]byte, error)

func (*HTTPClient) DeleteCategory

func (h *HTTPClient) DeleteCategory(ctx context.Context, categoryID string) ([]byte, error)

func (*HTTPClient) DeleteChannel

func (h *HTTPClient) DeleteChannel(ctx context.Context, channelID string) ([]byte, error)

func (*HTTPClient) DeleteMessage

func (h *HTTPClient) DeleteMessage(ctx context.Context, messageID string) ([]byte, error)

func (*HTTPClient) DeleteRole

func (h *HTTPClient) DeleteRole(ctx context.Context, roleID string) ([]byte, error)

func (*HTTPClient) DownloadAttachment

func (h *HTTPClient) DownloadAttachment(ctx context.Context, attachmentID string) ([]byte, error)

func (*HTTPClient) EditCategory

func (h *HTTPClient) EditCategory(ctx context.Context, categoryID string, patch EditCategoryPatch) ([]byte, error)

func (*HTTPClient) EditChannel

func (h *HTTPClient) EditChannel(ctx context.Context, channelID string, patch EditChannelPatch) ([]byte, error)

func (*HTTPClient) EditGuild

func (h *HTTPClient) EditGuild(ctx context.Context, guildID string, patch EditGuildPatch) ([]byte, error)

func (*HTTPClient) EditMessage

func (h *HTTPClient) EditMessage(ctx context.Context, messageID, content string) ([]byte, error)

func (*HTTPClient) EditRole

func (h *HTTPClient) EditRole(ctx context.Context, roleID string, patch map[string]any) ([]byte, error)

func (*HTTPClient) GetChannel

func (h *HTTPClient) GetChannel(ctx context.Context, channelID string) ([]byte, error)

func (*HTTPClient) GetGuild

func (h *HTTPClient) GetGuild(ctx context.Context, guildID string) ([]byte, error)

func (*HTTPClient) GetMember

func (h *HTTPClient) GetMember(ctx context.Context, guildID, userID string) ([]byte, error)

func (*HTTPClient) GetRole

func (h *HTTPClient) GetRole(ctx context.Context, roleID string) ([]byte, error)

func (*HTTPClient) GetUser

func (h *HTTPClient) GetUser(ctx context.Context, userID string) ([]byte, error)

func (*HTTPClient) KickMember

func (h *HTTPClient) KickMember(ctx context.Context, guildID, userID string) ([]byte, error)

func (*HTTPClient) ListCategories

func (h *HTTPClient) ListCategories(ctx context.Context, guildID string) ([]byte, error)

func (*HTTPClient) ListChannelMembers

func (h *HTTPClient) ListChannelMembers(ctx context.Context, channelID string, limit, offset int, search string) ([]byte, error)

func (*HTTPClient) ListChannels

func (h *HTTPClient) ListChannels(ctx context.Context, guildID string) ([]byte, error)

func (*HTTPClient) ListCommands

func (h *HTTPClient) ListCommands(ctx context.Context) ([]byte, error)

func (*HTTPClient) ListGuildBans

func (h *HTTPClient) ListGuildBans(ctx context.Context, guildID string) ([]byte, error)

func (*HTTPClient) ListMessages

func (h *HTTPClient) ListMessages(ctx context.Context, channelID, before string, limit int) ([]byte, error)

func (*HTTPClient) ListRoles

func (h *HTTPClient) ListRoles(ctx context.Context, guildID string) ([]byte, error)

func (*HTTPClient) Me

func (h *HTTPClient) Me(ctx context.Context) ([]byte, error)

func (*HTTPClient) PurgeChannel

func (h *HTTPClient) PurgeChannel(ctx context.Context, channelID string, limit int) ([]byte, error)

func (*HTTPClient) RegisterCommands

func (h *HTTPClient) RegisterCommands(ctx context.Context, commands []map[string]any) ([]byte, error)

func (*HTTPClient) RemoveReaction

func (h *HTTPClient) RemoveReaction(ctx context.Context, channelID, messageID, emoji string) ([]byte, error)

func (*HTTPClient) RemoveRole

func (h *HTTPClient) RemoveRole(ctx context.Context, guildID, userID, roleID string) ([]byte, error)

func (*HTTPClient) ReorderCategories

func (h *HTTPClient) ReorderCategories(ctx context.Context, guildID string, items []ReorderItem) ([]byte, error)

func (*HTTPClient) ReorderChannels

func (h *HTTPClient) ReorderChannels(ctx context.Context, guildID string, items []ReorderItem) ([]byte, error)

func (*HTTPClient) Request

func (h *HTTPClient) Request(ctx context.Context, method, path string, body any, params map[string]string, extraHeaders map[string]string) ([]byte, error)

func (*HTTPClient) RespondInteraction

func (h *HTTPClient) RespondInteraction(ctx context.Context, interactionID, token string, body map[string]any) error

func (*HTTPClient) SendMessage

func (h *HTTPClient) SendMessage(ctx context.Context, channelID string, body SendMessageBody) ([]byte, error)

func (*HTTPClient) SetCategoryPermissions

func (h *HTTPClient) SetCategoryPermissions(ctx context.Context, categoryID, roleID string, allow, deny int64) ([]byte, error)

func (*HTTPClient) SetChannelPermissions

func (h *HTTPClient) SetChannelPermissions(ctx context.Context, channelID, roleID string, allow, deny int64) ([]byte, error)

func (*HTTPClient) TriggerTyping

func (h *HTTPClient) TriggerTyping(ctx context.Context, channelID string) ([]byte, error)

func (*HTTPClient) UnbanMember

func (h *HTTPClient) UnbanMember(ctx context.Context, guildID, userID string) ([]byte, error)

func (*HTTPClient) UploadAttachment

func (h *HTTPClient) UploadAttachment(ctx context.Context, channelID string, f *File) ([]byte, error)

type HTTPException

type HTTPException struct {
	BanterError
	Status  int
	Code    int
	Message string
	Method  string
	Path    string
}

type HelpCommand

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

func CustomHelpCommand

func CustomHelpCommand(handler PrefixHandler) *HelpCommand

func DefaultHelpCommand

func DefaultHelpCommand() *HelpCommand

type Interaction

type Interaction struct {
	ID          string
	Token       string
	AppID       string
	Type        string
	CommandName string
	CustomID    string
	MessageID   string
	Options     map[string]any
	GuildID     string
	ChannelID   string
	UserID      string
	// contains filtered or unexported fields
}

func (*Interaction) Defer

func (i *Interaction) Defer(ctx context.Context, ephemeral bool) error

func (*Interaction) Followup

func (i *Interaction) Followup(ctx context.Context, content string, opts RespondOpts) error

func (*Interaction) IsButton

func (i *Interaction) IsButton() bool

func (*Interaction) IsSlash

func (i *Interaction) IsSlash() bool

func (*Interaction) OptBool

func (i *Interaction) OptBool(name string, fallback bool) bool

func (*Interaction) OptInt

func (i *Interaction) OptInt(name string, fallback int) int

func (*Interaction) OptString

func (i *Interaction) OptString(name, fallback string) string

func (*Interaction) Respond

func (i *Interaction) Respond(ctx context.Context, content string, opts RespondOpts) error

func (*Interaction) Update

func (i *Interaction) Update(ctx context.Context, content string, opts RespondOpts) error

type Logger

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

func NewLogger

func NewLogger(name string) *Logger

func (*Logger) Debug

func (l *Logger) Debug(format string, args ...any)

func (*Logger) Error

func (l *Logger) Error(format string, args ...any)

func (*Logger) Info

func (l *Logger) Info(format string, args ...any)

func (*Logger) Panic

func (l *Logger) Panic(format string, args ...any)

func (*Logger) Warn

func (l *Logger) Warn(format string, args ...any)

type LoginFailure

type LoginFailure struct{ BanterError }

type Member

type Member struct {
	UserID   string   `json:"user_id"`
	GuildID  string   `json:"guild_id"`
	Nickname string   `json:"nickname"`
	RoleIDs  []string `json:"role_ids"`
	JoinedAt string   `json:"joined_at"`
	// contains filtered or unexported fields
}

type MemberJoinHandler

type MemberJoinHandler func(ctx context.Context, m *Member)

type Message

type Message struct {
	ID          string       `json:"id"`
	ChannelID   string       `json:"channel_id"`
	GuildID     string       `json:"guild_id"`
	UserID      string       `json:"user_id"`
	Content     string       `json:"content"`
	CreatedAt   string       `json:"created_at"`
	EditedAt    string       `json:"edited_at"`
	ReplyTo     string       `json:"reply_to"`
	Attachments []Attachment `json:"attachments"`
	IsBot       bool         `json:"is_bot"`
	// contains filtered or unexported fields
}

type MessageDeleteHandler

type MessageDeleteHandler func(ctx context.Context, payload json.RawMessage)

type MessageEditHandler

type MessageEditHandler func(ctx context.Context, payload json.RawMessage)

type MessageHandler

type MessageHandler func(ctx context.Context, m *Message)

type MissingArgument

type MissingArgument struct {
	CommandError
	Name string
}

type MissingPermissions

type MissingPermissions struct {
	BanterError
	Missing []string
}

type NotFound

type NotFound struct{ HTTPException }

type Paginator

type Paginator struct {
	Fetch        FetchFn
	PerPage      int
	BuildEmbed   BuildEmbedFn
	Prefix       string
	EmptyMessage string
}

func NewPaginator

func NewPaginator(fetch FetchFn, perPage int, build BuildEmbedFn) *Paginator

func (*Paginator) Respond

func (p *Paginator) Respond(ctx context.Context, i *Interaction, page int, ephemeral bool) error

func (*Paginator) Update

func (p *Paginator) Update(ctx context.Context, i *Interaction) error

type PermissionOverride

type PermissionOverride struct {
	RoleID string `json:"role_id"`
	Allow  int64  `json:"allow"`
	Deny   int64  `json:"deny"`
}

func AllowingOverride

func AllowingOverride(roleID string, bits int64) PermissionOverride

func DenyingOverride

func DenyingOverride(roleID string, bits int64) PermissionOverride

type PrefixHandler

type PrefixHandler func(ctx context.Context, c *Context) error

type RateLimited

type RateLimited struct {
	HTTPException
	RetryAfter float64
}

type ReactionAddHandler

type ReactionAddHandler func(ctx context.Context, payload json.RawMessage)

type ReactionRemoveHandler

type ReactionRemoveHandler func(ctx context.Context, payload json.RawMessage)

type ReadyHandler

type ReadyHandler func(ctx context.Context)

type ReorderItem

type ReorderItem struct {
	ID       string `json:"id"`
	Position int    `json:"position"`
}

type RespondOpts

type RespondOpts struct {
	Embed      *Embed
	Ephemeral  bool
	Components []map[string]any
	ReplyTo    string
}

type ResumedHandler

type ResumedHandler func(ctx context.Context)

type Role

type Role struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Color       string `json:"color"`
	Position    int    `json:"position"`
	Permissions int64  `json:"permissions"`
	// contains filtered or unexported fields
}

type SendFileOpts added in v0.1.2

type SendFileOpts struct {
	Content string
	ReplyTo string
	Embed   *Embed
}

type SendMessageBody

type SendMessageBody struct {
	Content       string           `json:"content"`
	Embed         map[string]any   `json:"embed,omitempty"`
	ReplyTo       string           `json:"reply_to,omitempty"`
	AttachmentIDs []string         `json:"attachment_ids,omitempty"`
	Components    []map[string]any `json:"components,omitempty"`
}

type SlashHandler

type SlashHandler func(ctx context.Context, i *Interaction) error

func HasPermissions

func HasPermissions(required int64, handler SlashHandler) SlashHandler

type SlashOption

type SlashOption struct {
	Name        string
	Type        string
	Description string
	Required    bool
}

func NewSlashOption

func NewSlashOption(name, optType string) SlashOption

func (SlashOption) Describe

func (o SlashOption) Describe(s string) SlashOption

func (SlashOption) Optional

func (o SlashOption) Optional() SlashOption

type User

type User struct {
	ID          string `json:"id"`
	Username    string `json:"username"`
	DisplayName string `json:"display_name"`
	AvatarID    string `json:"avatar_id"`
	Bot         bool   `json:"is_bot"`
}

func (*User) UnmarshalJSON

func (u *User) UnmarshalJSON(data []byte) error

Directories

Path Synopsis
examples
createchannel command
fileinfo command
listguilds command
prefix command
randomfile command
slash command

Jump to

Keyboard shortcuts

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