discord_rda 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +398 -0
  4. data/lib/discord_rda/bot.rb +842 -0
  5. data/lib/discord_rda/cache/configurable_cache.rb +283 -0
  6. data/lib/discord_rda/cache/entity_cache.rb +184 -0
  7. data/lib/discord_rda/cache/memory_store.rb +143 -0
  8. data/lib/discord_rda/cache/redis_store.rb +136 -0
  9. data/lib/discord_rda/cache/store.rb +56 -0
  10. data/lib/discord_rda/connection/gateway_client.rb +383 -0
  11. data/lib/discord_rda/connection/invalid_bucket.rb +205 -0
  12. data/lib/discord_rda/connection/rate_limiter.rb +280 -0
  13. data/lib/discord_rda/connection/request_queue.rb +340 -0
  14. data/lib/discord_rda/connection/reshard_manager.rb +328 -0
  15. data/lib/discord_rda/connection/rest_client.rb +316 -0
  16. data/lib/discord_rda/connection/rest_proxy.rb +165 -0
  17. data/lib/discord_rda/connection/scalable_rest_client.rb +526 -0
  18. data/lib/discord_rda/connection/shard_manager.rb +223 -0
  19. data/lib/discord_rda/core/async_runtime.rb +108 -0
  20. data/lib/discord_rda/core/configuration.rb +194 -0
  21. data/lib/discord_rda/core/logger.rb +188 -0
  22. data/lib/discord_rda/core/snowflake.rb +121 -0
  23. data/lib/discord_rda/entity/attachment.rb +88 -0
  24. data/lib/discord_rda/entity/base.rb +103 -0
  25. data/lib/discord_rda/entity/channel.rb +446 -0
  26. data/lib/discord_rda/entity/channel_builder.rb +280 -0
  27. data/lib/discord_rda/entity/color.rb +253 -0
  28. data/lib/discord_rda/entity/embed.rb +221 -0
  29. data/lib/discord_rda/entity/emoji.rb +89 -0
  30. data/lib/discord_rda/entity/factory.rb +99 -0
  31. data/lib/discord_rda/entity/guild.rb +619 -0
  32. data/lib/discord_rda/entity/member.rb +263 -0
  33. data/lib/discord_rda/entity/message.rb +405 -0
  34. data/lib/discord_rda/entity/message_builder.rb +369 -0
  35. data/lib/discord_rda/entity/role.rb +157 -0
  36. data/lib/discord_rda/entity/support.rb +294 -0
  37. data/lib/discord_rda/entity/user.rb +231 -0
  38. data/lib/discord_rda/entity/value_objects.rb +263 -0
  39. data/lib/discord_rda/event/auto_moderation.rb +294 -0
  40. data/lib/discord_rda/event/base.rb +986 -0
  41. data/lib/discord_rda/event/bus.rb +225 -0
  42. data/lib/discord_rda/event/scheduled_event.rb +257 -0
  43. data/lib/discord_rda/hot_reload_manager.rb +303 -0
  44. data/lib/discord_rda/interactions/application_command.rb +436 -0
  45. data/lib/discord_rda/interactions/command_system.rb +484 -0
  46. data/lib/discord_rda/interactions/components.rb +464 -0
  47. data/lib/discord_rda/interactions/interaction.rb +553 -0
  48. data/lib/discord_rda/plugin/analytics_plugin.rb +528 -0
  49. data/lib/discord_rda/plugin/base.rb +190 -0
  50. data/lib/discord_rda/plugin/registry.rb +126 -0
  51. data/lib/discord_rda/version.rb +5 -0
  52. data/lib/discord_rda.rb +70 -0
  53. metadata +302 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 53c5128ffda5f61e3d0e5aea868f9e93bafa82d98151d79f7c6739e8d185f1f9
