core

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package core holds botbooter's platform-agnostic engine: the Bot type, its command/middleware dispatch, and the connection lifecycle. Platform support is provided by adapters (see the Adapter interface) that live in sibling internal packages. The public github.com/lao/botbooter package is a thin facade over this one.

Index

Constants

This section is empty.

Variables

View Source
var ErrAlreadyConnected = errors.New("botbooter: already connected")

ErrAlreadyConnected is returned by Connect when the Bot is already connected.

View Source
var ErrUnknownBotType = errors.New("botbooter: unknown bot type")

ErrUnknownBotType is returned by Bot methods when the Bot has no adapter, which happens when it was not built through one of the platform constructors.

Functions

This section is empty.

Types

type Adapter

type Adapter interface {
	// Connect starts delivering incoming messages and runs until ctx is
	// canceled. It uses deps to dispatch messages and to signal the run loop.
	Connect(ctx context.Context, deps AdapterDeps) error
	// Disconnect tears down the connection. It must be safe to call when the
	// adapter never connected.
	Disconnect() error
	// Send delivers text to channelID.
	Send(ctx context.Context, channelID, text string) error
	// Attachments extracts the platform-agnostic attachments of a message.
	Attachments(m *Message) ([]Attachment, error)
}

Adapter is the platform-specific half of a Bot. Each supported platform (Slack, Discord, CLI) provides one; the Bot drives it through this interface, so the core has no compile-time dependency on any particular platform's connection logic.

type AdapterDeps

type AdapterDeps struct {
	// Dispatch routes an incoming message through middleware and command
	// matching.
	Dispatch func(ctx context.Context, m *Message)
	// Done signals the run loop that the connection has ended with err.
	Done func(err error)
	// Disconnect performs a full Bot.Disconnect; adapters that tear down on
	// context cancellation (e.g. Discord) use it.
	Disconnect func() error
}

AdapterDeps is the set of callbacks an Adapter uses to talk back to the Bot. It keeps the Bot's internals (dispatch, the done channel) unexported while still letting adapters in other packages drive them.

type Attachment

type Attachment struct {
	IsImage   bool
	URL       string
	ExtraData any
}

Attachment is a platform-agnostic file attached to a message. ExtraData holds the raw platform-specific attachment for callers that need more than URL.

type Bot

type Bot struct {
	BotType BotType

	DiscordSession    *discordgo.Session
	SlackClient       *slack.Client
	SlackSocketClient *socketmode.Client
	// contains filtered or unexported fields
}

Bot is the platform-agnostic chat bot. It holds the registered commands, middleware and unknown-command handler, drives a single Adapter through the connection lifecycle, and exposes the raw platform clients (DiscordSession, SlackClient, ...) as escape hatches. A Bot is safe for concurrent use.

func New

func New(botType BotType, adapter Adapter) *Bot

New creates a Bot of the given type backed by adapter. Constructors in the adapter packages use it and then set the exported escape-hatch fields (DiscordSession, SlackClient, ...) where applicable.

func (*Bot) AddHandler

func (b *Bot) AddHandler(cmd Command) error

AddHandler registers cmd, compiling and caching its Pattern. It returns an error if the pattern is not a valid regular expression. Commands are matched in registration order, first match wins.

func (*Bot) AddMiddleware

func (b *Bot) AddMiddleware(middleware Middleware)

AddMiddleware appends middleware to the dispatch chain. Middleware runs in registration order, each wrapping the next, around the matched handler.

func (*Bot) Connect

func (b *Bot) Connect(ctx context.Context) error

Connect starts the adapter's event loop and returns without blocking. It returns ErrAlreadyConnected if a connection is already active, ErrUnknownBotType if the Bot has no adapter, or any error from the adapter's own Connect.

func (*Bot) Disconnect

func (b *Bot) Disconnect() error

Disconnect tears down the active connection: it cancels the run context and runs the adapter's Disconnect exactly once. It is safe to call when not connected, returning ErrUnknownBotType only if the Bot has no adapter.

func (*Bot) GetAttachments

func (b *Bot) GetAttachments(message *Message) ([]Attachment, error)

GetAttachments returns the platform-agnostic attachments of message. It returns ErrUnknownBotType if the Bot has no adapter.

func (*Bot) HandleFunc

func (b *Bot) HandleFunc(pattern string, handler CommandHandler) error

HandleFunc is a convenience wrapper around AddHandler that registers handler for the given pattern.

func (*Bot) Run

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

Run connects the Bot and blocks until ctx is canceled or the event loop ends, then disconnects. A clean shutdown via ctx cancellation returns nil rather than ctx.Err(), so callers can safely do log.Fatal(bot.Run(ctx)).

func (*Bot) SendMessage

func (b *Bot) SendMessage(channelID, text string) error

SendMessage sends text to channelID using a background context. See SendMessageContext to supply your own.

func (*Bot) SendMessageContext

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

SendMessageContext sends text to channelID, honoring ctx for cancellation and deadlines. It returns ErrUnknownBotType if the Bot has no adapter.

func (*Bot) SetUnknownCommandHandler

func (b *Bot) SetUnknownCommandHandler(handler CommandHandler)

SetUnknownCommandHandler sets the handler invoked when an incoming message matches no registered command. If unset, unmatched messages are ignored.

func (*Bot) Start

func (b *Bot) Start() error

Start runs the Bot until the process receives an interrupt or SIGTERM, wiring up signal handling for callers that do not manage their own context.

type BotType

type BotType int

BotType identifies the messaging platform a Bot is connected to.

const (
	SlackBotType BotType = iota
	DiscordBotType
	CLIBotType
)

The supported bot types.

func (BotType) String

func (t BotType) String() string

String returns the lowercase platform name (e.g. "slack"), or a BotType(<n>) placeholder for an unknown value.

type CLIMessage

type CLIMessage struct {
	Text        string
	Attachments []Attachment
}

CLIMessage is the raw payload of a message read from the CLI adapter: the typed line and any attachments resolved from file paths in it.

type Command

type Command struct {
	Pattern string
	Handler CommandHandler
	// contains filtered or unexported fields
}

Command pairs a regular-expression Pattern with the Handler to run when an incoming message matches it. Register one with Bot.AddHandler, which compiles and caches the pattern.

type CommandHandler

type CommandHandler func(ctx context.Context, b *Bot, m *Message)

CommandHandler handles a dispatched message for a matched command.

type Message

type Message struct {
	UserID    string
	ChannelID string
	Content   string

	DiscordData *discordgo.MessageCreate
	SlackData   *slackevents.MessageEvent
	CLIData     *CLIMessage
}

Message is a platform-agnostic incoming message handed to command handlers. UserID, ChannelID and Content are always set; the platform-specific *Data field carries the raw event for callers that need it, and only the field for the originating platform is non-nil.

type Middleware

type Middleware func(ctx context.Context, b *Bot, m *Message, next CommandHandler)

Middleware wraps message dispatch. It runs before the matched handler and must call next to continue the chain (or omit it to short-circuit).

Jump to

Keyboard shortcuts

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