baldbot
v0.0.25
Published
BaldBot is a bald-themed, feature-rich Discord bot framework
Downloads
16
Readme
BaldBot
BaldBot is a bald-themed, feature-rich Discord bot framework.
Description
BaldBot allows developers to quickly create a Discord bot by creating easy-to-implement plugins that can execute upon any kind
of Discord.js ClientEvent
. There are other options to interact with a server too, such as daemons that can execute independently
of user interaction.
BaldBot aims to make writing custom commands and functionality as easy as possible. BaldBot handles all event listening, event handling, user authorization, execution priority, guild and user configuration, error handling, logging, and so much more.
BaldBot does expects developers to be familiar with Discord.js and TypeScript in
order to create new features. In summary, developers define the conditions and implementation of a feature, and BaldBot handles
everything else. BaldBot also exposes the Discord.js Client
to the user, and all of it's own event listeners, so a developer
can have as much or as little control over what BaldBot does and doesn't do as they want.
Features
Some of BaldBot's features include:
- Node.js Asynchronous context tracking to provide a context for each
ClientEvents
event and arguments, as well as easy access to the user/channel/guild using mappers defined for each event type. - Very strong guild/user configuration (planned). Most BaldBot configuration values can be modified by each guild to suit their needs, and users themselves can control which plugins they want enabled. Users can even selfban themselves from the bot, in case of peladophobia.
- Utility methods and abstractions so plugins can be written without needing to know exactly how to manage different event types. The intent is to have a very generic event chain so less code needs to be written, without falling into the trap of making wrappers that damage the extensibility of BaldBot.
- MongoDB database per-guild with abstractions for saving/loading shared or user data.
- Permission/administrator systems with granular role/permission control per user.
- Currency system
- Detailed logging using context variables.
- Strong error-handling, including startup time checks to reduce the likelihood of a bad plugin causing issues during runtime.
- Daemons, running defined tasks on intervals. Daemons can be defined globally or per-guild. Per-guild Daemons have access to the guild in it's context, in order to enable any sort of guild-based logic.
- And a lot more. Many features are in flux, and many others are planned.
Using BaldBot
TODO out of date
Adding a Plugin
BaldBot plugins implement the BaldBotPlugin
interface, and are used to implement powerful features very easily. They know which ClientEvents
they belong to, which event arguments to expect, which permissions are required to use them, their priority, their cooldown, and more.
There are also a few abstract plugins that can be extended, such as BaldBotDataPlugin
and BaldBotCommandPlugin
.
BaldBotDataPlugin
supports easily managing persistent data. It uses a type parameter to hold data of any shape or size, and has method to save
and load the data as needed. There are separate methods for guild (or shared) data, as well as data unique to the user that initiated the event.
BaldBotCommandPlugin
supports combining legacy-style message commands (using a prefix) with Discord slash commands. Commands are defined on this
plugin, and it will automagically intercept all slash command invocations (or messages matching the either command name or configured aliases) and
route them to the appropriate methods.
Note that the generics and fields currently available may not be in line with what's shown here, but the general structure should still be valid.
TODO out of date
export interface BaldBotPlugin<K extends keyof ClientEvent> {
supportedClientEvents: K[];
permissions: BaldBotPermission[];
priority?: number;
allowBots?: boolean;
cooldown?: { [key in PluginCooldownType]?: TimeUnit };
postRegister?(): void | Promise<void>
canHandle(clientEvent: K, eventArgs: ClientEvent[K]): boolean | Promise<boolean>;
handle(clientEvent: K, eventArgs: ClientEvent[K]): void | Promise<void>;
}
export abstract class BaldBotCommandPlugin implements BaldBotPlugin<'messageCreate' | 'interactionCreate'> {
commands: BaldBotPluginCommands;
aliases?: string[];
handleCommand(event: CommandInteraction): void | Promise<void>;
handleMessage?(event: Message): void | Promise<void>;
}
Adding a Daemon
Daemons are scheduled tasks that run on a defined interval with an optional delay. They have access to the Client object
used by BaldBot, so they can be powerful if needed. Daemons extend/implement the BaldBotDaemon
abstract class:
TODO out of date
export abstract class BaldBotDaemon {
...
constructor(private intervalMs: TimeUnit, private delayMs?: TimeUnit) { }
protected abstract run(client?: Client): void;
...
}
Adding support for a new ClientEvent
TODO out of date
By default, BaldBot only has deep support for messageCreate
and interactionCreate
events, emitted by the Discord.js
Client. However, this is no limitation! BaldBot can be configured to support any kind of client event across it's entire
event chain.
Most of BaldBot doesn't need to know anything about which client event is in flight, but there are a few places where
custom logic must be defined for each type of client event, if the behavior is needed. Here are a list of places where
custom support for new ClientEvents
will need to be added, if needed:
ClientEventContextMapper // Defines how BaldBotEventContext is built from ClientEvents
OperationManager (and subclasses) // Defines how generic operations work with ClientEvents
BaldBot does plan to support more of these out-of-the-box in the future, but for now,
messageCreate
andinteractionCreate
events remain the highest priority.
Sample
Visit BaldBot-Sample for a sample implementation. This sample bot initializes
BaldBot with a custom plugin and daemon, and adds support for a new ClientEvents
type across BaldBot's entire event chain.
Versioning
As BaldBot as very new and under active heavy development (renaming, moves, pattern changes, etc) it will be versioned by incrementing the minor version with no safety from breaking changes. Semantic versioning will eventually be used once BaldBot is considered production-ready. However, there are some unknowns around how the versioning will be affected by Discord API changes, and consequently Discord.js changes.
Check CHANGELOG.md to see the current versions, and what's been going into each one.
Special Thanks
- Discord.js
- The importance of Discord.js could not be overstated, this project would not exist without it. Discord.js allows BaldBot easy access and a great interface to the official Discord APIs.
- BaldBot has become increasingly dependent on Discord.js with time, as it currently uses Discord.js's list of
ClientEvents
as the backbone for most of BaldBot's extensibile patterns.
- ~~Continuation-Local Storage~~
- ~~This feature is something BaldBot plans to take great advantage of in the future. Originally added just for logging purposes~~ ~~(adding context to logs), there are plans to use CLS as a "interaction context" for all messages and commands.~~
- With the addition of Node.js Asynchronous context tracking
(Node.js's official implementation of the
node:async_hooks
module), this package isn't needed anymore. However, it was a great package to build BaldBot around, and was seamlessly replaced with Node.js'sAsyncLocalStorage
class.
History/Milestones
BaldBot began as a simple JavaScript bot, with the intention to add a few fun bald-related commands and also serve as some programming practice. Eventually, as more time went into BaldBot, it was decided that the productivity increase and type-safety gained from a transition to TypeScript would pay off.
After this, various features began to be added, such as database support, context, permissions, logging, and many others. Some of these came from need/asks, and others came from a desire to learn and achieve something new. Despite being invisible to users, much of the pride from BaldBot comes from the architecture, abstraction, and extensibility it offers to developers.
Plugins added to BaldBot for personal use in servers started to feel like restrictions for making BaldBot public, as many of them weren't meant to be public, for various reasons. This led to the idea of splitting the BaldBot framework into its own library to be made public, and keeping personal plugins private.
Today, BaldBot can now be used as a library to get a fairly advanced Discord bot off the ground in minutes. Check TODO.md for planned features/updates or known issues.