4
+ data.tar.gz: 9d73432141274e3bbc8905fe7ddba98691ea64e7fd2381ffd9de1833a0a733f8
5
+ SHA512:
6
+ metadata.gz: 568d5fcbb987b97e5ba71f793346d536a6433b22398cdc32f04d2df43ced244f7a8215f818f942313e19a8b95e9c02d31dd99aac39fc1cb557648cbe7783081b
7
+ data.tar.gz: 861a6cbd6e0dba4b88e1ce6fcec261c700541493a0802384321d4bd3975ba64fc952d17c41736e28854e602ea58df9361e048bb148c74fdbd4cc9ea743bbe7ae
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JΓΊlia Klee
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,398 @@
1
+ # DiscordRDA
2
+
3
+ > Modern, scalable Ruby library for Discord bot development with full Slash Commands and Component V2 support
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![Ruby Version](https://img.shields.io/badge/ruby-%3E%3D%203.0-red.svg)](https://www.ruby-lang.org/)
7
+
8
+ 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.
9
+
10
+ ## Features
11
+
12
+ ### Core Capabilities
13
+ - **⚑ Async Runtime**: Built on Ruby 3.0+ Fiber scheduler for true concurrency
14
+ - **🏭 Factory Pattern**: Clean entity creation with `EntityFactory`
15
+ - **πŸ“‘ Auto Sharding**: Automatic and manual sharding with zero-downtime resharding
16
+ - **πŸ’Ύ Pluggable Cache**: Memory or Redis backends with pattern-based invalidation
17
+ - **πŸ”Œ Plugin System**: Extensible architecture for commands and features
18
+ - **πŸ“Š Rate Limiting**: Advanced Discord API rate limit handling with queue management
19
+ - **🎯 Full Documentation**: Every API is fully documented
20
+
21
+ ### Slash Commands & Interactions
22
+ - **Full Slash Command API**: Create, edit, delete global and guild commands
23
+ - **Context Menu Commands**: User and Message context menu support
24
+ - **Autocomplete**: Real-time autocomplete with dynamic choices
25
+ - **Modals**: Custom modal forms with text inputs
26
+ - **Component V2**: Latest Discord components (buttons, selects, containers)
27
+
28
+ ### Enterprise Features
29
+ - **Zero-Downtime Resharding**: Add shards without stopping the bot
30
+ - **Hot Reload**: File system event-based code reloading
31
+ - **Session Transfer**: Migrate guilds between shards seamlessly
32
+ - **REST Proxy Support**: Horizontal scaling with proxy servers
33
+ - **State Preservation**: Maintain sessions across reloads
34
+
35
+ ## Installation
36
+
37
+ Add this line to your application's Gemfile:
38
+
39
+ ```ruby
40
+ gem 'discord_rda'
41
+ ```
42
+
43
+ And then execute:
44
+
45
+ ```bash
46
+ bundle install
47
+ ```
48
+
49
+ Or install it yourself as:
50
+
51
+ ```bash
52
+ gem install discord_rda
53
+ ```
54
+
55
+ ## Quick Start
56
+
57
+ ```ruby
58
+ require 'discord_rda'
59
+
60
+ bot = DiscordRDA::Bot.new(
61
+ token: ENV['DISCORD_TOKEN'],
62
+ intents: [:guilds, :guild_messages, :message_content]
63
+ )
64
+
65
+ bot.on(:message_create) do |event|
66
+ if event.content == '!ping'
67
+ event.message.respond(content: 'Pong!')
68
+ end
69
+ end
70
+
71
+ bot.run
72
+ ```
73
+
74
+ ## Table of Contents
75
+
76
+ - [Features](#features)
77
+ - [Installation](#installation)
78
+ - [Quick Start](#quick-start)
79
+ - [Slash Commands](#slash-commands)
80
+ - [Components](#components)
81
+ - [Interactions](#interactions)
82
+ - [Architecture](#architecture)
83
+ - [Configuration](#configuration)
84
+ - [Sharding](#sharding)
85
+ - [Caching](#caching)
86
+ - [Rate Limiting](#rate-limiting)
87
+ - [Plugin System](#plugin-system)
88
+ - [Development](#development)
89
+ - [License](#license)
90
+
91
+ ## Slash Commands
92
+
93
+ DiscordRDA provides a comprehensive DSL for building Slash Commands:
94
+
95
+ ### Basic Slash Command
96
+
97
+ ```ruby
98
+ bot.slash('hello', 'Say hello') do |cmd|
99
+ cmd.string('name', 'Your name', required: true)
100
+ cmd.handler do |interaction|
101
+ name = interaction.option('name')
102
+ interaction.respond(content: "Hello, #{name}!")
103
+ end
104
+ end
105
+ ```
106
+
107
+ ### Command with Multiple Options
108
+
109
+ ```ruby
110
+ bot.slash('ban', 'Ban a user from the server') do |cmd|
111
+ cmd.user('user', 'User to ban', required: true)
112
+ cmd.string('reason', 'Reason for ban')
113
+ cmd.integer('days', 'Days of messages to delete')
114
+ cmd.default_permissions(:ban_members)
115
+
116
+ cmd.handler do |interaction|
117
+ user = interaction.option('user')
118
+ reason = interaction.option('reason') || 'No reason provided'
119
+ interaction.respond(content: "Banned #{user.username}", ephemeral: true)
120
+ end
121
+ end
122
+ ```
123
+
124
+ ### Guild-Specific Commands
125
+
126
+ ```ruby
127
+ bot.slash('admin', 'Admin only command', guild_id: '123456789') do |cmd|
128
+ cmd.default_permissions(:administrator)
129
+ cmd.handler do |interaction|
130
+ interaction.respond(content: 'Admin command executed!', ephemeral: true)
131
+ end
132
+ end
133
+ ```
134
+
135
+ ### Context Menu Commands
136
+
137
+ ```ruby
138
+ # User context menu
139
+ bot.context_menu(type: :user, name: 'High Five') do |interaction|
140
+ user = interaction.target_user
141
+ interaction.respond(content: "High-fived #{user.username}!")
142
+ end
143
+ ```
144
+
145
+ ## Components
146
+
147
+ ### Button Components
148
+
149
+ ```ruby
150
+ interaction.respond(content: 'Click the button!') do |builder|
151
+ builder.components do |row|
152
+ row.button(style: :primary, label: 'Click Me', custom_id: 'click_button')
153
+ row.button(style: :danger, label: 'Delete', custom_id: 'delete_button')
154
+ row.button(style: :link, label: 'Docs', url: 'https://example.com')
155
+ end
156
+ end
157
+
158
+ # Handle button clicks
159
+ bot.on(:button_click) do |interaction|
160
+ interaction.respond(content: 'Button clicked!', ephemeral: true)
161
+ end
162
+ ```
163
+
164
+ ### Select Menus
165
+
166
+ ```ruby
167
+ interaction.respond(content: 'Select your roles:') do |builder|
168
+ builder.components do |row|
169
+ row.string_select(
170
+ custom_id: 'role_select',
171
+ placeholder: 'Choose roles',
172
+ options: [
173
+ { label: 'Admin', value: 'admin' },
174
+ { label: 'Mod', value: 'mod' }
175
+ ]
176
+ )
177
+ end
178
+ end
179
+ ```
180
+
181
+ ## Interactions
182
+
183
+ ### Deferred Responses
184
+
185
+ ```ruby
186
+ bot.slash('slow', 'A slow command') do |cmd|
187
+ cmd.handler do |interaction|
188
+ interaction.defer(ephemeral: true)
189
+ # Do slow work
190
+ sleep(5)
191
+ interaction.edit_original(content: 'Done!')
192
+ end
193
+ end
194
+ ```
195
+
196
+ ### Modals
197
+
198
+ ```ruby
199
+ bot.slash('feedback', 'Submit feedback') do |cmd|
200
+ cmd.handler do |interaction|
201
+ interaction.modal(custom_id: 'feedback_modal', title: 'Send Feedback') do |modal|
202
+ modal.short(custom_id: 'subject', label: 'Subject', required: true)
203
+ modal.paragraph(custom_id: 'message', label: 'Your feedback', required: true)
204
+ end
205
+ end
206
+ end
207
+
208
+ # Handle modal submission
209
+ bot.on(:modal_submit) do |interaction|
210
+ subject = interaction.modal_value('subject')
211
+ message = interaction.modal_value('message')
212
+ interaction.respond(content: 'Thank you!', ephemeral: true)
213
+ end
214
+ ```
215
+
216
+ ## Documentation
217
+
218
+ - [Getting Started](docs/getting_started.md)
219
+ - [Architecture](docs/architecture.md)
220
+ - [API Reference](https://rubydoc.info/github/juliaklee/discord_rda)
221
+
222
+ ## Examples
223
+
224
+ See the [examples](examples/) directory:
225
+
226
+ - `basic_bot.rb` - Simple echo bot
227
+ - `sharded_bot.rb` - Multi-shard example
228
+ - `plugin_bot.rb` - Custom plugin demonstration
229
+ - `slash_command_bot.rb` - Slash command handling
230
+
231
+ ## Architecture
232
+
233
+ DiscordRDA follows a layered architecture designed for scalability:
234
+
235
+ ```
236
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
237
+ β”‚ Application Layer β”‚
238
+ β”‚ (Your bot code, commands, event handlers, plugins) β”‚
239
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
240
+ β”‚ Interaction Layer β”‚
241
+ β”‚ (Slash commands, components, modals, autocomplete) β”‚
242
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
243
+ β”‚ Entity Layer β”‚
244
+ β”‚ (User, Message, Guild, Channel - Factory Pattern) β”‚
245
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
246
+ β”‚ Event System β”‚
247
+ β”‚ (EventBus, subscriptions, middleware chain) β”‚
248
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
249
+ β”‚ Connection Layer β”‚
250
+ β”‚ (Gateway WebSocket, REST API client) β”‚
251
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
252
+ β”‚ Scalability Layer β”‚
253
+ β”‚ (Rate limiting, sharding, hot reload, caching) β”‚
254
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
255
+ β”‚ Core Runtime β”‚
256
+ β”‚ (Async scheduler, configuration, logging) β”‚
257
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
258
+ ```
259
+
260
+ ### Key Design Principles
261
+
262
+ 1. **Immutable by Default**: Entities are frozen after creation for thread safety
263
+ 2. **Async-First**: All I/O operations are non-blocking using Ruby's Fiber scheduler
264
+ 3. **Type Safety**: Full type coercion with attributes system
265
+ 4. **Zero-Cost Abstractions**: No unnecessary object allocations
266
+ 5. **Extensibility**: Plugin system for modular functionality
267
+
268
+ ## Configuration
269
+
270
+ ### Basic Configuration
271
+
272
+ ```ruby
273
+ bot = DiscordRDA::Bot.new(
274
+ token: ENV['DISCORD_TOKEN'],
275
+ application_id: ENV['DISCORD_APP_ID'],
276
+ shards: :auto,
277
+ cache: :redis,
278
+ intents: [:guilds, :guild_messages, :message_content],
279
+ log_level: :info,
280
+ log_format: :json
281
+ )
282
+ ```
283
+
284
+ ### Advanced Configuration
285
+
286
+ ```ruby
287
+ bot = DiscordRDA::Bot.new(
288
+ token: ENV['DISCORD_TOKEN'],
289
+ shards: [[0, 4], [1, 4]],
290
+ cache: :redis,
291
+ redis_config: { host: 'localhost', port: 6379 },
292
+ enable_scalable_rest: true,
293
+ intents: [:guilds, :guild_members, :guild_messages, :message_content]
294
+ )
295
+ ```
296
+
297
+ ## Sharding
298
+
299
+ ### Automatic Sharding
300
+
301
+ ```ruby
302
+ bot = DiscordRDA::Bot.new(token: token, shards: :auto)
303
+ ```
304
+
305
+ ### Zero-Downtime Resharding
306
+
307
+ ```ruby
308
+ # Enable auto-resharding
309
+ bot.enable_auto_reshard(max_guilds_per_shard: 1000)
310
+
311
+ # Manual resharding
312
+ bot.reshard_to(8)
313
+ ```
314
+
315
+ ## Caching
316
+
317
+ ### Memory Cache (Default)
318
+
319
+ ```ruby
320
+ bot = DiscordRDA::Bot.new(token: token, cache: :memory, max_cache_size: 10000)
321
+ ```
322
+
323
+ ### Redis Cache
324
+
325
+ ```ruby
326
+ bot = DiscordRDA::Bot.new(
327
+ token: token,
328
+ cache: :redis,
329
+ redis_config: { host: 'localhost', port: 6379 }
330
+ )
331
+ ```
332
+
333
+ ### Cache Invalidation
334
+
335
+ ```ruby
336
+ bot.cache.invalidate(:user, user_id)
337
+ bot.cache.invalidate_guild(guild_id)
338
+ bot.cache.clear
339
+ ```
340
+
341
+ ## Rate Limiting
342
+
343
+ DiscordRDA includes advanced rate limit management:
344
+
345
+ ```ruby
346
+ # Enable scalable REST (recommended for production)
347
+ bot.enable_scalable_rest
348
+
349
+ # Check invalid request bucket status
350
+ status = bot.invalid_bucket_status
351
+ ```
352
+
353
+ ## Plugin System
354
+
355
+ ### Creating a Plugin
356
+
357
+ ```ruby
358
+ class MusicPlugin < DiscordRDA::Plugin
359
+ def setup(bot)
360
+ @bot = bot
361
+ end
362
+
363
+ def ready(bot)
364
+ bot.logger.info('Music plugin ready')
365
+ end
366
+ end
367
+
368
+ bot.register_plugin(MusicPlugin.new)
369
+ ```
370
+
371
+ ## Development
372
+
373
+ ### Hot Reload
374
+
375
+ ```ruby
376
+ bot = DiscordRDA::Bot.new(token: token)
377
+ bot.enable_hot_reload(watch_dir: 'lib')
378
+ ```
379
+
380
+ ### Running Tests
381
+
382
+ ```bash
383
+ bundle exec rspec
384
+ ```
385
+
386
+ ## Contributing
387
+
388
+ Bug reports and pull requests are welcome on GitHub.
389
+
390
+ ## License
391
+
392
+ Licensed under the [MIT License](LICENSE).
393
+
394
+ Copyright (c) 2026 JΓΊlia Klee
395
+
396
+ ## Acknowledgments
397
+
398
+ Created by JΓΊlia Klee. Inspired by DiscordJDA and other Discord libraries. Special thanks to the Ruby async community and Discord API documentation contributors.