0.0
No release in over 3 years
DiscordRDA (Ruby Development API) is a modern, scalable Ruby library for Discord bot development
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 13.2
~> 3.13
~> 1.71
~> 3.24
~> 0.9

Runtime

~> 2.21
~> 0.86
~> 1.29
~> 3.9
~> 3.16
~> 5.2
~> 4.3
 Project Readme

DiscordRDA

Modern, scalable Ruby library for Discord bot development with full Slash Commands and Component V2 support

License: MIT Ruby Version

DiscordRDA (Ruby Development API) is a high-performance Ruby library for building Discord bots with modern async patterns, comprehensive Slash Command support, Component V2 architecture, and enterprise-grade scalability features.

Features

Core Capabilities

  • ⚑ Async Runtime: Built on Ruby 3.0+ Fiber scheduler for true concurrency
  • 🏭 Factory Pattern: Clean entity creation with EntityFactory
  • πŸ“‘ Auto Sharding: Automatic and manual sharding with zero-downtime resharding
  • πŸ’Ύ Pluggable Cache: Memory or Redis backends with pattern-based invalidation
  • πŸ”Œ Plugin System: Extensible architecture for commands and features
  • πŸ“Š Rate Limiting: Advanced Discord API rate limit handling with queue management
  • 🎯 Full Documentation: Every API is fully documented

Slash Commands & Interactions

  • Full Slash Command API: Create, edit, delete global and guild commands
  • Context Menu Commands: User and Message context menu support
  • Autocomplete: Real-time autocomplete with dynamic choices
  • Modals: Custom modal forms with text inputs
  • Component V2: Latest Discord components (buttons, selects, containers)

Enterprise Features

  • Zero-Downtime Resharding: Add shards without stopping the bot
  • Hot Reload: File system event-based code reloading
  • Session Transfer: Migrate guilds between shards seamlessly
  • REST Proxy Support: Horizontal scaling with proxy servers
  • State Preservation: Maintain sessions across reloads

Installation

Add this line to your application's Gemfile:

gem 'discord_rda'

And then execute:

bundle install

Or install it yourself as:

gem install discord_rda

Quick Start

require 'discord_rda'

bot = DiscordRDA::Bot.new(
  token: ENV['DISCORD_TOKEN'],
  intents: [:guilds, :guild_messages, :message_content]
)

bot.on(:message_create) do |event|
  if event.content == '!ping'
    event.message.respond(content: 'Pong!')
  end
end

bot.run

Table of Contents

  • Features
  • Installation
  • Quick Start
  • Slash Commands
  • Components
  • Interactions
  • Architecture
  • Configuration
  • Sharding
  • Caching
  • Rate Limiting
  • Plugin System
  • Development
  • License

Slash Commands

DiscordRDA provides a comprehensive DSL for building Slash Commands:

Basic Slash Command

bot.slash('hello', 'Say hello') do |cmd|
  cmd.string('name', 'Your name', required: true)
  cmd.handler do |interaction|
    name = interaction.option('name')
    interaction.respond(content: "Hello, #{name}!")
  end
end

Command with Multiple Options

bot.slash('ban', 'Ban a user from the server') do |cmd|
  cmd.user('user', 'User to ban', required: true)
  cmd.string('reason', 'Reason for ban')
  cmd.integer('days', 'Days of messages to delete')
  cmd.default_permissions(:ban_members)
  
  cmd.handler do |interaction|
    user = interaction.option('user')
    reason = interaction.option('reason') || 'No reason provided'
    interaction.respond(content: "Banned #{user.username}", ephemeral: true)
  end
end

Guild-Specific Commands

bot.slash('admin', 'Admin only command', guild_id: '123456789') do |cmd|
  cmd.default_permissions(:administrator)
  cmd.handler do |interaction|
    interaction.respond(content: 'Admin command executed!', ephemeral: true)
  end
end

Context Menu Commands

# User context menu
bot.context_menu(type: :user, name: 'High Five') do |interaction|
  user = interaction.target_user
  interaction.respond(content: "High-fived #{user.username}!")
end

Components

Button Components

interaction.respond(content: 'Click the button!') do |builder|
  builder.components do |row|
    row.button(style: :primary, label: 'Click Me', custom_id: 'click_button')
    row.button(style: :danger, label: 'Delete', custom_id: 'delete_button')
    row.button(style: :link, label: 'Docs', url: 'https://example.com')
  end
end

# Handle button clicks
bot.on(:button_click) do |interaction|
  interaction.respond(content: 'Button clicked!', ephemeral: true)
end

Select Menus

interaction.respond(content: 'Select your roles:') do |builder|
  builder.components do |row|
    row.string_select(
      custom_id: 'role_select',
      placeholder: 'Choose roles',
      options: [
        { label: 'Admin', value: 'admin' },
        { label: 'Mod', value: 'mod' }
      ]
    )
  end
