Skip to content

mineral-dart/core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2,297 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mineral

Mineral is a Dart framework for building Discord bots. It handles the Discord gateway, REST API, and interaction routing so you can focus on your bot's logic.

Everything is organized around providers — isolated modules that register commands, events, and components. Each feature lives in its own class, making bots easy to grow and maintain across a team.

Discord


Packages

Package Description Version
mineral Core framework — gateway, REST API, commands, events, components pub
mineral_cache Cache providers — in-memory and Redis pub

Examples

Setting up a bot

Register providers and start the bot. Each provider groups related commands, events, and components.

void main() async {
  final client = ClientBuilder()
    .setIntent(Intent.allNonPrivileged)
    .registerProvider(WelcomeProvider.new)
    .registerProvider(FeedbackProvider.new)
    .build();

  await client.init();
}
final class WelcomeProvider extends Provider {
  final Client _client;

  WelcomeProvider(this._client) {
    _client
      ..register<OnMemberJoin>(OnMemberJoin.new)
      ..register<FeedbackButton>(FeedbackButton.new);
  }
}

Welcoming a new member

React to a member joining the server and send a message in the system channel.

final class OnMemberJoin extends ServerMemberAddEvent {
  @override
  Future<void> handle(Member member, Server server) async {
    final channel = await server.channels.resolveSystemChannel();
    await channel?.send(MessageBuilder.text('Welcome, ${member.username}!'));
  }
}

Slash command with an option

Declare a /say command that repeats a message back to the user.

final class SayCommand implements CommandDeclaration {
  Future<void> handle(ServerCommandContext ctx, CommandOptions options) async {
    final message = options.require<String>('message');
    await ctx.interaction.reply(builder: MessageBuilder.text(message));
  }

  @override
  CommandDeclarationBuilder build() {
    return CommandDeclarationBuilder()
      ..setName('say')
      ..setDescription('Repeat a message')
      ..addOption(Option.string(name: 'message', description: 'Text to repeat', required: true))
      ..setHandle(handle);
  }
}

Button interaction

Bind a button to a handler by its customId. Mineral routes the click automatically — no switch statement, no manual dispatch.

final class FeedbackButton extends ServerButtonClickEvent {
  @override
  String? get customId => 'open_feedback';

  @override
  Future<void> handle(ServerButtonContext ctx) async {
    await ctx.interaction.reply(
      builder: MessageBuilder.text('Thanks for your feedback!'),
    );
  }
}

Development

This repo uses Dart workspaces. All packages share a single dependency resolution from the root.

# Install all dependencies
dart pub get

# Run tests for a specific package
dart test packages/core
dart test packages/cache

# Analyze a specific package
dart analyze packages/core
dart analyze packages/cache

Publishing

Each package is published independently, triggered by a git tag.

git tag core-v4.3.0 && git push origin core-v4.3.0      # publishes mineral
git tag cache-v1.3.0 && git push origin cache-v1.3.0    # publishes mineral_cache