DiscordRDA
Modern, scalable Ruby library for Discord bot development with full Slash Commands and Component V2 support
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..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.(: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.(:administrator)
cmd.handler do |interaction|
interaction.respond(content: 'Admin command executed!', ephemeral: true)
end
end
Context Menu Commands
# User context menu
bot.(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.(style: :primary, label: 'Click Me', custom_id: 'click_button')
row.(style: :danger, label: 'Delete', custom_id: 'delete_button')
row.(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')
= interaction.modal_value('message')
interaction.respond(content: 'Thank you!', ephemeral: true)
end
Documentation
Examples
See the examples directory:
basic_bot.rb- Simple echo botsharded_bot.rb- Multi-shard exampleplugin_bot.rb- Custom plugin demonstrationslash_command_bot.rb- Slash command handling
Architecture
DiscordRDA follows a layered architecture designed for scalability:
Key Design Principles
- Immutable by Default: Entities are frozen after creation for thread safety
- Async-First: All I/O operations are non-blocking using Ruby's Fiber scheduler
- Type Safety: Full type coercion with attributes system
- Zero-Cost Abstractions: No unnecessary object allocations
- 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.