end

Interactions

Deferred Responses

bot.slash('slow', 'A slow command') do |cmd|
  cmd.handler do |interaction|
    interaction.defer(ephemeral: true)
    # Do slow work
    sleep(5)
    interaction.edit_original(content: 'Done!')
  end
end

Modals

bot.slash('feedback', 'Submit feedback') do |cmd|
  cmd.handler do |interaction|
    interaction.modal(custom_id: 'feedback_modal', title: 'Send Feedback') do |modal|
      modal.short(custom_id: 'subject', label: 'Subject', required: true)
      modal.paragraph(custom_id: 'message', label: 'Your feedback', required: true)
    end
  end
end

# Handle modal submission
bot.on(:modal_submit) do |interaction|
  subject = interaction.modal_value('subject')
  message = interaction.modal_value('message')
  interaction.respond(content: 'Thank you!', ephemeral: true)
end

Documentation

Examples

See the examples directory:

  • basic_bot.rb - Simple echo bot
  • sharded_bot.rb - Multi-shard example
  • plugin_bot.rb - Custom plugin demonstration
  • slash_command_bot.rb - Slash command handling

Architecture

DiscordRDA follows a layered architecture designed for scalability:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Application Layer                       β”‚
β”‚  (Your bot code, commands, event handlers, plugins)         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                      Interaction Layer                       β”‚
β”‚  (Slash commands, components, modals, autocomplete)         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                      Entity Layer                            β”‚
β”‚  (User, Message, Guild, Channel - Factory Pattern)         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                      Event System                            β”‚
β”‚  (EventBus, subscriptions, middleware chain)               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                    Connection Layer                          β”‚
β”‚  (Gateway WebSocket, REST API client)                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                     Scalability Layer                        β”‚
β”‚  (Rate limiting, sharding, hot reload, caching)            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                      Core Runtime                            β”‚
β”‚  (Async scheduler, configuration, logging)                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Design Principles

  1. Immutable by Default: Entities are frozen after creation for thread safety
  2. Async-First: All I/O operations are non-blocking using Ruby's Fiber scheduler
  3. Type Safety: Full type coercion with attributes system
  4. Zero-Cost Abstractions: No unnecessary object allocations
  5. Extensibility: Plugin system for modular functionality

Configuration

Basic Configuration

bot = DiscordRDA::Bot.new(
  token: ENV['DISCORD_TOKEN'],
  application_id: ENV['DISCORD_APP_ID'],
  shards: :auto,
  cache: :redis,
  intents: [:guilds, :guild_messages, :message_content],
  log_level: :info,
  log_format: :json
)

Advanced Configuration

bot = DiscordRDA::Bot.new(
  token: ENV['DISCORD_TOKEN'],
  shards: [[0, 4], [1, 4]],
  cache: :redis,
  redis_config: { host: 'localhost', port: 6379 },
  enable_scalable_rest: true,
  intents: [:guilds, :guild_members, :guild_messages, :message_content]
)

Sharding

Automatic Sharding

bot = DiscordRDA::Bot.new(token: token, shards: :auto)

Zero-Downtime Resharding

# Enable auto-resharding
bot.enable_auto_reshard(max_guilds_per_shard: 1000)

# Manual resharding
bot.reshard_to(8)

Caching

Memory Cache (Default)

bot = DiscordRDA::Bot.new(token: token, cache: :memory, max_cache_size: 10000)

Redis Cache

bot = DiscordRDA::Bot.new(
  token: token,
  cache: :redis,
  redis_config: { host: 'localhost', port: 6379 }
)

Cache Invalidation

bot.cache.invalidate(:user, user_id)
bot.cache.invalidate_guild(guild_id)
bot.cache.clear

Rate Limiting

DiscordRDA includes advanced rate limit management:

# Enable scalable REST (recommended for production)
bot.enable_scalable_rest

# Check invalid request bucket status
status = bot.invalid_bucket_status

Plugin System

Creating a Plugin

class MusicPlugin < DiscordRDA::Plugin
  def setup(bot)
    @bot = bot
  end
  
  def ready(bot)
    bot.logger.info('Music plugin ready')
  end
end

bot.register_plugin(MusicPlugin.new)

Development

Hot Reload

bot = DiscordRDA::Bot.new(token: token)
bot.enable_hot_reload(watch_dir: 'lib')

Running Tests

bundle exec rspec

Contributing

Bug reports and pull requests are welcome on GitHub.

License

Licensed under the MIT License.

Copyright (c) 2026 JΓΊlia Klee

Acknowledgments

Created by JΓΊlia Klee. Inspired by DiscordJDA and other Discord libraries. Special thanks to the Ruby async community and Discord API documentation contributors.